My colleague told me that the reason why his code is silky is that he uses Mybatis Plus?

1. Pain points of mybatis

We know that MyBatis is a persistence layer framework based on java. It encapsulates jdbc internally, which greatly improves our development efficiency.

However, there are many pain points in developing with Mybatis:

  1. Each Dao interface needs to define a bunch of addition, deletion, modification and query methods.
/**
 * @Desc: UserDao Interface
 * @Author: Official account: know if the technology
 * @date: 7:43 PM 2022 / 5 / 7
 */
public interface UserDao {
    // Get all user information
    List<User> getUserList();
    
    // Get user information based on id
    User getUserById(int id);
    
    // New user information
    boolean add(User user);
    
    // Update user information
    boolean update(User user);
    
    // Delete user information
    boolean delete(int id);
}
Copy code

2. Each Mapper file needs to write a pile of basic addition, deletion, modification and query statements.

3. If the query list needs paging, we also need to encapsulate the component page object for the query method.

You might say: can Mybatis still hurt? How convenient it is to use!

For small projects, it's OK to use it. However, in case of large projects, there are hundreds of Dao interfaces. If you have to manually define a pile of addition, deletion, modification and query methods and sql statements, it will also be a waste of time.

Is there such a framework:

1. It encapsulates Mybatis and comes with CRUD method. We don't need to define CRUD method ourselves.

2. Provide various query methods without writing some basic sql statements in the mapper file.

3. The paging function is encapsulated to make paging query extremely smooth.

Yes, MybatisPlus is on the stage.

2. Meet MybatisPlus

Official website:

https://baomidou.com/
Copy code

MybatisPlus is encapsulated based on the original functions of Mybatis. It does not change, but enhances the function of Mybatis.

We don't have to write map XML, directly calling its API can complete CRUD and various query operations.

And it comes with some advanced functions such as paging plug-in, which greatly improves our development efficiency.

3. Introductory cases

Development environment:

  • Development tool: IDEA
  • Build tool: Maven
  • Database: MySQL
  • Project framework: SpringBoot

1. Create a new SpringBoot project

2. Introduce dependency

<!-- mybatis-plus rely on-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.0</version>
</dependency>
<!-- mysql drive -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
Copy code

3. Create database table

user table:

CREATE TABLE `user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT 'full name',
  `age` int DEFAULT NULL COMMENT 'Age',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1508421137384648706 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC;
Copy code

4. Entity class

public class User {
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    private int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
Copy code

5. Modify application yml

server:
  port: 8082
  servlet:
    context-path: /mybatisplus_demo
# Data source configuration
spring:
  datasource:
    username: root
    password: 12345678
    url: jdbc:mysql://localhost:3306/ssm?allowPublicKeyRetrieval=true&useSSL=false
    driver-class-name: com.mysql.cj.jdbc.Driver
 Copy code

6. Create a new UserMapper interface

Note:

(1) Because mybatis stipulates: mapper The name of the XML file should be the same as that of the interface, so many people are used to naming the Dao interface xxmapper.

(2)BaseMapper is the built-in interface of MybatisPlus, which contains basic CRUD methods.

7. Add @ MapperScan annotation to the startup class

8. Test

@SpringBootTest
public class MybatisPlusDemoApplicationTests {

    @Resource
    private UserMapper userMapper;

    @Test
    void testMybatisPlus() {
        for (int i = 18; i < 20; i++) {
            User user = new User("Wang Xiaobo" + i, i);
            userMapper.insert(user);
        }
    }
}
Copy code

9. Summary

We found that as long as we inherit the BaseMapper of MybatisPlus, we can complete the basic addition, deletion, modification and query operations, which is very convenient.

4. Basic addition, deletion, modification and query

1. NEW

User user = new User("Wang Xiaobo", 19);
userMapper.insert(user);
Copy code

2. Editing

Update data according to id

int rows = userMapper.updateById(user);
if(rows>0){
    System.out.println("Update successful"); 
}
Copy code

3. Delete

Delete information according to primary key

userMapper.deleteById("152635612");
Copy code

Delete information according to map conditions

Map<String, Object> param = new HashMap<>();
param.put("age", 18);
int rows = userMapper.deleteByMap(param);
if (rows > 0) {
    System.out.println("Delete succeeded!");
}
Copy code

Batch deletion based on id set

List<Integer> ids = Stream.of(110, 112, 113, 115).collect(Collectors.toList());
int rows = userMapper.deleteBatchIds(ids);
if (rows > 0) {
  System.out.println("Delete succeeded!");
}
Copy code

4. Query

Query by id

User user = userMapper.selectById(152382374);
Copy code

Query according to map criteria

Map<String, Object> param = new HashMap<>();
param.put("age", 18);
List<User> userList = userMapper.selectByMap(param);
Copy code

Batch query based on id set

List<Integer> ids = Stream.of(110, 112, 113, 115).collect(Collectors.toList());
List<User> userList = userMapper.selectBatchIds(ids);
Copy code

5. Constructor

MybatisPlus provides a query constructor and an update constructor to generate sql statements with where conditions.

(1) Constructor encapsulating query criteria:

QueryWrapper
 Copy code

Common query criteria:

Equal to: eq

QueryWrapper<User> userWrapper = new QueryWrapper<>();
// Query the user whose name is Zhang San
userWrapper.eq("name","Zhang San");
List<User> userList = userMapper.selectList(userWrapper);
Copy code

Not equal to: ne

QueryWrapper<User> userWrapper = new QueryWrapper<>();
userWrapper.ne("name","Zhang San");
// User whose query name is not Zhang San
List<User> userList = userMapper.selectList(userWrapper);
Copy code

Fuzzy query: like

QueryWrapper<User> userWrapper = new QueryWrapper<>();
// Fuzzy query
userWrapper.like("name","Zhang");
List<User> userList = userMapper.selectList(userWrapper);
Copy code

Descending order: orderByDesc

QueryWrapper<User> userWrapper = new QueryWrapper<>();
// Fuzzy query and reverse order according to number
userWrapper.like("name","Zhang").orderByDesc("number");
List<User> userList = userMapper.selectList(userWrapper);
Copy code

Ascending order: orderByAsc

QueryWrapper<User> userWrapper = new QueryWrapper<>();
// Fuzzy query and descending order according to number
userWrapper.like("name","Zhang").orderByAsc("number");
List<User> userList = userMapper.selectList(userWrapper);
Copy code

For other common conditions, you can check the relevant documents on the official website, which will not be repeated here:

https://baomidou.com/pages/10c804/#in
 Copy code

(2) Constructor that encapsulates the update condition:

UpdateWrapper
 Copy code

The where condition of UpdateWrapper is the same as that of QueryWrapper, except that the set value is required.

UpdateWrapper<User> userWrapper = new UpdateWrapper<>();
userWrapper.set("name","Wang Xiaobo").set("age",22)
    .eq("name","Zhang San");
Copy code

6. General Service

MybatisPlus has a general interface Iservice and implementation class, which encapsulates common operations such as addition, deletion, modification and query.

1. Create a new service and implementation class

UserService

/**
 * @Desc:
 * @Author: Official account: know if the technology
 * @date: 9:57 PM 2022 / 5 / 11
 */
public interface UserService extends IService<User> {

}
Copy code

UserServiceImpl

/**
 * @Desc:
 * @Author: Official account: know if the technology
 * @date: 9:57 PM 2022 / 5 / 11
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}
Copy code

2. Test

We found that the IService interface encapsulates some common methods, which greatly improves our development efficiency.

7. Common notes

1.@TableId

MybatisPlus will take the id in the entity class as the primary key by default.

@TableId refers to the generation strategy of id. there are two commonly used methods:

(1) Self increment strategy based on Database

(2) Random generation using snowflake algorithm strategy

2.@TableName

If the table names of the entity class and the database are inconsistent, you can use this annotation for mapping

For example:

3.@TableField

When the table attribute and the attribute name in the entity class are inconsistent, you can use this annotation for mapping:

8. Pagination

The paging plug-in is encapsulated in MybatisPlus, and the paging function can be realized only by simple configuration.

1. Configuration class

/**
 * @Desc:
 * @Author: Official account: know if the technology
 * @date: 9:31 PM 2022 / 5 / 11
 */
@Configuration
@MapperScan("com.zhifou.mapper")
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new
                PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}
Copy code

2. Test

@Test
void testMybatisPlus() {
    int current = 1;
    int size = 10;
    Page<User> userPage = new Page<>(current, size);
    //Get paging data
    List<User> list = userPage.getRecords();
    list.forEach(user->{
        System.out.println(user);
    });
    Page<User> page = userMapper.selectPage(userPage, null);
    System.out.println("Current page:" + page.getCurrent());
    System.out.println("Number of entries per page:" + page.getSize());
    System.out.println("Total records:" + page.getTotal());
    System.out.println("PageCount :" + page.getPages());
}
Copy code

9. Code generator

MybatisPlus can help us automatically generate controller, service, dao, model and mapper XML and other files, which greatly improves our development efficiency.

1. Introduce dependency

<!-- Code generator  -->
<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-plus-generator</artifactId>
  <version>3.5.1</version>
</dependency>
<dependency>
  <groupId>org.freemarker</groupId>
  <artifactId>freemarker</artifactId>
</dependency>
Copy code

2. Code generator tool class

public class CodeGenerator {
public static void main(String[] args) {
// Connect database
FastAutoGenerator.create("jdbc:mysql://localhost:3306/ssm?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC", "root", "123456")
    .globalConfig(builder -> {
        builder.author("Know technology") // Set author
                .fileOverride() // Overwrite generated files
                // Set date and time
                .dateType(DateType.ONLY_DATE)
                .outputDir("D:\\WorkSpace\\idea\\mybatisplus_demo\\src\\main\\java"); // Specify output directory
    })
    .packageConfig(builder -> {
        builder.parent("com.zhifou") // Set parent package name
                .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D:\\WorkSpace\\idea\\mybatisplus_demo\\src\\main\\resources\\mapper")); // Set mapperXml generation path
    })
    .strategyConfig(builder -> {
        builder.addInclude("t_user") // Set the table name to be generated
                .addTablePrefix("t_"); // Before setting filter table

        // Add new data and automatically assign a value to the creation time
        IFill createFill = new Column("created_date", FieldFill.INSERT);
        IFill updateFill = new Column("updated_date", FieldFill.UPDATE);
        builder.entityBuilder()
                // Set id type
                .idType(IdType.ASSIGN_ID)
                // Open Lombok
                .enableLombok()
                // Turn on continuous setting mode
                .enableChainModel()
                // Hump naming mode
                .naming(NamingStrategy.underline_to_camel)
                .columnNaming(NamingStrategy.underline_to_camel)
                // Automatically assign values to creation time and modification time
                .addTableFills(createFill).addTableFills(updateFill)
                // Delete field logically
                .logicDeleteColumnName("is_deleted");

        // Restful style
        builder.controllerBuilder().enableRestStyle();
        // Remove Service prefix I
        builder.serviceBuilder().formatServiceFileName("%sService");
        // mapper settings
        builder.mapperBuilder()
                .enableBaseResultMap()
                .enableBaseColumnList();
    })
    // fixed
    .templateEngine(new FreemarkerTemplateEngine()) // Freemarker engine template is used. The default is Velocity engine template
    .execute();
  }
}
Copy code

Key points:

(1) Configure database connection information.

Automatic code generation requires connection to the database

(2) Specify the output directory. Set the directory of your project directly here. There is no need to assign and paste at that time.

(3) Set the parent package name.

(4) Set table name

Then right-click to run, and the code will be generated automatically.

10. application.yml configuration

# MybatisPlus
mybatis-plus:
  global-config:
    db-config:
      column-underline: true # Hump form
      logic-delete-field: isDeleted # Global logically deleted entity field name
      logic-delete-value: 1 # Logical deleted value (default = 1)
      logic-not-delete-value: 0 # Logical undeleted value (default is 0)
      db-type: mysql
      id-type: assign_id # id policy
      table-prefix: t_ # Default prefix for configuration table 
  mapper-locations: classpath*:/mapper/**Mapper.xml # mapper file location
  type-aliases-package: com.zhifou.entity # Entity class alias
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # Log: print sql statements
 Copy code

11. Complete code

link: https://pan.baidu.com/s/1nlRjKOWs3ON53Dh1XXLKGw 
Extraction code: 9un7 
Copy code

12. Pit encountered

1. When the parameter passed is 0, the query statement is invalid.

For example, if the age passed is 0, the query will become invalid

<select id="getUser" resultType="user">
    select id,name,age,sex from user
    <where>
        <if test="age != null and age !='' ">
            age = #{age}
        </if>
    </where>
</select>
Copy code

Reason: judge whether int is empty= Null is OK. If you add type! = '', 0 will be made null.

2.MybatisPlus failed to update the field to null

terms of settlement:

@TableField(updateStrategy = FieldStrategy.IGNORED)
private String name;
Copy code

This annotation will ignore the judgment that is empty,

Tags: Java Spring Boot Interview Spring Cloud programming language

Posted by greenber on Sun, 15 May 2022 00:18:14 +0300