Mbatis plus usage details

Posted by my_mind on Sun, 06 Feb 2022 06:44:36 +0100

1, Pure Mybatis is integrated with Mybatis plus.

1. Import dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>cn.itcast.mp</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>itcast-mybatis-plus-simple</module>
        <module>itcast-mabatis-plus-spring</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
    <!-- mybatis-plus Plug in dependency -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.1.1</version>
        </dependency>

        <!-- MySql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
    </dependency>
        <!-- Connection pool -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.24</version>
        </dependency>

        <!--simplify bean Code Toolkit-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>1.18.4</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. Create a profile

log4j.properties:

log4j.rootLogger=DEBUG,A1

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n

jdbc.properties:

jdbc.username=
jdbc.password=
jdbc.url=jdbc:mysql://localhost:3306/mabatis-puls
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.initialSize=5
jdbc.maxActive=10

3. Write mybatis config XML file:

<?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>
        <!--    Load external files-->
        <properties resource="jdbc.properties"></properties>
        <!--    Data source environment-->
        <environments default="development">
                <environment id="development">
                        <transactionManager type="JDBC"></transactionManager>
                        <dataSource type="POOLED">
                                <property name="driver" value="${jdbc.driverClassName}"></property>
                                <property name="url" value="${jdbc.url}"></property>
                                <property name="username" value="${jdbc.username}"></property>
                                <property name="password" value="${jdbc.password}"></property>
                        </dataSource>
                </environment>
        </environments>
        <mappers>
               <mapper resource="UserMapper.xml"></mapper>
        </mappers>
</configuration>

4. Write User entity object: (lombok is used for evolutionary bean operation here)

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/*  Using lombok
 *  @Data : Annotation on class; It provides getting and setting methods for all attributes of the class, as well as equals, canEqual, hashCode and toString methods
    @Setter: Annotation on attributes; Provide a setting method for the property
    @Getter: Annotation on attributes; Providing a getting method for a property
    @Log4j : Annotation on class; Provide a log4j log object with the attribute log for the class
    @NoArgsConstructor: Annotation on class; Provide a parameterless constructor for the class
    @AllArgsConstructor: Annotation on class; Provide a full parameter constructor for the class
  * Specify the @ User table name in the database
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
    private Long id;
    private String user_name;
    private String password;
    private String name;
    private Integer age;
    private String email;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + user_name + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", email='" + email + '\'' +
                '}';
    }
}

5. Inherit UserMapper from BaseMapper and have all the methods in BaseMapper:

import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;


import java.util.List;

public interface UserMapper extends BaseMapper<User> {
    public List<User> findAll();

}

6. Use the MybatisSqlSessionFactoryBuilder process in MP to build


import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.MybatisSqlSessionFactoryBuilder;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MybatistTest {
    @Test
    public void testFindAll() throws IOException {
        InputStream resourceAsFile = Resources.getResourceAsStream("mybatis-config.xml");
        //The MybatisSqlSessionFactoryBuilder in MP is used here
        SqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(resourceAsFile);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        
       //  You can call the methods defined in BaseMapper
        List<User> users = mapper.selectList(null);
        System.out.println(users);
        sqlSession.close();

    }
}

Note:

① In case of operation error:

Solution: add @ TableName to the User object and specify the database table name

2, Spring + Mybatis + MP

The Spring framework is introduced, and the data source and construction are left to Spring management.

 1. Import dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>cn.itcast.mp</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>itcast-mybatis-plus-simple</module>
        <module>itcast-mabatis-plus-spring</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
    <!-- mybatis-plus Plug in dependency -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.1.1</version>
        </dependency>

        <!-- MySql -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
    </dependency>
        <!-- Connection pool -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.24</version>
        </dependency>

        <!--simplify bean Code Toolkit-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
            <version>1.18.4</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
        <!--Spring Relevant coordinates-->
      <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. Write JDBC properties

log4j.rootLogger=DEBUG,A1

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n

3. Write ApplicationContext 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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

    <!--    Sweep bag-->
    <context:property-placeholder location="classpath:jdbc.properties"/>

    <!-- Define data source -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
          destroy-method="close">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="maxActive" value="10"/>
        <property name="minIdle" value="5"/>
    </bean>
    <!--Use here MP Provided sessionFactory  complete MP and Spring Integration of-->
    <bean id="sessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--scanning mapper Interface, still using Mybatis Native scanner-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="mapper"/>
    </bean>

</beans>

4. Write User object and UserMapper interface:

package pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
    private Long id;
    private String user_name;
    private String password;
    private String name;
    private Integer age;
    private String email;

  
}
package mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import pojo.User;

/**
 * @Description: // Class description
 * @ClassName: UserMapper    // Class name
 * @Author: Zeng Weihong / / creator
 * @Date: 2022/1/30 11:59   // time
 * @Version: 1.0       // edition
 */
public interface UserMapper extends BaseMapper<User> {

}

5. Test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class TestSpringMP {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectList(){
        List<User> users = this.userMapper.selectList(null);
        for (User user : users) {
            System.out.println(user);
        }
    }
}

3, SpringBoot + Mybatis + MP

Using SpringBoot will further simplify MP integration. It should be noted that using SpringBoot needs to inherit the parent.

 1. Import dependency

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <groupId>cn.itcast.mp</groupId>
    <artifactId>itcast-mp-springboot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--Toolkit to simplify code-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--mybatis-plus of springboot support-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2. Prepare configuration file

log4j.properties:

log4j.rootLogger=DEBUG,A1

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n

3. Write application properties

spring.application.name = itcast-mp-springboot
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mp?
useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=Zwh1174946082!

4. Prepare pojo

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {
private Long id;
private String userName;
private String password;
private String name;
private Integer age;
private String email;
}

5. Write mapper

import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface UserMapper extends BaseMapper<User> {
}

6. Write startup class

package cn.itcast.mp;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;

@MapperScan("cn.itcast.mp.mapper") //Set the scanning package of mapper interface
@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
    SpringApplication.run(MyApplication.class, args);
}
}

7. Write test

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect() {

        List<User> userList = userMapper.selectList(null);
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

4, Detailed explanation of general CRUD

1) Annotation details

1. Set the generation strategy of id - @ TableId details

@TableId , is the generation policy for setting id

① AUTO --- self increment of database ID

② NONE --- this type is not set with primary key

③ INPUT --- user INPUT ID * * * * this type can be filled through self registered automatic filling plug-in*****

        

The following three types are automatically filled only when the inserted object ID is empty.

        ①ID_WORKER --- globally unique ID (idWorker)

② UUID --- globally unique ID (UUID)

        ③ID_WORKER_STR --- globally unique ID of string (string representation of idworker)

For example:

         

2.@TableField

In MP, some attributes of the field can be specified through @ TableField annotation. There are three common problems to be solved:

1. Inconsistency between attribute name and field name in object (non hump)

        

2. The attribute field in the object does not exist in the table

        

3. You do not want an attribute value to appear in the query result

        

2) Add, delete, modify and query

1. Insert operation

Test case:

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestUserMapper {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        User user = new User();
        user.setMail("2@itcast.cn");
        user.setAge(301);
        user.setUserName("caocao1");
        user.setName("Cao Cao 1");
        user.setPassword("123456");
        user.setAddress("Beijing");

        int result = this.userMapper.insert(user); //result the number of rows affected by the database
        System.out.println("result => " + result);

        //Get the id value after self growth, and the id value after self growth will be backfilled into the user object
        System.out.println("id => " + user.getId());
    }

2. Update operation

① Update by id

Method definition:

/**
* Modify according to ID
*
* @param entity Entity object
*/
int updateById(@Param(Constants.ENTITY) T entity);

Mapped SQL statement: UPDATE tb_user SET age=? WHERE id=?  

@RunWith(SpringRunner.class)
@SpringBootTest
public class TestUserMapper {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testUpdateById() {
        User user = new User();
        user.setId(1L); //Condition, updated by id
        user.setAge(19); //Updated fields
        user.setPassword("666666");

        int result = this.userMapper.updateById(user);
        System.out.println("result => " + result);
    }
    }

② Update according to conditions

Method definition:

/**
* Update the record according to the whereEntity condition
*
* @param entity Entity object (set condition value, nullable)
* @param updateWrapper Entity object encapsulates operation class (null able, and entity in it is used to generate where statement)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T>
updateWrapper);

Mapped SQL statement: UPDATE tb_user SET age=? WHERE id = ?

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import net.minidev.json.writer.UpdaterMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;


//Update via QueryWrapper
    @Test
    public void testUpdate() {
        User user = new User();
        user.setAge(20); //Updated fields
        user.setPassword("8888888");

        //update criteria
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("user_name", "zhangsan"); //Match user_ Name = user data of Zhangsan

        //Update according to conditions
        int result = this.userMapper.update(user, wrapper);
        System.out.println("result => " + result);
    }


    //Alternatively, update through UpdateWrapper
    @Test
    public void testUpdate2() {

        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.set("age", 21).set("password", "999999") //For the updated field, the name of the field is set instead of the attribute of the entity
        .eq("user_name", "zhangsan"); //Updated conditions

        //Update according to conditions
        int result = this.userMapper.update(null, wrapper);
        System.out.println("result => " + result);
    }

}

3. Delete

① Delete by id -- deleteById

Method definition:

/**
* Delete by ID
*
* @param id Primary key ID
*/
int deleteById(Serializable id);

Mapped SQL statement: DELETE FROM tb_user WHERE id=?

import cn.itcast.mp.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testDeleteById(){
        // Delete data according to id
        int result = this.userMapper.deleteById(9L);
        System.out.println("result => " + result);
    }
}

② Batch delete data according to id -- deleteBatchIds

Method definition:

/**
* Delete (batch delete according to ID)
*
* @param idList List of primary key ID S (cannot be null and empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable>
idList);

Mapped SQL statement: DELETE FROM tb_user WHERE id IN ( ? , ? , ? )

import cn.itcast.mp.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    
     @Test
    public void  testDeleteBatchIds(){
        // Delete data in batch according to id
        int result = this.userMapper.deleteBatchIds(Arrays.asList(10L, 11L));
        System.out.println("result => " + result);
    }

③ Delete by map -- deleteByMap

Method definition:

/**
* Delete the record according to the columnMap condition
*
* @param columnMap Table field map object
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

Mapped SQL statement: DELETE FROM tb_user WHERE name = ? AND age = ?

import cn.itcast.mp.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testDeleteByMap(){

        Map<String,Object> map = new HashMap<>();
        map.put("user_name", "zhangsan");
        map.put("password", "999999");

        // Delete the data according to the map, and the relationship between multiple conditions is and
        int result = this.userMapper.deleteByMap(map);
        System.out.println("result => " + result);
    }

④ Encapsulating conditional deletion through entity object -- delete

Method definition:

/**
* Delete the record according to the entity condition
*
* @param wrapper Entity object encapsulates operation class (null able)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);

Mapped SQL statement: DELETE FROM tb_user WHERE name=? AND age=?

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testDelete(){

        //Usage 1:
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        wrapper.eq("user_name", "caocao1")
//                .eq("password", "123456");

        //Usage 2 (recommended):
        User user = new User();
        user.setPassword("123456");
        user.setUserName("caocao");

        QueryWrapper<User> wrapper = new QueryWrapper<>(user);

        // Delete according to packaging conditions
        int result = this.userMapper.delete(wrapper);
        System.out.println("result => " + result);
    }

4. Query operation

MP provides a variety of query operations, including query by id, batch query, query of single data, query list, paging query and so on.

① Query by id -- selectById

Method definition:

/**
* Query by ID
*
* @param id Primary key ID
*/
T selectById(Serializable id);

Mapped SQL statement:

        SELECT id,user_name,password,name,age,email FROM tb_user WHERE id=?

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectById() {

        //Query data by id
        User user = this.userMapper.selectById(2L);
        System.out.println("result = " + user);
    }
}

② Batch query data by id - selectBatchIds()

Method definition:

/**
* Query (batch query by ID)
*
* @param idList List of primary key ID S (cannot be null and empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable>
idList);

Mapped SQL statement:

SELECT id,user_name,password,name,age,email FROM tb_user WHERE id IN ( ? , ? , ? )

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Arrays;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectBatchIds(){
        // Batch query data according to id
        List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 4L, 100L));
        for (User user : users) {
            System.out.println(user);
        }
    }
}

③ Query and return a piece of data according to the query criteria (there is only one piece of data in the query result, and an error will be reported if multiple pieces are found) --- selectOne()

Method definition:

/**
* Query a record according to the entity condition
*
* @param queryWrapper Entity object encapsulates operation class (null able)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Mapped SQL statement:

SELECT id,user_name,password,name,age,email FROM tb_user WHERE name = ?

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectOne(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //query criteria
        wrapper.eq("password", "123456");
        // When more than one piece of data is queried, an exception will be thrown
        User user = this.userMapper.selectOne(wrapper);
        System.out.println(user);
    }
}

④ Total number of data pieces queried according to criteria - selectCount()

Method definition:

/**
* Query the total number of records according to Wrapper conditions
*
* @param queryWrapper Entity object encapsulates operation class (null able)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Mapped SQL statement:

        SELECT COUNT( 1 ) FROM tb_user WHERE age > ?

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;


     @Test
    public void testSelectCount(){

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.gt("age", 20); // Conditions: users over 20 years old

        // Query the number of data according to criteria
        Integer count = this.userMapper.selectCount(wrapper);
        System.out.println("count => " + count);
    }
}

⑤ Query and return the list of all records according to the criteria ----- selectList()

Method definition:

/**
* Query all records according to the entity condition
*
* @param queryWrapper Entity object encapsulates operation class (null able)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Mapped SQL statement:

     SELECT id,user_name,password,name,age,email FROM tb_user WHERE age > ?

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;


    @Test
    public void testSelectList(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Set query criteria
        wrapper.like("email", "itcast");

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }
}

⑥ Query and return all data according to conditions (and turn pages) --- selectPage()

Method definition:

/**
* Query all records (and turn the page) according to the entity condition
*
* @param page Paging query criteria (can be rowboundaries. Default)
* @param queryWrapper Entity object encapsulates operation class (null able)
*/
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Mapped SQL statement:

        SELECT COUNT(1) FROM tb_user WHERE age > ?

        SELECT id,user_name,password,name,age,email FROM tb_user WHERE age > ? LIMIT ?,?

To configure the paging plug-in:

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("cn.itcast.mp.mapper") //Set the scanning package of mapper interface
public class MybatisPlusConfig {

    /**
    * Paging plug-in
    */
    @Bean
    public PaginationInterceptor paginationInterceptor() {

        return new PaginationInterceptor();
    }
}

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;


     // Test paging query
    @Test
    public void testSelectPage(){

        Page<User> page = new Page<>(3,1); //Query the first page, query 1 piece of data

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //Set query criteria
        wrapper.like("email", "itcast");

        IPage<User> iPage = this.userMapper.selectPage(page, wrapper);
        System.out.println("Total number of data: " + iPage.getTotal());
        System.out.println("Total data pages: " + iPage.getPages());
        System.out.println("Current pages: " + iPage.getCurrent());

        List<User> records = iPage.getRecords();
        for (User record : records) {
            System.out.println(record);
        }

    }

5, Principle of SQL injection

In MP, ISqlInjector is responsible for SQL injection. It is an interface and AbstractSqlInjector is its implementation class. The implementation relationship is as follows:

AbstractSqlInjector is mainly injected by the inspectInject() method, as follows:

@Override
public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?>
mapperClass) {
    Class<?> modelClass = extractModelClass(mapperClass);
    if (modelClass != null) {
        String className = mapperClass.toString();
        Set<String> mapperRegistryCache =
GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
    if (!mapperRegistryCache.contains(className)) {
        List<AbstractMethod> methodList = this.getMethodList();
        if (CollectionUtils.isNotEmpty(methodList)) {
            TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant,
modelClass);
            // Loop injection custom method
            methodList.forEach(m -> m.inject(builderAssistant, mapperClass,modelClass, tableInfo));
    } else {
            logger.debug(mapperClass.toString() + ", No effective injection method was found.");
        }
        mapperRegistryCache.add(className);
        }
    }
}

In the implementation method, methodlist forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); Is the key, loop traversal method, injection.

Finally, the abstract method injectMappedStatement is called for real injection:

/**
* Custom injected MappedStatement
*
* @param mapperClass mapper Interface
* @param modelClass mapper generic paradigm
* @param tableInfo Database table reflection information
* @return MappedStatement
*/
public abstract MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo);

View the implementation of this method:

Take SelectById as an example:

public class SelectById extends AbstractMethod {

@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
    SqlMethod sqlMethod = SqlMethod.LOGIC_SELECT_BY_ID;
    SqlSource sqlSource = new RawSqlSource(configuration,
String.format(sqlMethod.getSql(),
    sqlSelectColumns(tableInfo, false),
    tableInfo.getTableName(), tableInfo.getKeyColumn(),tableInfo.getKeyProperty(),
tableInfo.getLogicDeleteSql(true, false)), Object.class);

    return this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(),sqlSource, modelClass, tableInfo);
    }
}

You can see that the SqlSource object is generated, and then the SQL is added to the meppedStatements through the addSelectMappedStatement method.

6, Disposition

1) Basic configuration

1.configLocation ---- the location of the name configuration file

MyBatis Configuration file location. If you have a separate MyBatis Configuration, please configure its path to configLocation. For details of MyBatis Configuration, please refer to the official documents of MyBatis.

Spring Boot:  

 mybatis-plus.config-location = classpath:mybatis-config.xml

Spring MVC:

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>

2. Maperlocations ---- the location of configuring custom methods

The XML file location corresponding to MyBatis Mapper. If you have a custom method in Mapper (there is a custom implementation in XML), you need to configure it and tell Mapper the corresponding XML file location.

 Spring Boot:

 mybatis-plus.mapper-locations = classpath*:mybatis/*.xml

The scanning path of Maven multi module project should start with classpath *: (that is, load XML files under multiple jar packages)

Spring MVC:

<bean id="sqlSessionFactory"
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="mapperLocations" value="classpath*:mybatis/*.xml"/>
</bean>

3.typeAliasesPackage --- configure the alias package scanning path. After configuration, you can directly use the class name

MyBaits alias package scan path, through this attribute can be registered to the class in the package alias, after registration in the Mapper corresponding XML file can use the class name directly, instead of using the fully qualified class name (that is, when XML calls do not include the package name).

 Spring Boot:

mybatis-plus.type-aliases-package = cn.itcast.mp.pojo

Spring MVC:

<bean id="sqlSessionFactory"
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="typeAliasesPackage" value="com.baomidou.mybatisplus.samples.quickstart.entity"/>
</bean>

2) Advanced configuration

The Configuration in this section is mostly the Configuration supported by MyBatis natively, which means that you can configure it in the form of MyBatis XML Configuration file.

        

         1.mapUnderscoreToCamelCase ---- configure whether to enable automatic hump naming rule mapping

  • Type: boolean
  • Default value: true

Whether to enable automatic hump naming rule (camel case) mapping, that is, from the classic database column name a_ A similar mapping from column (named by underscore) to the classic Java attribute name aColumn (named by hump).

Note: the default value of this attribute in MyBatis is false. In MyBatis plus, this attribute will also be used to generate the select body of the final SQL. If your database name complies with the rules, you do not need to specify the database field name with the @ TableField annotation.

SpringBoot:

#Turn off automatic hump mapping. This parameter cannot be compared with mybatis plus Config location exists at the same time
mybatis-plus.configuration.map-underscore-to-camel-case=false

        2.cacheEnabled ---- configure whether caching is required

  • Type: boolean
  • Default value: true

Globally turn on or off any cache that has been configured by all mappers in the configuration file. The default is true.

        SpringBoot:

 mybatis-plus.configuration.cache-enabled=false

3) DB policy configuration

1.idType ---- configure primary key type

  • Type: com baomidou. mybatisplus. annotation. IdType
  • Default: ID_WORKER

The global default primary key type. After setting, the @ TableId(type = IdType.AUTO) configuration in the entity object can be omitted.

SpringBoot: 

 mybatis-plus.global-config.db-config.id-type=auto

 SpringMVC:

<!--Use here MP Provided sqlSessionFactory,It's done Spring And MP Integration of-->
<bean id="sqlSessionFactory"
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="globalConfig">
        <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">
            <property name="dbConfig">
                <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                    <property name="idType" value="AUTO"/>
                </bean>
            </property>
        </bean>
    </property>
</bean>

3.tablePrefix----

  • Type: String
  • Default: null

Table name prefix. The @ TableName() configuration can be omitted after global configuration.

 SpringBoot:

 mybatis-plus.global-config.db-config.table-prefix=tb_

SpringMVC:

<bean id="sqlSessionFactory"
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="globalConfig">
        <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig">
            <property name="dbConfig">
                <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">
                    <property name="idType" value="AUTO"/>
                    <property name="tablePrefix" value="tb_"/>
                </bean>
            </property>
    </bean>
    </property>
</bean>

7, Conditional constructor

In MP, the implementation class relationship of Wrapper interface is as follows:

Note: the parent classes of QueryWrapper(LambdaQueryWrapper) and UpdateWrapper(LambdaUpdateWrapper) are used to generate the where conditions of sql, and the entity attribute is also used to generate the where conditions of sql. Note: the where conditions generated by entity have no associated behavior with the where conditions generated by using various APIs.

1) allEq

① Explain

  • allEq(Map params)
  • allEq(Map params, boolean null2IsNull)
  • allEq(boolean condition, Map params, boolean null2IsNull)

Individual parameter description: params: key is the database field name, value is the field value null2IsNull: if it is true, the isNull method will be called when the value of the map is null, and if it is false, the value with null will be ignored

  • Example 1: allEq({id:1,name: "Lao Wang", age: null}) -- > id = 1 and name = 'Lao Wang' and age is null
  • Example 2: allEq({id:1,name: "Lao Wang", age: null}, false) -- > id = 1 and name = 'Lao Wang'

 

  • allEq(BiPredicate filter, Map params)
  • allEq(BiPredicate filter, Map params, boolean null2IsNull)
  • allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull)

Description of individual parameters: filter: filter function, whether to allow fields to pass in params and null2IsNull in comparison conditions: the same as above

Example 1: alleq ((k, V) - > k.indexof ("a") > 0, {ID: 1, name: "Lao Wang", age: null}) - > name = 'Lao Wang' and age is null

Example 2: alleq ((k, V) - > k.indexof ("a") > 0, {ID: 1, name: "Lao Wang", age: null}, false) - > name = 'Lao Wang'

Test:

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testWrapper() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //Set conditions
        Map<String,Object> params = new HashMap<>();
        params.put("name", "Cao Cao");
        params.put("age", "20");
        params.put("password", null);

        // wrapper.allEq(params);//SELECT * FROM tb_user WHERE password IS NULL AND name = ? AND age = ?

        // wrapper.allEq(params,false); //SELECT * FROM tb_user WHERE name = ? AND age = ?

        // wrapper.allEq((k, v) -> (k.equals("name") || k.equals("age")) ,params);//SELECT * FROM tb_user WHERE name = ? AND age = ?

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
        System.out.println(user);
        }
    }
}

2) Basic comparison operation

  • eq equals=
  • ne is not equal to < >
  • gt > greater than >
  • ge > greater than or equal to >=
  • lt < less than<
  • le = less than or equal to<=
  • BETWEEN , BETWEEN 1 AND 2
  • NOT BETWEEN not between 1 AND 2
  • In field in (value. Get (0), value get(1), ...)
  • Not in field NOT IN (v0, v1,...)
import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testEq() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,user_name,password,name,age,email FROM tb_user WHERE password = ? AND age >= ? AND name IN (?,?,?)

wrapper.eq("password", "123456").ge("age", 20).in("name", "Li Si", "Wang Wu", "Zhao Liu");

        List<User> users = this.userMapper.selectList(wrapper);
            for (User user : users) {
            System.out.println(user);
        }
    }
}

3) Fuzzy query

  • like
    • % 'LIKE value
    • Example: like("name", "Wang") --- > name like '% Wang%'
  • notLike
    • NOT LIKE '% value%'
    • Example: notLike("name", "Wang") --- > name not like '% Wang%'
  • likeLeft
    • LIKE '% value'
    • Example: likeLeft("name", "King") --- > name like '% King'
  • likeRight
    • LIKE 'value%'
    • Example: likereight ("name", "Wang") --- > name like 'Wang%'
import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testWrapper() {

        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,user_name,password,name,age,email FROM tb_user WHERE name LIKE ?
        //Parameters:% 1% (String)

        wrapper.like("name", "Cao");
        
        List<User> users = this.userMapper.selectList(wrapper);
            for (User user : users) {
            System.out.println(user);
        }
    }
}

4) Sort

  • orderBy
    • Sorting: ORDER BY field
    • Example: orderby (true, true, "Id", "name") --- > order by ID ASC, name ASC
  • orderByAsc
    • Sorting: ORDER BY field ASC
    • Example: orderbyasc ("Id", "name") --- > order by ID ASC, name ASC
  • orderByDesc
    • Sorting: ORDER BY field DESC
    • Example: orderbydesc ("Id", "name") --- > order by ID DESC, name desc
import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testWrapper() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESC

        wrapper.orderByDesc("age");

        List<User> users = this.userMapper.selectList(wrapper);
            for (User user : users) {
            System.out.println(user);
        }
    }
}

 

5) Logical query

  • or
    • Splice OR
    • Actively calling or means that the next method is not connected with and! (if or is not called, and connection is used by default.)
  • and
    • AND nesting
    • Example: and (I - > i.eq ("name", "Li Bai") ne("status", "alive") --- > and (name = 'Li Bai' and status < > 'alive')
import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testWrapper() {

        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,user_name,password,name,age,email FROM tb_user WHERE name = ? OR age = ?

        wrapper.eq("name","Li Si").or().eq("age", 24);

        List<User> users = this.userMapper.selectList(wrapper);
            for (User user : users) {
            System.out.println(user);
        }
    }
}

6) select

In MP query, all fields are queried by default. If necessary, you can also specify fields through the select method.

 

import cn.itcast.mp.mapper.UserMapper;
import cn.itcast.mp.pojo.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testWrapper() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();

        //SELECT id,name,age FROM tb_user WHERE name = ? OR age = ?

        wrapper.eq("name", "Li Si").or().eq("age", 24).select("id", "name", "age");

        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) {
            System.out.println(user);
        }
    }
}

8, ActiveRecord

ActiveRecord also belongs to the ORM (object relationship mapping) layer. It was first proposed by Rails and follows the standard ORM model: table mapping to record, record mapping to object, and field mapping to object attribute. With the naming and configuration conventions followed, the operation of the model can be quickly realized to a great extent, and it is simple and easy to understand.

The main idea of ActiveRecord is:

  • Create a class for each database table, and each object instance of the class corresponds to a row of records in the database table; Generally, each Field of the table has a corresponding Field in the class;
  • ActiveRecord is also responsible for persisting itself. ActiveRecord encapsulates the access to the database, namely CURD;;
  • ActiveRecord is a domain model that encapsulates some business logic;

(I) start AR journey

In MP, starting AR is very simple. You only need to inherit the entity object from the Model.

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User extends Model<User> {
    private Long id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

 

9, Mybatis plus plug-in

1) mybatis plug-in mechanism

MyBatis allows you to intercept calls at some point during the execution of mapped statements. By default, MyBatis allows the use of plug-ins to intercept method calls, including:

        1. The executor (update, query, flushstatements, commit, rollback, gettransaction, close, isclosed) intercepts the method of the executor

        2. ParameterHandler (getParameterObject, setParameters) intercepts the processing of parameters

        3. ResultSetHandler (handleResultSets, handleOutputParameters) intercepts the processing of result sets

        4. StatementHandler (prepare, parameterize, batch, update, query) intercepts the processing constructed by Sql syntax

We have seen some methods that can intercept the Executor interface, such as update, query, commit, rollback and other methods, as well as some methods of other interfaces.

The general summary is as follows:

                        1. Method of intercepting actuator

                        2. Processing of interception parameters

                        3. Processing of interception result set

                        4. Processing of intercepting Sql syntax construction

Interceptor example:

package cn.itcast.mp.plugins;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;

import java.util.Properties;

@Intercepts({@Signature(
        type= Executor.class,
        method = "update",
        args = {MappedStatement.class,Object.class})})
public class MyInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        //Interception method, location of specific business logic writing
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        //Create a proxy object for the target object to add the current interceptor to the object
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {
        //Property settings
    }
}

Inject into Spring container:

/**
* custom interceptor 
*/
@Bean
public MyInterceptor myInterceptor(){
    return new MyInterceptor();
}

2) Execute analysis plug-in

The MP provides a plug-in for SQL analysis, which can be used to block the update and deletion of the whole table,

Note: this plug-in is only applicable to the development environment, not the production environment.

SpringBoot configuration:

@Bean
public SqlExplainInterceptor sqlExplainInterceptor(){

    SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();

    List<ISqlParser> sqlParserList = new ArrayList<>();

    // Attack SQL, block parser and join parsing chain
    sqlParserList.add(new BlockAttackSqlParser());
    sqlExplainInterceptor.setSqlParserList(sqlParserList);

    return sqlExplainInterceptor;
}

3) Performance analysis plug-in

The execution time of each statement will exceed the maximum execution time of the interceptor, which can be used to analyze the performance of each statement.

This plug-in is only used in the development environment and is not recommended for the production environment.

to configure:

<configuration>
<plugins>
        <!-- Performance analysis plug-in -->
<!-- SQL Perform performance analysis and use the development environment, which is not recommended online. maxTime refer to sql Maximum execution time -->
        <plugin interceptor="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor">
            <!--Maximum execution time in milliseconds-->
            <property name="maxTime" value="100"/>
            <!--For output SQL Format, default to false-->
            <property name="format" value="true"/>
        </plugin>
</configuration>

 

4) Optimistic lock plug-in

1. Main applicable scenarios

Intention: when you want to update a record, you want it not to be updated by others

Optimistic lock implementation method:

  • When the record is fetched, the current version is obtained
  • When updating, bring this version
  • When updating, set version = newVersion where version = oldVersion
  • If the version is incorrect, the update fails

Plug in configuration:

①spring xml:

<bean class="com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor"/>

②spring boot:

@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
    return new OptimisticLockerInterceptor();
}

Use steps:

The @ Version annotation needs to be added to the entity field.

First, add the version field to the table and set the initial value to 1:

ALTER TABLE `tb_user`
ADD COLUMN `version` int(10) NULL AFTER `email`;

UPDATE `tb_user` SET `version`='1';

Step 2: add the Version field for the User entity object and add the @ Version annotation:

@Version
private Integer version;

Test:

  @Test
    public void testUpdateVersion(){
        User user = new User();
        user.setId(2L);// query criteria

        User userVersion = user.selectById();

        user.setAge(23); // Updated data
        user.setVersion(userVersion.getVersion()); // Current version information

        boolean result = user.updateById();
        System.out.println("result => " + result);
    }

Special note:

  • The only supported data types are: int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • newVersion = oldVersion + 1 under integer type
  • newVersion will be written back to entity
  • Only updateById(id) and update(entity, wrapper) methods are supported
  • Under the update(entity, wrapper) method, the wrapper cannot be reused!!!

10, The Sql injector implements custom global operations

When we need to extend the methods in BaseMapper, we need to use the Sql injector

① Write MyBaseMapper (other mappers can inherit this Mapper, so as to realize unified extension)

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.List;

public interface MyBaseMapper<T> extends BaseMapper<T> {
    List<T> findAll();

    // Extend other methods
}

Note: all other mappers should inherit from MyBaseMapper, while MyBaseMapper should inherit from BaseMapper

For example:

package cn.itcast.mp.mapper;

import cn.itcast.mp.pojo.User;

public interface UserMapper extends MyBaseMapper<User> {

    User findById(Long id);
}

② Write MySQL injector

If we inherit AbstractSqlInjector directly, the methods in the original BaseMapper will fail, so we choose to inherit DefaultSqlInjector for extension.

 

package cn.itcast.mp.injectors;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;

import java.util.ArrayList;
import java.util.List;

public class MySqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList() {
        List<AbstractMethod> list = new ArrayList<>();

        // Gets the collection in the parent class
        list.addAll(super.getMethodList());

        // Custom re extension method
        list.add(new FindAll());

        return list;
    }
}

③ Write FindAll

package cn.itcast.mp.injectors;

import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;

public class FindAll extends AbstractMethod {

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {

        String sql = "select * from " + tableInfo.getTableName();
        SqlSource sqlSource = languageDriver.createSqlSource(configuration,sql, modelClass);

        return this.addSelectMappedStatement(mapperClass, "findAll", sqlSource, modelClass, tableInfo);
    }
}

 

④ Register to the Spring container

/**
     * Inject custom SQL injector
     * @return
     */
    @Bean
    public MySqlInjector mySqlInjector(){
        return new MySqlInjector();
    }

11, Auto fill function

Sometimes we may have such requirements. When inserting or updating data, we hope that some fields can be filled with data automatically, such as password, version, etc. This function is provided in MP, which can realize automatic filling.

Development steps:

① Add @ TableField annotation

@TableField(fill = FieldFill.INSERT) //Populate when inserting data
private String password;

FieldFill provides a variety of mode options:

public enum FieldFill {
    /**
    * Do not process by default
    */
    DEFAULT,
    /**
    * Fill in fields on insertion
    */
    INSERT,
    /**
    * Fill in fields when updating
    */
    UPDATE,
    /**
    * Fill in fields when inserting and updating
    */
    INSERT_UPDATE
}

② Write MyMetaObjectHandler

package cn.itcast.mp.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
        * Fill in when inserting data
     * @param metaObject
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // Get the value of password first, and then judge. If it is empty, fill it in. If it is not empty, do not process it
        Object password = getFieldValByName("password", metaObject);
        //Fill in if the field is empty
        if(null == password){
           setFieldValByName("password", "888888", metaObject);
        }
    }

    /**
     * Fill in when updating data
     * @param metaObject
     */
    @Override
    public void updateFill(MetaObject metaObject) {

    }
}

12, Logical deletion

When developing the system, sometimes when realizing the function, the deletion operation needs to realize logical deletion. The so-called logical deletion is to mark the data as deletion, rather than the real physical deletion (non DELETE operation). The status conditions need to be carried during the query to ensure that the marked data is not queried. The purpose of this is to prevent the data from being really deleted.

Development steps:

① modify table structure

TB_ The deleted field is added to the user table to indicate whether the data has been deleted. 1 means deleted and 0 means not deleted.

ALTER TABLE `tb_user`
ADD COLUMN `deleted` int(1) NULL DEFAULT 0 COMMENT '1 For deleted, 0 for not deleted' AFTER
`version`;

At the same time, modify the User entity, add the deleted attribute and add the @ TableLogic annotation:

@TableLogic
private Integer deleted;

② Disposition

application.properties:

# Logical deleted value (default = 1)
mybatis-plus.global-config.db-config.logic-delete-value=1
# Logical undeleted value (default is 0)
mybatis-plus.global-config.db-config.logic-not-delete-value=0

13, General enumeration

It solves the cumbersome configuration and makes mybatis use enumeration attributes gracefully!

Development steps:

① Modify table structure

ALTER TABLE `tb_user`
ADD COLUMN `sex` int(1) NULL DEFAULT 1 COMMENT '1-Male, 2-female' AFTER `deleted`;

② Define enumeration

package cn.itcast.mp.enums;

import com.baomidou.mybatisplus.core.enums.IEnum;

public enum SexEnum implements IEnum<Integer> {

    MAN(1,"male"),
    WOMAN(2,"female");

    private int value;
    private String desc;

    SexEnum(int value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    @Override
    public Integer getValue() {
        return this.value;
    }

    @Override
    public String toString() {
        return this.desc;
    }
}

③ Disposition

# Enumerate package scans
mybatis-plus.type-enums-package=cn.itcast.mp.enums

④ Modify entity

 private SexEnum sex;

14, Code generator

AutoGenerator is the code generator of mybatis plus. Through AutoGenerator, you can quickly generate the code of Entity, Mapper, Mapper XML, Service, Controller and other modules, which greatly improves the development efficiency.

Development steps:

① Create project import package

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <groupId>cn.itcast.mp</groupId>
    <artifactId>itcast-mp-generator</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--mybatis-plus of springboot support-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

② Write code (generally applied directly)

package cn.itcast.mp.generator;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
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.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * <p>
 * mysql Code generator demo example
 * </p>
 */
public class MysqlGenerator {

    /**
     * <p>
     * Read console content
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("Please enter" + tip + ": ");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("Please enter the correct" + tip + "!");
    }

    /**
     * RUN THIS
     */
    public static void main(String[] args) {
        // Code generator 
        AutoGenerator mpg = new AutoGenerator();

        // Global configuration
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("itcast");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // Data source configuration
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&useSSL=false&characterEncoding=utf8");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // Package configuration
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("Module name"));
        pc.setParent("cn.itcast.mp.generator");
        mpg.setPackageInfo(pc);

        // Custom configuration
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // Custom input file name
                return projectPath + "/itcast-mp-generator/src/main/resources/mapper/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        mpg.setTemplate(new TemplateConfig().setXml(null));

        // Policy configuration
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//        strategy.setSuperEntityClass("com.baomidou.mybatisplus.samples.generator.common.BaseEntity");
        strategy.setEntityLombokModel(true);
//        strategy.setSuperControllerClass("com.baomidou.mybatisplus.samples.generator.common.BaseController");
        strategy.setInclude(scanner("Table name"));
        strategy.setSuperEntityColumns("id");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        // When selecting freemaker engine, you need to specify the following addition. Note that pom dependency must be present!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}

15, MybatisX rapid development plug-in

MybatisX is a rapid development plug-in based on IDEA, which is born for efficiency.

Installation method: open IDEA, enter file - > Settings - > plugins - > Browse repositories, enter mybatisx to search and install.

Function: Java and XML call back and jump Mapper method to automatically generate XML

Topics: Java Spring eureka