SpringBoot advanced usage

1, Description of spring boot integration Mybatis

1. Introduction to Mybatis

MyBatis is an excellent persistence layer framework, which supports custom SQL, stored procedures and advanced mapping. MyBatis eliminates almost all JDBC code and the work of setting parameters and obtaining result sets. MyBatis can configure and map primitive types, interfaces and Java POJO s (Plain Old Java Objects) to records in the database through simple XML or annotations.
Summary: MyBatis is an excellent persistence layer framework, which integrates JDBC internally and simplifies the process of users operating the database
Mybatis is a semi automated ORM mapping framework

2. ORM thought

Object Relational Mapping (English: Object Relational Mapping, referred to as ORM, or O/RM, or O/R mapping) is a programming technology used to realize the conversion between data of different types of systems in object-oriented programming language. In effect, it actually creates a "virtual object database" that can be used in the programming language. Nowadays, there are many free and paid ORM products, and some programmers prefer to create their own ORM tools.
Core knowledge:
Purpose: operate the database as an object
1. It is required that the query result set can be automatically encapsulated as an object (read)
2. Encapsulate data with objects, and then (automatically) dynamically generate Sql statements to perform relevant operations (Updates)

3. Spring boot integrates Mybatis process

1)Import dependency jar Package database driver/JDBC package/Spring integration Mybatis package
2)edit application.yml File configuration data source/to configure Spring integration Mybatis
3)edit Mybatis Interface file/edit xxx.xml Mapping file
4)adopt@MapperScan Create a proxy object for the interface

4,@SpringBootTest

Note: this annotation is a SpringBoot program. In order to simplify back-end code testing, a special testing API is provided
Key point: the Spring container is required to manage the object during testing, and the tested object is obtained for testing
Note: Test annotations can only be run in test packages

5. Mybatis call process

1)Spring The container creates a proxy object for the interface. Spring The container startup object is created immediately
2)according to @Autowired Annotation dynamic injection Mapper Proxy object for interface
3)User through Mapper Interface call method.(Perform business operations)
4)Mybatis Dynamic matching according to interface method xml Mapping file for
	4.1) according to Mapper Interface path match xml In the mapping file com.jt.mapper.UserMapper
	4.2)Match according to the method of the interface xml In the mapping file Sql ID,After execution Sql sentence
	4.3)Mybatis Encapsulate the result set as an object and return

6. Description of mybatis statement exception

Method 1: replace the xml Mapping file

Method 2: replace YML file
Method 3: Mybatis link exception caused by IDEA cache

2, MybatisPlus

1. MP introduction

1.1) MP introduction

1.2) what is MP

No invasion: it is only enhanced without change, and its introduction will not affect the existing project, which is as smooth as silk
Low loss: the basic CURD will be injected automatically upon startup, with basically no loss of performance and direct object-oriented operation
Powerful crud operation: built in general Mapper and general Service, most CRUD operations of a single table can be realized only through a small number of configurations, and there is a powerful condition constructor to meet various use requirements
Support Lambda formal call: it is convenient to write various query conditions through Lambda expression, and there is no need to worry about wrong fields
Support automatic generation of primary key: support up to 4 primary key strategies (including distributed unique ID generator - Sequence), which can be configured freely to perfectly solve the primary key problem
Support ActiveRecord mode: support ActiveRecord formal calls. Entity classes only need to inherit Model classes to perform powerful CRUD operations
Support custom global general operations: support global general method injection (Write once, use anywhere)
Built in code generator: code or Maven plug-in can be used to quickly generate Mapper, Model, Service and Controller layer code, support template engine, and more custom configurations for you to use
Built in paging plug-in: Based on MyBatis physical paging, developers do not need to care about specific operations. After configuring the plug-in, writing paging is equivalent to ordinary List query
The paging plug-in supports multiple databases: MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, Postgre, SQLServer and other databases
Built in performance analysis plug-in: it can output Sql statements and their execution time. It is recommended to enable this function during development and testing to quickly find out slow queries
Built in global interception plug-in: it provides intelligent analysis and blocking of full table delete and update operations, and can also customize interception rules to prevent misoperation

2. MP introduction case

Core idea: operate the database with objects, and almost no Sql is written for single table query
Project structure

2.1) import jar package

Note: the enhancement (including) of MybatisPlus to Mybatis. All jar packages only need to be imported into MP, and the original Mybatis needs to be deleted
Add to pox table

<?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>

	<!--coordinate-->
	<groupId>com.jt</groupId>
	<artifactId>springboot_demo3_mp</artifactId>
	<version>1.0-SNAPSHOT</version>

	<!--
	  location: SpringBoot Main role integration SSM,Make the use of the framework more simplified
	  principle: "Out of the box"
	  parent Main role:
			 1.SpringBoot It is internally compatible with almost all current third-party frameworks
			 2.SpringBoot All compatible versions have been defined on the official website
			  (Almost solved the version conflict problem)The version number is hardly written in the future
	  generalization: parent Manage other project version information in the tab.
  -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.5.2</version>
		<relativePath/>
	</parent>

	<properties>
		<java.version>1.8</java.version>
		<!--Skip test class packaging-->
		<skipTests>true</skipTests>
	</properties>

	<!--principle: Import on demand  -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<!--springboot Startup item(implement)Inside the package SpringBoot
			The of the project has been completed"integration"(to configure) The user takes it and uses it
			web Import SpringMVC
			-->
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

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

		<!--Support hot deployment -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
		</dependency>

		<!--add to lombok rely on-->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>

		<!--Introducing database driver -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>

		<!--springBoot Database connection  -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>

		<!--spring integration mybatis  temporary
		   mapper Interface/mapper.xml Mapping file
		  -->

		<!--
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.2.0</version>
		</dependency>
		-->

		<!--Import MP After package,Delete original Mybatis My bag -->
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-boot-starter</artifactId>
			<version>3.4.3</version>
		</dependency>

	</dependencies>

	<!--SpringBoot Project and Maven A plug-in for integration
		You can perform project packaging through plug-ins/test/Document generation and other operations
		matters needing attention: The plug-in cannot be omitted
		When the project is published: java -jar xxxx.jar  report errors:No master list information!!!!
	-->
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<version>2.5.2</version>
			</plugin>
		</plugins>
	</build>


</project>

2.2) configure object relationship mapping, user java

package com.jt.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
 * Object relationship mapping configuration:
 *      1.User The object needs to be with the demo_user table binding
 *      2.User The attributes in the object are bound to the fields in the table one by one
 */
@Data
@Accessors(chain = true)
@TableName("demo_user")
//The function of entity object is to pass parameters
//@Component / / there is no need to hand over the entity object to the Spring container for management
public class User implements Serializable {
    //Primary key auto increment
    @TableId(type= IdType.AUTO)
    //Serialization: ensure data transmission integrity
    private Integer id;

    //@TableField( "name")
    //If the attribute has the same name as the field (including hump rule), the annotation can be omitted
    private String name;
    private Integer age;
    private String sex;
}

2.3) inherit the public API interface, UserMapper

package com.jt.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
//How can the Mybatis interface be managed by the Spring container!!!!!
//@Mapper//Mybatis creates proxy objects for interfaces JDK dynamic proxy objects Spring container management
@Mapper
public interface UserMapper extends BaseMapper<User> {

    //Query all demos_ User table data
    List<User> getAll();
    Integer getId(String name);

}

2.4) edit YML configuration file

server:
  port: 8090

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root
    #If the database password starts with the number 0, you must use the "" number
    #password: "01234"

#SpringBoot integration MP configuration
mybatis-plus:
  #Define alias package: implement object mapping
  type-aliases-package: com.jt.pojo
  #Load a mapping file. One interface corresponds to one mapping file
  mapper-locations: classpath:/mybatis/*.xml
  #Turn on hump mapping
  configuration:
    map-underscore-to-camel-case: true

#Do not print log
debug: false

#The Mapper interface prints Sql logs
logging:
  level:
    com.jt.mapper: debug

2.5) tool API test

@SpringBootTest
public class TestSpringBoot {
    @Autowired
    private UserMapper userMapper;   //Proxy object

    @Test
    public void testGetAll(){
        System.out.println(userMapper.getClass());
        List<User> userList = userMapper.getAll();
        System.out.println(userList);
    }

    /**
     * New user
     *  Mybatis: 1.mapper Interface 2 XML Mapping Sql
     *  MP: Call interface method
     */
    @Test
    public void testInsert(){
        User user = new User();
        user.setName("ha-ha").setAge(30).setSex("male");
        //Single table operations rarely write Sql
        userMapper.insert(user);
    }
}

2.6) print log

server:
  port: 8090

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

#SpringBoot integration MP
mybatis-plus:
  type-aliases-package: com.jt.pojo
  mapper-locations: classpath:/mybatis/*.xml
  configuration:
    map-underscore-to-camel-case: true


# The Mapper interface prints Sql logs
logging:
  level:
    com.jt.mapper: debug

3. MP implementation principle

1)User execution User Object warehousing userMapper.insert(user);
2)Since the generic object needs to be passed in the interface method, find the corresponding generic object according to the user configuration
3)According to the user's interface Mapper Parent interface of interface BaseMapper,according to BaseMapper Generic object in, get information User.class type
4)according to User.class Dynamic acquisition@TableName("demo_user") Get the table name corresponding to the object, and then pass@TableField("name")Bind the corresponding field.,At this point, the object and table are mapped.
5)According to the above mapping relationship,Dynamic splicing Sql sentence.
example: userMapper.insert(user object) How to transform Sql?
		insert into Table name(Field name) values (Property value)
		insert into demo_user(id,name,age,sex) values ("and xx",xx,xx,xx)
MP Dynamically generated Sql hand Mybatis Perform the final data warehousing operation!!!

4. MP usage

4.1 query data according to ID

/**
     * MP: Operate the database with objects
     * Learning: code structure
     * Case 1: query data according to Id=1 ID = primary key
     * Sql: SELECT id,name,age,sex FROM demo_user WHERE id=?
     */
    @Test
    public void getUserById(){
        User user = userMapper.selectById(1);
        System.out.println(user);
    }

4.2) conditional constructor - object encapsulation

/**
     * Case 2: query data according to age=18 sex = "female"
     * Sql: select * from demo_user where age=18 and sex="Female“
     */
    @Test
    public void getUserByAS(){
        //Construct a conditional constructor to dynamically splice where conditions
        User user = new User();
        user.setAge(18).setSex("female");
        //Generate where conditions based on non null properties in the object. By default, and connections are used
        QueryWrapper queryWrapper = new QueryWrapper(user);
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

4.3) condition constructor - special character query

/**
     * Case 3: query data according to age > 18 sex = "female"
     * Sql: select * from demo_user where age>18 and sex="Female“
     * Special characters (xml file): > GT, < LT, = EQ
     *          >= ge, <=le, != ne
     */
    @Test
    public void getUserGT(){
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.gt("age", 18)
                    .eq("sex","female");
        List userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

4.4) conditional constructor like keyword

/**
     * Case 4: query the data containing "Jun" in name
     * Sql: select * from demo_user where name like"%King“
     * Sql2:SELECT id,name,age,sex FROM demo_user WHERE (name NOT LIKE ?)
     */
    @Test
    public void testLike(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //queryWrapper.like("name", "Jun");
        //Look left and right at the position of the% sign
        //queryWrapper.likeLeft("name", "Jun");
        queryWrapper.notLike("name","King" );
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

4.5) condition constructor orderBy

/**
     * Case 5: query users with age > 18 and arrange them in descending order by age. If the age is the same, arrange them in sex
     */
    @Test
    public void testOrderBy(){
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        queryWrapper.gt("age",18)
                    .orderByDesc("age", "sex");
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

4.6) conditional constructor - in keyword

/**
     * Case 6: query data with Id=1,3,5,6,7
     * Keyword: single table query in or efficiency is almost the same
     *        For multi table queries, or is recommended for faster performance
     * Variable parameter type:
     *      1.Variable parameter type data structure is essentially an array
     *      2.When defining a variable parameter type, it must be in the last bit of the method parameter!
     *      void addUser(Integer age,Integer... ids);
     *      void addUser(Integer age,Integer[] ids);
     */
    @Test
    public void testIn(){
        //1. Method 1 condition constructor
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //queryWrapper.in("age","1,3,5,6,7");
        queryWrapper.in("id",1,2,3,4,5,6);
        List<User> userList1 = userMapper.selectList(queryWrapper);
        //2. After calling MP special methods, use object types as much as possible (objects have methods)
        Integer[] ids = new Integer[]{1,2,3,4,5,6};
        List idList = Arrays.asList(ids);
        List<User> userList2 = userMapper.selectBatchIds(idList);
        System.out.println(userList1);
        System.out.println(userList2);
    }

4.7) conditional constructor - dynamic Sql

 /**
     * Case 7: dynamically query the database according to name/sex
     * Resolution: if name/sex has a value, dynamically splice the where condition
     *       Otherwise, the where condition is not written
     * Dynamic Sql implementation: condition parameter
     *             Boolean type value true: splice where condition
     *                        false: No where condition
     * String judgment API:
     *      StringUtils.hasLength(name);
     */
    @Test
    public void testSelectNS(){
        String name = null;
        String sex = "";
        QueryWrapper<User> queryWrapper = new QueryWrapper();
        //Judge whether there is a value
        boolean nameFlag = StringUtils.hasLength(name);
        boolean sexFlag =  StringUtils.hasLength(sex);
        queryWrapper.eq(nameFlag,"name",name)
                    .eq(sexFlag,"sex",sex);
        List userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

4.8) MP update operation

@Test
    public void testUpdate(){
        User user = new User();
        user.setName("Good luck").setAge(100);
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("name","ha-ha");
        int row = userMapper.update(user,updateWrapper);
        System.out.println(row);
    }

    // name = "Yunying" sex = "male" age="16"
    @Test
    public void testUpdateById(){
        User user = new User();
        user.setId(246).setName("greisen").setSex("male").setAge(16);
        //where id=xxx, other non null attributes are regarded as set conditions
        userMapper.updateById(user);
    }

Keywords: Mybatis

Added by DavidGS on Fri, 14 Jan 2022 01:04:12 +0200