Spring Boot与MyBatis集成
本节是 Spring Boot 与数据库连接使用最重要的一节,因为,在互联网发展过程中,框架技术从 SSM 框架过渡到微服务框架,其中大量的代码还是使用 SQL完成的。这个时候,就应该思考在 Spring Boot 中是否支持 SQL,使代码复用呢?答案是可以的。在开始介绍之前,普及 MyBatis 的知识,然后介绍 Spring Boot 与 MyBatis 的集成。
MyBatis原理
MyBatis 是一款优秀的持久层框架,而且越来越多的互联网企业开始使用这个框架,其优秀的特性主要体现在支持定制化的 SQL、存储过程、高级映射等。
MyBatis 和其他持久层框架一样,避免了 JDBC 代码的书写,不需要手动获取结果集。而且,MyBatis 支持 XML 与注解两种方式配置映射,可以将接口与 POJO 映射到数据库中的字段。
先看 MyBatis 的框架原理,通过图6.10可以了解到这个框架的核心。

每个 MyBatis 应用都是直接使用 SqlSession 实例操作数据,包含了数据库执行 SQL 所需的方法。SqlSession 实例是从 SqlSessionFactory 的实例中获取,而 SqlSessionFactory 可以通过 SqlSessionFactoryBuilder 获得。
MyBatis 应用通过 XML 的配置文件创建 SqlSessionFactory,SqlSessionFactory 再根据配置文件与映射文件获取 SqlSession,最后通过 SqlSession 运行映射的 SQL 语句,完成增删改查操作。
MyBatis 的优点如下。
-
简单易学:MyBatis 是轻量级框架,没有太多依赖,只需要使用配置文件就可以进行试验学习。文档丰富,结合SQL的知识,上手快速。
-
灵活:可以自由书写 SQL,不会影响程序,而且 SQL 可以自己进行优化。
-
松耦合:在使用 Dao 层时,可以将数据访问与业务逻辑分离,易维护。
Spring Boot与MyBatis集成
Spring Boot 原本不支持 MyBatis,但 MyBatis 为了整合 Spring Boot,自己提供了开发包。因此想在 Spring Boot 中使用 MyBatis,需要使用下面的依赖。
<!--Mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
在上面的程序中,我们需要自己加上版本号,因为不是 Spring Boot 官方提供的包,所以版本也会不一致,根据情况自己选择版本号即可。然后,在 application.properties 中配置 MyBatis,配置项如下所示。
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3308/test?serverTimezo ne=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
spring.datasource.hikari.auto-commit=true
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.pool-name=DatebookHikariCP
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
mybatis.mapper-locations=classpath:mapper/*.xml
上面的配置项中,重点是加粗部分,分别表示数据库连接信息与 MyBatis 配置信息。mybatis.mapper-locations 用于指定 mapper 文件的位置,使用通配符指定,mapper 的目录是 src/main/resources 下的 mapper。
在运行程序之前,需要新建数据表,下面是 MySQL 中建表的 SQL 语句。
CREATE TABLE 'user' (
'id' int(16) NOT NULL,
'username' varchar(255) DEFAULT NULL,
'password' varchar(255) DEFAULT NULL,
'email' varchar(255) DEFAULT NULL,
PRIMARY KEY ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
为了整合 MyBatis,新建了一个 package 包,与 datasource 包区分开来。程序结构如图6.11所示。

在 entity 文件夹下新建 User 类,主要对应 user 表,代码如下所示。
package com.springBoot.springbootAndMybatis.entity;
public class User {
private int id;
private String username;
private String password;
private String email;
//set and get
}
然后,写主要的功能接口,在 mapper 包下新建 UserMapper 接口,代码如下所示。
package com.springBoot.springbootAndMybatis.mapper;
@Mapper
public interface UserMapper {
//通过姓名查询user
List<User> queryUserByName(String name);
//查询所有的user
public List<User> queryAllUser();
//插入user
public int insertUser(User user);
//删除user
public int delete(int id);
//更新user
public int update(User user);
}
上面是新建接口代码,但是在接口前有一个 @Mapper 注解。在 sqlSession 对象中 GET 将会是一个实现类,后面的代码中没有手动写实现类,其实 MyBatis 通过 JDK 动态代理在加载配置文件时,根据 mapper 的 XML 生成会比较方便,节省了很多时间。这就是这个注解的作用,所以在这里可以写接口或者抽象类。
然后,为了合乎开发规范,我们再写一层 service,使得服务层与数据库访问层分离。写 service,直接使用接口中的方法即可,可以理解为使用接口的实现类中的方法,代码如下所示。
package com.springBoot.springbootAndMybatis.service;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
//通过姓名查询user
public List<User> queryUserByName(String name){
return userMapper.queryUserByName(name);
}
//查询所有的user
public List<User> queryAllUser(){
return userMapper.queryAllUser();
}
//插入user
public User insertUser(User user){
userMapper.insertUser(user);
return user;
}
//删除user
public int delete(int id){
return userMapper.delete(id);
}
//更新user
public int update(User user){
return userMapper.update(user);
}
}
签名的测试很多都是写测试类,这里换种方式。为了进行测试,我们使用 Restful 接口的方式进行测试,这里复习一下在第3章讲解过的 Restful 风格的知识。不过与之还有区别,这里的请求只是浏览器的请求,没有写测试类的请求。在 controller 包下新建 UserController 类,代码如下所示。
package com.springBoot.springbootAndMybatis.controller
@RestController
@RequestMapping(value = "/user", method = { RequestMethod.GET, RequestMethod.POST })
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/queryUserByName")
@ResponseBody
public List<User> queryUserByName(String name){
return userService.queryUserByName(name);
}
@RequestMapping("/queryAllUser")
public List<User> queryAllUser(){
return userService.queryAllUser();
}
@RequestMapping(value = "/insertUser",method = RequestMethod. POST)
public User insertUser(User user){
return userService.insertUser(user);
}
@RequestMapping(value = "/update",method = RequestMethod.POST)
public int update(User user){
return userService.update(user);
}
@RequestMapping(value = "/delete",method = RequestMethod.GET)
public int delete(int id){
return userService.delete(id);
}
}
然后,开始展示 MyBatis 的映射文件。根据 application.properties 的配置项,映射文件在 mapper 的目录下,名字可以随意写,因此 UserMapper.xml 的代码如下所示。
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.springBoot.springbootAndMybatis.mapper. UserMapper">
<resultMap id="result" type="com.springBoot.springbootAndMybatis. entity.User">
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="email" column="email"/>
</resultMap>
<select id="queryAllUser" resultMap="result">
SELECT * FROM user;
</select>
<select id="queryUserByName" resultMap="result">
SELECT * FROM user where username=#{username};
</select>
<insert id="insertUser" parameterType="com.springBoot. springbootAndMybatis.entity.User"
keyProperty="id" useGeneratedKeys="true">
INSERT INTO user(id,username,password,email)VALUES (#{id},#{username, jdbcType=VARCHAR},#{password, jdbcType=VARCHAR},#{email});
</insert>
<delete id="delete" parameterType="int">
delete from user where id=#{id};
</delete>
<update id="update" parameterType="com.springBoot. springbootAndMybatis.entity.User">
update user set user.username=#{username},user. password=#{password},user.email=#{email} where user.id=#{id};
</update>
</mapper>
最后,写一个启动类,代码如下所示。
package com.springBoot.springbootAndMybatis;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在这里需要特别注意的是,这个类需要放在刚才所有程序的父包中,如果新建一个包与 controller 包同级,并将启动类放在新建的包中,则在访问 controller 时将访问不到。所以,Application 启动类可以放在 controller 包或者其父包中。
最后,进行 Restful 测试,建议使用Postman专业工具进行测试。这里为了方便,使用谷歌浏览器。查询所有用户的结果如图6.12所示。

根据姓名查询用户如图6.13所示。

新增用户如图6.14所示。在这里需要注意的是字段key必须是user类中的属性。
