Spring boot integrates mybatis

Help me to the Internet cafe 2022-05-14 14:39:47 阅读数:580

springbootintegratesmybatis

MyBatis brief introduction

MyBatis Is an excellent persistence layer framework , It supports customization SQL、 Stored procedures and high-level mappings .MyBatis It dispenses with almost everything JDBC Code and the work of setting parameters and getting result sets .MyBatis It can be done by simple XML Or annotations to configure and map primitive types 、 Interface and Java POJO(Plain Ordinary Java Objects, Simple Java object ) For records in the database .

Reference from MyBatis The official profile of .

MyBatis As an excellent persistence layer framework , Has the following advantages :

  1. Small and easy to learn .

  2. Compared with JDBC Reduces a lot of redundant code .

  3. take SQL Statement is separated from program code , Reduced coupling , Easy to manage .

  4. Provide XML label , Support writing dynamics SQL sentence .

  5. Provide mapping label , Support Java Objects and databases ORM Mapping of fields .

MyBatis practice

So let's create one Spring Boot project , Integrate MyBatis, Simple implementation CRUD function .

1. Introduce dependencies

POM The documents are as follows :

<?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 https://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.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot-mybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-mybatis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

2. To configure MySQL and MyBatis

The configuration file application.yml Is as follows :

# To configure MySQL
spring:
datasource:
url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# To configure MyBatis
mybatis:
mapper-locations: classpath:mapper/*
type-aliases-package: com.example.entity
configuration:
map-underscore-to-camel-case: true

MyBatis In the configuration item of :

  • mapper-locations: Used to specify mapper.xml Path to file , This document is used to write SQL sentence .

  • type-aliases-package: Used to set alias , Its function is to tell MyBatis The package of the entity class whose alias needs to be set . By default ,MyBatis It will use the unqualified class name of the entity class as its alias , Such as the  com.example.entity.User  The alias of is set to  User  or  user( Aliases are not case sensitive ). Of course ,MyBatis Custom aliases are also supported , We'll talk about this later .

  • map-underscore-to-camel-case: Used to turn on Automatic Hump naming mapping , For example, the fields in the data table user_name Attributes mapped to entity objects userName.

3. Entity class

Write simple User class :

package com.example.entity;
import lombok.Data;
import java.util.Date;
/**
* @Author john
* @Date 2021/11/14
*/
@Data
public class User {
private long id;
private String userName;
private int age;
private String address;
private Date createTime;
private Date updateTime;
}

User Class encapsulates the user's id、 full name 、 Age 、 Address 、 Information such as creation time and modification time .

4. establish user surface

user The fields of the table are designed as follows :

5. To write Mapper Interface and mapper file

First write UserMapper Interface :

package com.example.mapper;
import com.example.entity.User;
/**
* @Author john
* @Date 2021/11/16
*/
public interface UserMapper {
void insertUser(User user);
User findUserById(long id);
}

Two methods are defined in the interface ,insertUser Used to insert a record into the data table ,findUserById To pass through id Inquire about User.

After the above operations are completed , We are resources Create in folder mapper/user-mapper.xml file ( The file path is in the configuration file application.yml Set in ).user-mapper.xml The contents of the document are as follows :

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<sql id="insertFields">
user_name, age, address, gmt_create, gmt_modified
</sql>
<sql id="selectFields">
id, user_name, age, address, gmt_create, gmt_modified
</sql>
<resultMap id="UserMap" type="User">
<result column="id" jdbcType="INTEGER" property="id"/>
<result column="user_name" jdbcType="VARCHAR" property="userName"/>
<result column="age" jdbcType="INTEGER" property="age"/>
<result column="address" jdbcType="VARCHAR" property="address"/>
<result column="gmt_create" jdbcType="DATE" property="createTime" />
<result column="gmt_modified" jdbcType="DATE" property="updateTime" />
</resultMap>
<select id="findUserById" parameterType="Long" resultMap="UserMap">
select
<include refid="selectFields"/>
from user
where id = #{id}
</select>
<insert id="insertUser" parameterType="User" keyProperty="id">
insert into user (<include refid="insertFields"/>)
values(#{userName}, #{age}, #{address}, UTC_TIMESTAMP(), UTC_TIMESTAMP())
</insert>
</mapper>

You can see ,Mapper What is defined in the interface is CRUD Related methods ,mapper.xml What is defined in the document is specific SQL sentence .MyBatis Allow us to Mapper Interface and mapper.xml Documents are linked together , So when calling Mapper Method in interface , The actual processing logic is to execute mapper.xml The corresponding in the file SQL sentence . relation Mapper Interface and mapper.xml Documentation needs to be guaranteed :

  • Mapper The fully qualified name of the interface corresponds to mapper.xml Of documents namespace value .

  • Mapper The method name of the interface corresponds statement( every last SQL It's just one. statement) Of id value .

  • Mapper The parameters received by the method in the interface correspond to statement Input .

  • Mapper The return value of the method in the interface corresponds to statement Out of the ginseng .

So let's talk about that mapper.xml The meaning of several important labels in the document :

  • <sql>  label : Used to define reuse SQL fragment , If more than one SQL You need to operate on the same field set , Then you can use it  <sql>  Tags extract these fields , And then in SQL Directly reference in the statement . The quoted syntax is  <include refid=" "/>, among refid The value is  <sql>  Of id value .

  • <resultMap>  label : Used to create the mapping relationship between data table fields and entity attributes , In the query operation ,MyBatis We will find... According to the field name queried POJO Corresponding attribute name , And then call the property. setter Method . If the field name of the data table is exactly the same as the attribute name of the entity class , Or conform to the rules of hump naming mapping , that MyBatis You can directly complete the assignment operation . Otherwise , We need to use  <resultMap>  Create custom mapping rules for tags , tell MyBatis How should fields and attributes be mapped . In this study ,user Tabular id Will be automatically mapped to User Object's id,user Tabular user_name It is also automatically mapped to User Object's userName. however gmt_create and gmt_modified Will not be mapped to createTime and updateTime, Because the field name and attribute name are not exactly the same , It also does not conform to the rules of hump naming mapping , So here we need to use  <resultMap>  To create a new mapping relationship , Which attribute id Used to indicate that resultMap The logo of , attribute type Used to indicate the mapped entity class .

  • <select>  label : Used to perform query operations .

  • <insert>  label : Used to perform insert operations .

actually ,MyBatis Assignment does not necessarily call the property of entity class setter Method , Because we may not have added this method when coding . With User Attributes of a class id For example , If we add setId Method , that MyBatis Will get through reflection setId Corresponding MethodInvoker, And then call setId Method is id assignment ; If not set setId Method , that MyBatis Get properties id Corresponding SetFieldInvoker, Then assign a value to the attribute . See MetaObject Class setValue Method .

Next up SQL The meaning of several important attributes in the statement :

  • parameterType: Is used to specify the SQL The input parameter type of the statement ( It can be basic data type or JavaBean), This type needs to be consistent with the input parameter type of the corresponding interface method . If we set an alias , Then you can also use aliases as parameters , For example, using  User  or  user  Instead of  com.example.entity.User.

  • resultMap: Is used to specify the SQL The argument type of the statement , With insertUser Methods as an example , stay Mapper Interface , The return value of this method is User type , So the corresponding SQL The return value of the statement should also be User type , because User Object needs to use  <resultMap>  Mapping properties , So we will customize  UserMap  As a SQL The return value type of the statement .

  • keyProperty: Used to specify the primary key in POJO Corresponding property name in , It needs to be used in conjunction with the self incrementing primary key of the database . With user Table as an example , When we create a table, we use the primary key of the table id Set to database self increment id, So I'm going to User You don't need to set a property before the object is persisted to the database id Set initial value ,MySQL Will automatically assign values for us ,keyProperty The purpose of this is to tell MyBatis Which attribute is the primary key .

except resultMap Outside ,resultType Property can also be used to specify the parameter type . If we were to user Fields in the table gmt_create and gmt_modified To be changed to create_time and update_time, Then you don't need to use  <resultMap>  Tag to configure mapping rules , because user All fields of the table can be associated with User The properties of the object correspond to each other , In this way SQL In the sentence , It can be  resultMap="UserMap"  Replace with  resulType="User"  or  resulType="user". in addition , In this experiment ,resultMap Labels can also be defined as :

<resultMap id="UserMap" type="User">
<result column="gmt_create" jdbcType="DATE" property="createTime" />
<result column="gmt_modified" jdbcType="DATE" property="updateTime" />
</resultMap>

Because other fields are automatically mapped , No additional writing is required .

6. To write Service

establish UserService:

package com.example.service;
import com.example.entity.User;
import com.example.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @Author john
* @Date 2021/11/16
*/
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public void insertUser(User user) {
userMapper.insertUser(user);
}
public User findUserById(long id) {
return userMapper.findUserById(id);
}
}

stay UserService In the injection UserMapper object , And call relevant methods to add / Inquire about User.

In order to inject normally UserMapper object , We also need to add... To the startup class @MapperScan annotation , And designate Mapper The package where the interface is located :

package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.mapper")
public class SpringbootMybatisApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisApplication.class, args);
}
}

com.example.mapper  Everything under the bag Mapper Interfaces will be Spring scanning .

In addition to adding @MapperScan Explanatory notes , You can also do it in Mapper Add... Directly to the interface @Mapper annotation , This method is relatively troublesome , Because in practice, we may have multiple Mapper Interface , This requires adding multiple annotations .

7. test

Write test interface :

package com.example;
import com.example.entity.User;
import com.example.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class SpringbootMybatisApplicationTests {
@Autowired
private UserService service;
@Test
public void addUser(){
User user = new User();
user.setUserName("John");
user.setAge(24);
user.setAddress("BUPT");
service.insertUser(user);
}
@Test
public void findUser(){
System.out.println(service.findUserById(1));
}
}

First, execute addUser() Method , Query data table after successful execution , Get the following information :

And then execute findUser() Method , The results are as follows :

thus ,SpringBoot Integrate MyBatis Test success !

MyBatis How to set aliases

Mode one : In profile application.yml Add configuration in .

yml The configuration contents of the file are as follows :

mybatis:
type-aliases-package: com.example.entity

This experiment uses this way to set the alias , By default, the alias of an entity class is its class name , Strictly speaking, it is a lowercase unqualified class name , Because aliases are not case sensitive , therefore  UseruseruSer  The effect is the same .

MyBatis Custom aliases are also supported , We just need to add... To the entity class @Alias annotation , You can set an alias for it :

package com.example.entity;
import lombok.Data;
import org.apache.ibatis.type.Alias;
import java.util.Date;
/**
* @Author john
* @Date 2021/11/14
*/
@Data
@Alias("hello")
public class User {
private long id;
private String userName;
private int age;
private String address;
private Date createTime;
private Date updateTime;
}

In the above code , We will User The alias of the class is set to  hello. Be careful , If you want to make @Alias Annotations to take effect , You have to configure  type-aliases-package  To specify the package path of the entity class . in addition ,@Alias Will invalidate the default alias , For example, in this experiment ,User The alias of a class can only be  hello, And can't be  User  or  user  etc. .

Mode two : Use MyBatis Configuration file for filename.xml.

First, in the yml Set in file MyBatis The configuration file filename.xml(filename Is the name of the configuration file ) The path of :

# To configure MyBatis
mybatis:
mapper-locations: classpath:mapper/*
config-location: classpath:mybatis/mybatis-config.xml #MyBatis The configuration file

And then in resource Create under folder MyBatis Configuration file for mapper/mybatis-config.xml( The path and file name are in config-location Set in ), The contents of the configuration file are as follows :

<?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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.example.entity"/>
</typeAliases>
</configuration>

Several important labels mean :

  • <setting>  label : Used to open hump naming mapping , Its effect is similar to that in yml Configuration in file  map-underscore-to-camel-case: true  It's the same .

  • <typeAliases>  label : Used to configure aliases , Child tags  <package>  It can make MyBatis Scan entity classes under the specified package , Its effect is similar to that in yml Configuration in file  type-aliases-package: com.example.entity  It's the same .

In mode one , We can use @Alias Annotation custom alias , And in mode two , We can go through <typeAliases>  The child tag of  <typeAlias>  To set the alias :

<?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>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<typeAlias type="com.example.entity.User" alias="hello"/>
</typeAliases>
</configuration>

<typeAlias>  Tags do not need to be configured  type-aliases-package  It will take effect , And the label is consistent with  <package>  Labels do not conflict , That is, if we add  <package name="com.example.entity"/>, that User The alias of a class can be either  hello, It can also be  User  or  user  etc. . Of course , In mode 2, you can also add @Alias annotation , But after adding this annotation ,User The alias of a class can only be  hello  or @Alias The alias specified by the annotation .

版权声明:本文为[Help me to the Internet cafe]所创,转载请带上原文链接,感谢。 https://javamana.com/2022/134/202205141436333696.html