The Use of mybatis-plus--Introduction

Keywords: Mybatis Spring xml SQL

Links to the original text: https://www.jianshu.com/p/ceb1df475021

Preface:

Mybatis is still popular in the persistence layer framework, and most projects are based on ssm. Although mybatis can operate database directly in xml through SQL statements, it is very flexible. But its operation must be done through SQL statements, so it is very troublesome to write a large number of xml files. mybatis-plus solves this problem very well.

I. Introduction to mybatis-plus:

Mybatis-Plus (MP) is an enhancement tool for Mybatis. It is based on Mybatis and does not change. It comes into being to simplify development and improve efficiency. This is the official definition. More information and features about mybatis-plus can be consulted. mybatis-plus official website . So how does it enhance? In fact, it has already encapsulated some crud methods. We don't need to write xml anymore, just call these methods directly, just like JPA.

2. spring integrates mybatis-plus:

As the official said, mybatis-plus only makes enhancements on the basis of mybatis without changes, so its integration with spring is very simple. Just replace mybatis dependency with mybatis-plus dependency and sqlSession Factory with mybatis-plus dependency. Next, look at the specific operation:
1,pom.xml:
Core dependencies are as follows:

        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.3.14.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.14.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <!-- mp rely on -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>2.3</version>
        </dependency>

Note: These are core dependencies. This project also uses mysql driver, c3p0, log (slf4j-api, slf4j-log4j2), lombok. Integrating mybatis-plus removes mybatis and mybatis-spring to avoid conflicts; Lombok is a tool that adds this dependency, and the development tool installs Lombok plug-ins to use it. The most common use is to use its @Data annotation in entity classes, so that entity classes do not need to write set, get, String, etc. Law. For more use of Lombok, please Baidu yourself.

2,log4j.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{MM-dd
HH:mm:ss,SSS} %m (%F:%L) \n" />
        </layout>
    </appender>
    <logger name="java.sql">
        <level value="debug" />
    </logger>
    <logger name="org.apache.ibatis">
        <level value="info" />
    </logger>
    <root>
        <level value="debug" />
        <appender-ref ref="STDOUT" />
    </root>
</log4j:configuration>

3,jdbc.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:/// Database name? UseUnicode = true & characterEncoding = utf8
jdbc.username=#
jdbc.password=#

4,mybatis-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

Note: Because it is integrated with spring, most of all mybatis-plus are written in the spring configuration file, where an empty mybatis-config.xml can be defined.

5,spring-dao.xml:

<?xml version="1.0" encoding="UTF-8"?>    
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:aop="http://www.springframework.org/schema/aop"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="    
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd  
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd  
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">    
        
    <!-- Configuration integration mybatis-plus process -->
    <!-- 1,Configure database related parameters properties Properties: ${url} -->
    <context:property-placeholder location="classpath:jdbc.properties" />
    <!-- 2,Configure database connection pool -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!-- mybatis Of sqlsessionFactorybean: org.mybatis.spring.SqlSessionFactoryBean-->
    <!-- 3,To configure mybatis-plus Of sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="typeAliasesPackage" value="com.zhu.mybatisplus.entity"/>
    </bean>
    <!-- 4,DAO The package name of the interface, Spring The following classes are automatically found -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zhu.mybatisplus.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean> 
</beans>

6,entity:

@Data
@TableName(value = "tb_employee")//Specified table name
public class Employee {
    //Value is consistent with the database primary key column name, and value can be omitted if the entity class attribute name is consistent with the table primary key column name.
    @TableId(value = "id",type = IdType.AUTO)//Specify Self-Increasing Policy
    private Integer id;
    //If the naming of humps is not opened, or the column names in the table do not conform to the hump rules, the column names in the database tables can be specified by the annotation. exist indicates whether there are corresponding columns in the data table.
    @TableField(value = "last_name",exist = true)
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;
}

7,mapper:

public interface EmplopyeeDao extends BaseMapper<Employee> {
}

This completes the integration of mybatis-plus and spring. Firstly, mybatis and mybatis-spring dependencies are replaced by mybatis-plus dependencies. Then, SQL essionfactory is replaced by mybatis-plus. Then, annotations such as @TableName,@TableId are added to the entity class. Finally, mapper inherits BaseMapper.

8. Testing:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class test {
    @Autowired
    private DataSource dataSource;
    @Test
    public void testDataSource() throws SQLException {
        System.out.println(dataSource.getConnection());
    }
}

Running the junit, you can output the acquired connection, indicating that the integration is okay:

image.png


All the codes in this paper have been tested by myself. There are many codes involved in this paper. In order not to affect the length, it is not necessary to stop screenshots. All subsequent actions are based on this integrated project.
 

 

3. General crud of mp:

Demand:
There is a tb_employee table, and the corresponding entity class Employee exists. What do we need to do to implement the CRUD operation of the tb_employee table?
Based on Mybatis:
We need to write EmployeeMapper interface and manually write sql statements corresponding to CRUD method in EmployeeMapper.xml Mapping file.
Based on MP:
All you need to do is create the EmployeeMapper interface and inherit the BaseMapper interface.
We already have Employee, tb_employee, and EmployeeDao has inherited BaseMapper, and then we use crud.

1. insert operation:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class test {
    @Autowired
    private EmplopyeeDao emplopyeeDao;
    @Test
    public void testInsert(){
        Employee employee = new Employee();
        employee.setLastName("Invincible Eastern");
        employee.setEmail("dfbb@163.com");
        employee.setGender(1);
        employee.setAge(20);
        emplopyeeDao.insert(employee);
        //mybatisplus automatically writes the id of the currently inserted object back to the entity in the database
        System.out.println(employee.getId());
    }
}

The insert method is directly invoked to pass in the entity.

2. update operation:

@Test
public void testUpdate(){
        Employee employee = new Employee();
        employee.setId(1);
        employee.setLastName("Update test");
        //emplopyeeDao.updateById(employee); // Update based on id, properties that do not pass values will not be updated
        emplopyeeDao.updateAllColumnById(employee);//Updates are made according to id, and attributes that do not pass values are updated to null
}

Note: Notice the difference between the two update operations. The updateById method does not update fields without values. For example, only lastName is passed in, then age, gender and other attributes will retain their original values. The updateAllColumnById method, as its name implies, updates all columns, and the columns without values will be updated to null.

3. select operation:

(1) Query according to id:

Employee employee = emplopyeeDao.selectById(1);

(2) Query a piece of data according to the condition:

Employee employeeCondition = new Employee();
employeeCondition.setId(1);
employeeCondition.setLastName("Update test");
//If there are more than one record in the database that meets the incoming criteria, this method cannot be used and errors will be reported.
Employee employee = emplopyeeDao.selectOne(employeeCondition);

Note: The sql statement of this method is where id = 1 and last_name = update the test. If more than one record meets this requirement, an error will be reported.

(3) Return multiple data according to query conditions:
When there are more than one record that meets the specified criteria, the above method will report an error, and this method should be used.

Map<String,Object> columnMap = new HashMap<>();
columnMap.put("last_name","Invincible Eastern");//Write column names in tables
columnMap.put("gender","1");
List<Employee> employees = emplopyeeDao.selectByMap(columnMap);
System.out.println(employees.size());

Note: The query condition is encapsulated in map set, columnMap, which writes the column name in the data table, not the attribute name of the entity class. For example, the attribute name is lastName, and the field in the data table is last_name, which should be written here. The return value of the selectByMap method is received by the list collection.

(4) batch inquiry through id:

List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
List<Employee> employees = emplopyeeDao.selectBatchIds(idList);
System.out.println(employees);

Note: add all the IDs that need to be queried to the list set, then call the selectBatchIds method, and pass it into the list set. This method returns all the records of the corresponding id, and all the returned values are also received by the list.

(5) Paging queries:

List<Employee> employees = emplopyeeDao.selectPage(new Page<>(1,2),null);
System.out.println(employees);

Note: The selectPage method is pagination query, which passes in pagination information. The latter is the pagination condition of null. Let it be null first, and then talk about the use of conditional constructor. This paging is not a physical paging, but a memory paging. That is to say, there is no limit statement when querying. Only when the paging plug-in is configured can real paging be achieved.

4. delete operation:

(1) Delete according to id:

emplopyeeDao.deleteById(1);

(2) Delete:

Map<String,Object> columnMap = new HashMap<>();
columnMap.put("gender",0);
columnMap.put("age",18);
emplopyeeDao.deleteByMap(columnMap);

Note: This method is similar to selectByMap. It encapsulates the condition in columnMap, then calls deleteByMap method and passes it into columnMap. The return value is Integer type, indicating the number of rows affected.

(3) Delete in batches according to id:

 List<Integer> idList = new ArrayList<>();
 idList.add(1);
 idList.add(2);
 emplopyeeDao.deleteBatchIds(idList);

Note: This method is similar to selectBatchIds. It loads the id of the record that needs to be deleted into the idList, then calls deleteBatchIds and passes it into the idList.

 

IV. Global Policy Configuration:

From the small case above, we can find that the entity class needs to specify the database table name with @TableName annotation and the growth strategy of id with @TableId annotation. It doesn't matter if there are fewer entity classes. It's also troublesome if there are more entity classes. So you can configure the global policy in the spring-dao.xml file.

<! - 5. Global Policy Configuration of mybatisplus
<bean id="globalConfiguration" class="com.baomidou.mybatisplus.entity.GlobalConfiguration">
        After version 2.3, the default value of hump naming is true, so it can't be configured - >.
        <!--<property name="dbColumnUnderline" value="true"/>-->
        <! - Global Primary Key Self-Increasing Strategy, 0 means auto - >.
        <property name="idType" value="0"/>
        <! - Global Table Prefix Configuration - >
        <property name="tablePrefix" value="tb_"/>
</bean>

Configuration is not yet available here, and you need to inject configuration into sqlSession Factory to take effect. As follows:

<!-- 3,To configure mybatisplus Of sqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="typeAliasesPackage" value="com.zhu.mybatisplus.entity"/>
        <!-- Injection global configuration -->
        <property name="globalConfig" ref="globalConfiguration"/>
</bean>

In this way, the @TableName annotation and @TableId annotation in the entity class can be removed.
 

5. Conditional constructor (EntityWrapper):

With the above basic CRUD operations, we only need to inherit a BaseMapper to implement most single-form CRUD operations. BaseMapper provides as many as 17 methods for use, which can be extremely convenient to achieve single, batch, paging and other operations, greatly reducing the development burden. But the power of mybatis-plus is not limited to this. See how to deal with the following requirements:
Demand:
We need to paginate the tb_employee table for all users aged 18 to 50 who are male and whose name is xx. How can we achieve this?
MyBatis: We need to write conditional query SQL in the SQL mapping file and use PageHelper plug-in to complete paging. To achieve this simple requirement, we often need to do a lot of repetitive and monotonous work.
Using MP: Still without writing SQL statements, MP provides a powerful conditional constructor, EntityWrapper.

Next, I'll look directly at several cases to understand the use of EntityWrapper.

1. Users whose age of paging query is 18-50 and gender is 0 and whose name is tom:

List<Employee> employees = emplopyeeDao.selectPage(new Page<Employee>(1,3),
     new EntityWrapper<Employee>()
        .between("age",18,50)
        .eq("gender",0)
        .eq("last_name","tom")
);

Note: As can be seen from this case, the paging query is the same as before, and a new page object can pass in the paging information. As for paging conditions, a new EntityWrapper object can be called by calling the relevant methods of the object. The three parameters of the between method are column, value1 and value2. This method indicates that the value of column should be between value1 and value2. eq is the abbreviation of equals. The two parameters of this method, column and value, indicate that the value of column should be equal. Note that column is the field corresponding to the data table, not the property field of the entity class.

2. Query the user whose gender is 0 with a teacher in his name or a in his mailbox:

List<Employee> employees = emplopyeeDao.selectList(
                new EntityWrapper<Employee>()
               .eq("gender",0)
               .like("last_name","Teacher")
                //or()// is not very different from or new.
               .orNew()
               .like("email","a")
);

Note: Paging query is not mentioned, so use selectList, and use EntityWrapper's like method to do fuzzy query. Like method means that the value of column contains value value value value, where like method is to query the record of last_name containing the word "teacher"; "or" expressed by or or New method, the two methods are not very different. You can use either of them. You can feel the difference by yourself through the sql statement of the console.

3. Query gender is 0, sorted by age, simple paging:

List<Employee> employees = emplopyeeDao.selectList(
                new EntityWrapper<Employee>()
                .eq("gender",0)
                .orderBy("age")//Direct order by is ascending, asc
                .last("desc limit 1,3")//Append last to the sql statement (in descending order, paging at the same time)
);

Note: Simple paging refers to paging without page objects. The orderBy method is to sort in ascending order according to the incoming column. To descend the order, you can use the orderByDesc method or the last method as shown in the case. The last method is to append the value value of the last method to the back of the sql statement, in which the final sql statement becomes select order B. Y desc limit 1,3, with desc limit 1,3 added to allow descending sorting and paging.

4. Users whose age of paging query is 18-50 and gender is 0 and whose name is tom:
In addition to EntityWrapper, the conditional constructor also has Condition. Use Conditions to address this requirement:

 List<Employee> employees = emplopyeeDao.selectPage(
                new Page<Employee>(1,2),
                Condition.create()
                        .between("age",18,50)
                        .eq("gender","0")
 );

Note: The difference between Conditions and EntityWrapper is that when creating a conditional constructor, EntityWrapper is created by new, while Conditions is created by a tone create method.

5. Update according to conditions:

@Test
public void testEntityWrapperUpdate(){
        Employee employee = new Employee();
        employee.setLastName("Aoi Sora");
        employee.setEmail("cjk@sina.com");
        employee.setGender(0);
        emplopyeeDao.update(employee,
                new EntityWrapper<Employee>()
                .eq("last_name","tom")
                .eq("age",25)
        );
}

Note: This case indicates that the information of all users whose last_name is tom and age is 25 is updated to the information set in employee.

6. Delete:

emplopyeeDao.delete(
        new EntityWrapper<Employee>()
        .eq("last_name","tom")
        .eq("age",16)
);

Note: This case represents the deletion of all users whose last_name is tom and age is 16.
 

Conclusion:

This is mybatis-plus's introductory tutorial, which introduces how to integrate with spring, the use of general crud, the configuration of global strategy and the use of conditional constructors, but this is not all of MP's content, its strength is not limited to this. Avoid lengthy chapters. For more information on mybatis-plus usage, please refer to< The Use of mybatis-plus--Advancement At the end of the article, the source code of the case will be given.

Posted by storyteller on Thu, 12 Sep 2019 03:16:48 -0700