A quick start

Official document: mp.baomidou.com/

Steps:

1, create database mybatis-plus

Create table user

DROP TABLE IF EXISTS user;
 
CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT 'primary key ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT 'name',
    age INT(11) NULL DEFAULT NULL COMMENT 'age',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT 'email'.PRIMARY KEY (id)
);
Copy the code
2.1. Insert test data
INSERT INTO user (id, name, age, email) VALUES
(1.'Jone'.18.'[email protected]'),
(2.'Jack'.20.'[email protected]'),
(3.'Tom'.28.'[email protected]'),
(4.'Sandy'.21.'[email protected]'),
(5.'Billie'.24.'[email protected]');Copy the code

3. Create a project with IDEA (the details are not mentioned here)

4. Import dependencies

<! -- Database driver -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.20</version>
</dependency>
<! --mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
<! --lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
Copy the code

Special note: Using Mybatis- Plus can save us a lot of code, but try not to import both Mybatis and Mybatis- Plus dependencies!

5. Connect to the database

spring.datasource.username=root
spring.datasource.password=426457
spring.datasource.url=jdbc:mysql://localhost:3306/work? useSSl=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
Copy the code

6. No need to write services, Impl, and Mapper with Mybatis plus

pojo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @TableId(type = IdType.AUTO)
    private long id;
    private String name;
    private int age;
    private String email;
    @Version
    private int version;

    @TableLogic// Logical delete
    private int deleted;
}
Copy the code

Mapper interfaces

@Repository  // represents the persistence layer
public interface UserMapper extends BaseMapper<User> {}Copy the code

To scan all interfaces under our Mapper package on the main startup class

@MapperScan("com.lyw.Mapper")  // Scan the Mapper folder
@SpringBootApplication
public class MybatisPlusApplication {

    public static void main(String[] args) { SpringApplication.run(MybatisPlusApplication.class, args); }}Copy the code

Test in the test class

@SpringBootTest
class MybatisPlusApplicationTests {
    @Autowired
    UserMapper userMapper;
 
    @Test
    void contextLoads(a) {
        // Query all users
        List<User> users = userMapper.selectList(null); users.forEach(System.out::println); }}Copy the code

2. Configure logs

Now that we don’t need to write our own SQL statements, to see how the SQL executes, we need to turn on the log, right

# config log
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
Copy the code

After the configuration is complete, you can see what the internal automatically generated SQL statement looks like

Three, add, delete, change, check

1.Increasing (insert)

@Test
public void testInsert(a) {
    User user = new User();
    user.setName("Dainel");
    user.setAge(3);
    user.setEmail("[email protected]");
 
    int result = userMapper.insert(user);// Help us automatically generate id
    System.out.println(result);// The number of rows affected
    System.out.println(user);// Discovery: the ID is automatically backfilled
}
Copy the code

The value of id is not set (if the id is set to increment).

The rest of the source code interpretation

public enum IdType {
    AUTO(0), // The database ID is automatically increased
    NONE(1), // The primary key is not set
    INPUT(2), // Enter the id manually and write the id yourself
    ID_WORKER(3), // The default global unique ID
    UUID(4), // Globally unique ID UUID
    ID_WORKER_STR(5); // ID_WORKER string notation
}
Copy the code

2. Update operation

@Test
    /* Update operation */
void updateUser(a) {
    // Query the user to be updated
    User user = userMapper.selectById(7);
    // The value to update
    user.setName("demo");
    user.setAge(21);
    // Perform the update
    userMapper.updateById(user);
}
Copy the code

3. Automatic filling

Usually when we’re working with create time and change time, we don’t want to change it manually and that’s when we need to use auto-fill

Method 1: Directly change the database Settings

Add create_time,update_time; Note that the updated timestamp is checked

2. Test the insert method again (don’t forget to update the entity class)

Method 2: Change the code

1. Delete the default values and update the database

2. Add annotations to the field attributes of the entity class

// Add padding to the field
@TableField(fill = FieldFill.INSERT)
private Date createTime;
 
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
Copy the code

3, write processor to deal with this annotation: handler/MyMetaObjectHandler

package com.kuang.handler;
 
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
 
import java.util.Date;
 
@Slf4j
@Component Don't forget to add the handler to the IOC container
public class MyMetaObjectHandler implements MetaObjectHandler {
 
    // The padding strategy at insertion time
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ...");
        // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        this.setFieldValByName("createTime".new Date(), metaObject);
        this.setFieldValByName("updateTime".new Date(), metaObject);
    }
 
    // The populating strategy for the update
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ...");
        this.setFieldValByName("updateTime".newDate(), metaObject); }}Copy the code

Test again, success!

4. Optimistic Lock

Optimistic Lock: As the name implies, it always thinks there will be no problem, no matter what to do to lock! If something goes wrong, update the value test again!

Pessimistic lock: As the name implies, it always thinks there is always a problem, no matter what to lock! Operate again!

Optimistic lock implementation:

  • When the record is fetched, the current version is retrieved
  • When you update, take this version with you
  • When performing an update, set version = newVersion where version = oldVersion
  • If the version is incorrect, the update fails

Testing:

Add a version field to the database with an initial value of 1

Add the version annotation to the entity class

@Version // Optimistic lock version annotation
private Integer version;
Copy the code

3. Write config/MybatisPlusConfig

@Configuration
public class MybatisPlusConfig {
    // Register the lockup
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInnerInterceptor(a){
        return newOptimisticLockerInterceptor(); }}Copy the code

Testing:

Success: Changed the name of Number 2 to Lipu. View the version change

@Test
void OptimisticLock(a) {
    // Query the user to be updated
    User user = userMapper.selectById(2);
    // Modify user attributes
    user.setName("lipu");
    user.setAge(28);
    // Commit the update
    userMapper.updateById(user);
}
Copy the code

Failure: in the case of multithreading

// Test optimistic lock failed! Under the multithreading
@Test
public void testVersionFall(a) {
    / / thread 1
    User user1 = userMapper.selectById(9);
    user1.setName("fan111");
    user1.setAge(14);
    / / thread 2
    User user2 = userMapper.selectById(9);
    user2.setName("fan222");
    user2.setAge(24);
    userMapper.updateById(user2);
    // Spin lock to try to commit many times!
    userMapper.updateById(user1); // If there is no optimistic lock, the queue-jumping thread will be overwritten
}
Copy the code

Select * from (select)

// Test the query
@Test
public void testSelectById(a){
    User user = userMapper.selectById(1);
    System.out.println(user);
}
 
// Batch query
@Test
public void testSelectByBatchIds(a){
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1.2.3));
    users.forEach(System.out::println);
}
 
// Use map as one of the conditional queries
@Test
public void testSelectByMap(a){
    HashMap<String, Object> map = new HashMap<>();
    // Custom to query
    map.put("name"."Dainel");
    map.put("age"."6");
    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}
Copy the code

6, paging query

Pagination is often used in web pages. Here are a few common ways

  • Limit was originally used for paging
  • PageHelper third-party plugin
  • MybatisPlus has a built-in paging plug-in

There is a built-in paging plug-in using MybatisPlus

1. Configure the paging plug-in

// Paging plug-in
@Bean
public PaginationInterceptor paginationInterceptor(a) {
    return new PaginationInterceptor();
}
Copy the code

2, write paging query statements

// paging query
@Test
void selectLimit(a) {
    Page<User> page = new Page<User>(2.5);
    // Get the number of entries queried through paging
    page.getRecords().forEach(System.out::println);
    / / query
    userMapper.selectPage(page, null);
    // Query the total number of entries
    System.out.println("Total number of items:" + page.getTotal());
}
Copy the code

7. Delete

// Test delete
@Test
public void testdelete(a){
    userMapper.deleteById(6L);
}
 
// Test batch delete
@Test
public void testdeleteBatchId(a){
    userMapper.deleteBatchIds(Arrays.asList(1.14));
}
 
// Delete using map
@Test
public void testDeleteByMap(a){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name"."KUANG");
    userMapper.deleteByMap(map);
}
Copy the code

8. Logical deletion

Physical delete: Directly remove from the database

Logical delete: it is not removed from the database, but made valid by a variable! deleted=0 –> deleted=1

Administrators can view deleted records! Prevent data loss! It’s like a recycle bin!

Steps:

1. Add a deleted field in the database. The default value is 0

2. Modify the entity class

// Table logical drop
@TableLogic
private int deleted;
Copy the code

3. Add the configuration

// Remove the component logically
public ISqlInjector sqlInjector(a){
    return new LogicSqlInjector();
}
Copy the code

4. Add the configuration in properties

Delete the configuration logic
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
Copy the code

5, test,

// Logical delete
@Test
void deleteLogic(a) {
    userMapper.deleteById(1);
}
Copy the code

Delete the success

The query result for user 1 is 0

Performance analysis plug-in

In the usual development process, will encounter some slow SQL problems. The purpose of the performance analysis plug-in is to output each SQL statement and its execution time, and if this time is exceeded, the execution will be stopped. 1. Import the plug-in

// SQL execution efficiency plug-in
@Bean
@Profile({"dev","test"})
public PerformanceInterceptor performanceInterceptor(a){
    PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    performanceInterceptor.setMaxTime(100); //ms Sets the maximum time for SQL execution
    performanceInterceptor.setFormat(true); // Whether to format
    return performanceInterceptor;
}
Copy the code

Note: The environment configured in Springboot is dev or test

# Development environment
spring.profiles.active=dev
Copy the code

2. Test use

// paging query
@Test
void selectLimit(a) {
    Page<User> page = new Page<User>(1.5);
    // Get the number of entries queried through paging
    page.getRecords().forEach(System.out::println);
    / / query
    userMapper.selectPage(page, null);
    // Query the total number of entries
    System.out.println("Total number of items:" + page.getTotal());
}
Copy the code

Whenever the time is exceeded, an exception is thrown.

Performance analysis plugins can be used to improve efficiency. In the new version of MP, this widget has been removed and druid can be used

Code generators

AutoGenerator is the code generator of MyBatis-Plus, through which the code of Entity, Mapper, Mapper XML, Service, Controller and other modules can be generated quickly. Greatly improved the development efficiency.

Pom dependencies needed

<dependencies> <! --> <dependency> <groupId> IO. Springfox-swagger2 </artifactId> < version > 2.7.0 < / version > < / dependency > < the dependency > < groupId >. IO springfox < / groupId > < artifactId > springfox swagger - UI < / artifactId > < version > 2.7.0 < / version > < / dependency > <! <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> The < version > 2.0 < / version > < / dependency > <! <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> < the dependency > < groupId > com. Baomidou < / groupId > < artifactId > mybatis - plus - the boot - starter < / artifactId > < version > 3.0.5 < / version >  </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId>  </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>Copy the code

The test code

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
 
import java.util.ArrayList;
 
// Automatic code generator
public class zhixiCode {
    public static void main(String[] args) {
        // A code automatic generator object needs to be built
        AutoGenerator mpg = new AutoGenerator();
 
        // Configure the policy
        // 1
        GlobalConfig gc = new GlobalConfig();
        // Which directory to output the code to (get the project directory)
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        // Set the author
        gc.setAuthor("Zhang Zhixi");
        // Whether to open explorer (open directory after generating code)
        gc.setOpen(false);
        // Whether to overwrite the original file
        gc.setFileOverride(false);
 
        // Remove the IService I prefix (re)
        gc.setServiceName("%sService");
 
        // Set the field
        gc.setIdType(IdType.ID_WORKER);
        gc.setDateType(DateType.ONLY_DATE);
        / / configuration swagger
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);
 
        //2. Set the data source
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("JDBC: mysql: / / 182.92.209.212:3306 / mybatis_plus? useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("Password");
        // Database type
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);
 
        // package configuration (only need to change entity class name and package name and database configuration)
        PackageConfig pc = new PackageConfig();
 
        / / module name
        pc.setModuleName("blog");
        // Set the package to be placed under
        pc.setParent("com.kuang");
        // Set the entity class
        pc.setEntity("entity");
        / / set the mapper
        pc.setMapper("mapper");
        // Set up the Services layer
        pc.setService("service");
        // Set the controller layer
        pc.setController("controller");
 
        mpg.setPackageInfo(pc);
 
        //4
        StrategyConfig strategy = new StrategyConfig();
        // Set the name of the table to be mapped
        strategy.setInclude("blog_tags"."course"."links"."sys_settings"."user_record"." user_say");
 
        // Set the underline to camel name
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // Automatic lombok;
        strategy.setEntityLombokModel(true);
        // Set the logical deletion column name
        strategy.setLogicDeleteFieldName("deleted");
 
        // Automatically populate the configuration
        TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);/* Create time */
        TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);/* Change the time */
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(gmtCreate);
        tableFills.add(gmtModified);
        // Add auto-fill
        strategy.setTableFillList(tableFills);
 
        / / optimistic locking
        strategy.setVersionFieldName("version");/* Sets the version field name */
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true);// localhost:8080/hello_id_2
 
        mpg.setStrategy(strategy);
 
        mpg.execute(); / / execution}}Copy the code

This is the strength of MP!!