Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Time:2021-3-8

preface

Official website:Mybatis plus official documentSimplify mybatis!

Create database

The database name is mybatis_ plus

Create table

Create user table

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 'mailbox',
PRIMARY KEY (id)
);
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]');

Note: – in real development, there are four fields: version, deleted and GMT_ Create, GMT_ Modified (modified time)

Initialize project

Use springboot to initialize!

Import dependency

<! -- database driven -- >
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- lombok -->
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
</dependency>
<!-- mybatis-plus -->
<! -- mybatis plus is self-developed, not official! -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-boot-starter</artifactId>
  <version>3.0.5</version>
</dependency>

Note: try not to import mybatis and mybatis plus at the same time! Avoid unpredictable problems caused by version differences.

Connect to database

establish application.yml

spring:
  profiles:
    active: dev
  datasource:
#Driving different MySQL 5 com.mysql.jdbc .Driver
#         mysql 8   com.mysql.cj . jdbc.Driver The configuration of time zone needs to be added. Servertimezone = GMT% 2B8
    url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root

Business code

Entity class
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
  private Long id;
  private String name;
  private Integer age;
  private String email;
}

Mapper interface

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kuang.pojo.User;
import org.springframework.stereotype.Repository;
//Inherit the basic class basemapper from the corresponding mapper
@Repository // stands for persistence layer
public interface UserMapper extends BaseMapper<User> {
  //All CRUD operations have been written
}

Note that we need to scan all the interfaces under our mapper package on the main boot class
@MapperScan(“com.kwhua.mapper”)

test

@SpringBootTest
class MybatisPlusApplicationTests {
  //Inheriting basemapper, all methods are derived from their own parent classes
  //We can also write our own extension methods!
  @Autowired
  private UserMapper userMapper;
  @Test
  void contextLoads() {
    //The parameter is a wrapper and a condition constructor. Here we first set the condition to be empty and query all the parameters.
    List<User> users = userMapper.selectList(null);
    users.forEach(System.out::println);
 }
}

All data output
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Configuration log

All our SQL is invisible now, we want to know how it is executed, so we need to configure the output of the log
application.yml File add log configuration

#Configuration log
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

View the log information of SQL execution
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

3、 Crud of mybatis plus

1. Insert operation

//Test insertion
    @Test
    public void testInsert(){
        User user = new User();
        user.setName("kwhua_mybatis-plus_insertTest");
        user.setAge(15);
        user.setEmail("[email protected]");

        int result =  userMapper.insert (user); // help us generate ID automatically
        System.out.println (result); // number of rows affected
        System.out.println (user); // the ID will be filled automatically when you see it. }

Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

When you see the ID, it fills in automatically. The default value of ID inserted in database is: global unique ID

Primary key generation strategy

1) Primary key auto increment
1. @ tableid (type) on entity class field= IdType.AUTO )
2. The database ID field is set to auto increment!
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

3. Test again (you can see that the ID value is 1 larger than the last one)
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Source code explanation of ID generation strategy

public enum IdType {
  Auto (0), // database ID auto increment
  None (1), // no primary key set
  Input (2), // input manually
  ID_ Work (3), // the default method is globally unique ID
  UUID (4), // globally unique ID UUID
  ID_ WORKER_ STR(5); //ID_ Work string representation
}

The above will not be tested one by one.

update operation

@Test
    public void testUpdate(){
        User user = new User();
        //Automatic splicing of dynamic SQL through conditions
        user.setId(1302223874217295874L);
        user.setName("kwhua_mybatis-plus_updateTest");
        user.setAge(20);
        //Note: updatebyid, but the parameter is an object!
        int i = userMapper.updateById(user);
        System.out.println(i);
    }

Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Auto fill

Create time, modify time! These two field operations are automated, we do not want to manually update!
Alibaba Development Manual: all database tables should be configured with GMT_ create、gmt_ modified! And it needs automation!
Mode 1: database level (generally not used in work)
1. Add a new field GMT in the table_ create, gmt_ modified
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

2. Synchronize entity classes

private Date gmtCreate;
private Date gmtModified;

3. Check again
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Mode 2: code level
1. Delete the default value and update the database!
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

2. Annotation should be added to the field attribute of entity class

//Field add padding
    @TableField(fill = FieldFill.INSERT)
    private Date gmt_create;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date gmt_modified;

3. Write a processor to handle this annotation!

@Slf4j
@Component // don't forget to add the processor to the IOC container!
public class MyMetaObjectHandler implements MetaObjectHandler {
    //Fill policy at insert time
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill.....");
        // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject
        this.setFieldValByName("gmt_create",new Date(),metaObject);
        this.setFieldValByName("gmt_modified",new Date(),metaObject);
    }

    //Population policy at update time
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill.....");
        this.setFieldValByName("gmt_modified",new Date(),metaObject);
    }
}

4. Test inserts and updates, check for time changes.

Optimistic lock

Optimistic lock: so called Siyi, very optimistic, it always thinks that there will be no problem, no matter what you do not lock! If something goes wrong,
Update the value test again
Pessimistic lock: so called Siyi, very pessimistic, it always thinks that there is always a problem, no matter what you do will lock! Do it again!

Optimistic lock implementation mode:

When fetching the record, get the current version
When updating, bring this version with you
When updating, set version = newversion where version = OldVersion
If the version is not correct, the update fails

Optimistic lock: 1. Query first and get the version number version = 1
-- A
update user set name = "kwhua", version = version + 1
where id = 2 and version = 1
--Thread B completes first, and version = 2 at this time, which will lead to a modification failure!
update user set name = "kwhua", version = version + 1
where id = 2 and version = 1

Optimistic lock test
1. Add version field to database!
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

2. Add the corresponding field to the entity class

@Version // optimistic lock version annotation
    private Integer version;

3. Register components

//Scan our mapper folder
@MapperScan("com.kwhua.mapper")
@EnableTransactionManagement
@Configuration // configuration class
public class MyBatisPlusConfig {
    //Register optimistic lock plug-in
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
   }

4. Testing

//The test is successful!
    @Test
    public void testOptimisticLocker(){
        //1. Query user information
        User user = userMapper.selectById(1L);
        //2. Modify user information
        user.setName("kwhua");
        user.setEmail("[email protected]");
        //3. Execute the update operation
        userMapper.updateById(user);
    }

The version field has changed from 1 to 2

//Failed to test optimistic lock! Under multithreading
    @Test
    public void testOptimisticLocker2(){

        //Thread 1
        User user = userMapper.selectById(1L);
        user.setName("kwhua111");
        user.setEmail("[email protected]");

        //Simulate another thread to perform queue jumping operation
        User user2 = userMapper.selectById(1L);
        user2.setName("kwhua222");
        user2.setEmail("[email protected]");
        userMapper.updateById(user2);

        //Spin lock to multiple attempts to submit!
        userMapper.updateById (user); // if there is no optimistic lock, it will override the queue jumping thread value!
    }

Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

You can see that thread 1 failed to perform the update

Query operation

//Test query
    @Test
    public void testSelectById(){
        User user = userMapper.selectById(1L);
        System.out.println(user);
    }

    //Test batch query!
    @Test
    public void testSelectByBatchId(){
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        users.forEach(System.out::println);
    }

    //Using map operation according to one of the conditional queries
    @Test
    public void testSelectByBatchIds(){
        HashMap<String, Object> map = new HashMap<>();
        //User defined to query
        map.put("name","kwhua");
        map.put("age",15);

        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }

6.1 paging query
1. Configure interceptor components

//Paging plug in
@Bean
public PaginationInterceptor paginationInterceptor() {
  return  new PaginationInterceptor();
}

2. Directly use the page object!

//Test paging query
@Test
public void testPage(){
  //Parameter 1: current page
  //Parameter 2: page size
  Page<User> page = new Page<>(2,5);
  userMapper.selectPage(page,null);
  page.getRecords().forEach(System.out::println);
  System.out.println(page.getTotal());
}

Physical deletion

//Test delete
    @Test
    public void testDeleteById(){
        userMapper.deleteById(1L);
    }

    //Batch deletion by ID
    @Test
    public void testDeleteBatchId(){
        userMapper.deleteBatchIds(Arrays.asList(2L,3L));
    }

    //Delete by map
    @Test
    public void testDeleteMap(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","kwhua");
        userMapper.deleteByMap(map);
    }

Logical deletion

Physical delete: remove directly from database
Logical deletion: it is not removed from the database, but disabled by a variable! deleted = 0 => deleted = 1
Administrators can view the deleted records! Prevent the loss of data, similar to the recycle bin!

1. Add a deleted field to the data table
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

2. Adding attributes to entity classes

@Tablelogic // logical deletion
 private Integer deleted;

3. Configuration

//Delete component logically!
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }

Profile configuration

  global-config:
    db-config:
      logic-delete-value: 1
      logic-not-delete-value: 0

4. Testing
Test delete
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

The field value is also changed from 0 to 1
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Test query
Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Performance analysis plug in

Function: performance analysis interceptor, used to output each SQL statement and its execution time
MP also provides performance analysis plug-in, if it exceeds this time, it will stop running!
1. Import plug in

/**
     *SQL execution efficiency plug in
     */
    @Bean
    @Profile ({"dev", "test"}) // set the dev test environment on to ensure our efficiency
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        pe rformanceInterceptor.setMaxTime (100); // MS sets the maximum time for SQL execution. If it exceeds, it will not be executed
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }

Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

Conditional constructor (wrapper)

.isNotNull .gt

@Test
    void contextLoads() {
        //Query the user whose name is not empty and whose mailbox is not empty, whose age is greater than or equal to 12
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                . isnotnull ("name") // not empty
                .isNotNull("email")
                .ge("age",18);
        userMapper.selectList (wrapper).forEach( System.out : println); // compare with the map we just learned
    }

Detailed! Mybatis plus commonly used API full set of tutorials, I do not believe you do not understand after reading!

.eq

@Test
    void test2(){
        //Query name kwhoua
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name","kwhua");
        User user =  userMapper.selectOne (wrapper); // select one to query one data and list or map to query multiple results
        System.out.println(user);
    }

.between

@Test
    void test3(){
        //Query users aged between 20 and 30
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between ("age", 20,30); // interval
        Integer count =  userMapper.selectCount (wrapper); // number of query results
        System.out.println(count);
    }

.like

//Fuzzy query
    @Test
    void test4(){
        //Query the data without E in the name and the mailbox starts with T
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Left likelift% T, right likelight% t
        wrapper
                .notLike("name","e")
                .likeRight("email","t");

        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }

.insql

//Fuzzy query
    @Test
    void test5(){

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //The ID is found in the subquery
        wrapper.inSql("id","select id from user where id<3");

        List<Object> objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }

.orderByAsc

//Test six
    @Test
    void test6(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Sort by ID
        wrapper.orderByAsc("id");

        List<User> users = userMapper.selectList(wrapper);
        users.forEach(System.out::println);
    }

Automatic code generator

You can create a Java class in the test folder

//Automatic code generator
public class generateCode {
   public static void main(String[] args) {
    //You need to build an automatic code generator object
    AutoGenerator mpg = new AutoGenerator();
    //Configuration policy
    //1. Global configuration
    GlobalConfig gc = new GlobalConfig();
    String projectPath = System.getProperty("user.dir");
    gc.setOutputDir(projectPath+"/src/main/java");
    gc.setAuthor ("kwhoua"); // author name
    gc.setOpen(false);
    gc.setFileOverride (false); // override
    gc.setIdType(IdType.ID_WORKER);
    gc.setDateType(DateType.ONLY_DATE);
    gc.setSwagger2 (true); // entity attribute swagger2 annotation

    //Customize file naming, note that% s will automatically fill in table entity attributes!
    gc.setServiceName("%sService"); 
    gc.setControllerName("%sController");
    gc.setServiceName("%sService");
    gc.setServiceImplName("%sServiceImpl");
    gc.setMapperName("%sMapper");
    gc.setXmlName("%sMapper");

    mpg.setGlobalConfig(gc);

    //2. Set data source
    DataSourceConfig dsc = new DataSourceConfig();
    dsc.setUrl("jdbc:mysql://localhost:3306/kwhua_test?
useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
    dsc.setDriverName("com.mysql.cj.jdbc.Driver");
    //  dsc.setDriverName (" com.mysql.jdbc . driver "; // the driver below mysql5.6
    dsc.setUsername("root");
    dsc.setPassword("root");
    dsc.setDbType(DbType.MYSQL);
    mpg.setDataSource(dsc);
    //3. Package configuration
    PackageConfig pc = new PackageConfig();
    pc.setParent (" com.kwhua "); // package name
    pc.setModuleName ("model"); // module name
    pc.setEntity("entity");
    pc.setMapper("mapper");
    pc.setService("service");
    pc.setController("controller");
    mpg.setPackageInfo(pc);

    //4. Policy configuration
    StrategyConfig strategy = new StrategyConfig();
     strategy.setInclude ("user", "course"); // set the name of the table to be mapped
    strategy.setNaming(NamingStrategy.underline_to_camel);
    strategy.setColumnNaming(NamingStrategy.underline_to_camel);
    strategy.setEntityLombokModel (true); // Auto Lombok;
    strategy.setLogicDeleteFieldName("deleted");
    //Auto fill configuration
    TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
    TableFill gmtModified = new TableFill("gmt_modified",FieldFill.INSERT_UPDATE);
    ArrayList<TableFill> tableFills = new ArrayList<>();
    tableFills.add(gmtCreate);
    tableFills.add(gmtModified);
    strategy.setTableFillList(tableFills);
    //Optimistic lock
    strategy.setVersionFieldName("version");
    //Create the corresponding class name according to your table name. If your table name is not underlined, such as test, you can cancel this step
    strategy.setTablePrefix("t_");
    strategy.setRestControllerStyle (true); // rest request
    //Automatic underline, such as localhost:8080/hello_ id_2
    strategy.setControllerMappingHyphenStyle(true); 
    mpg.setStrategy(strategy);
    mpg.execute (); // execute
 }
}

Execute the main method to generate the corresponding code

last

Thank you for reading here. If you think the article is helpful to you, please give me a favor. You will share Java related technical articles or industry information every day. You are welcome to pay attention to and forward the articles!