本章节将介绍怎样将 MyBatis 集成到 Spring Boot。
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
在 Spring Boot 项目的 pom.xml 文件中添加如下依赖:
<!-- MyBatis 依赖 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <!-- MySQL 数据库驱动依赖 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.27</version> </dependency> <!-- JSON 依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.47</version> </dependency>
本教程将采用 MySQL 作为测试数据库,在 MySQL 中创建 test 数据库,然后创建一个 user 表。表结构 SQL 语句如下:
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) DEFAULT NULL, `sex` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- 插入测试数据 INSERT INTO `user` (`id`, `name`, `sex`, `age`) VALUES (1, '张三', '男', 27); INSERT INTO `user` (`id`, `name`, `sex`, `age`) VALUES (2, '李思', '女', 25); INSERT INTO `user` (`id`, `name`, `sex`, `age`) VALUES (3, '赵六', '男', 28);
下面将介绍怎样在 Spring Boot 中,通过 MyBatis 注解和 Mapper 文件的方式集成 MyBatis。
(1)添加数据库配置信息,如:数据库URL、driverclass、用户名、密码等。如下:
# datasource spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=aaaaaa
(2)定义 user 表对应的实体 UserEntity,代码如下:
public class UserEntity { private long id; private String name; private int age; private String sex; // 忽略 getter 和 setter }
(3)定义一个 Mapper 接口 UserMapper,该接口使用 MyBatis 提供的注解定义自己的 SQL 语句和结果映射关系。代码如下:
import com.huangx.entity.UserEntity; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import java.util.List; public interface UserMapper { @Select("select id, name, age, sex from user") @Results({ @Result(property = "id", column = "id", javaType = Long.class), @Result(property = "name", column = "name", javaType = String.class), @Result(property = "sex", column = "sex", javaType = String.class), @Result(property = "age", column = "age", javaType = Integer.class) }) List<UserEntity> findAll(); }
(4)在 Spring Boot 的主类上面使用 @MapperScan 注解定义 MyBatis mapper 的位置,便于 MyBatis 扫描这些 mapper。代码如下:
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan({"com.huangx.mapper"}) public class SpringbootMybatisApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisApplication.class, args); } }
(5)客户端代码,使用 Spring 的 @SpringBootTest 注解和 JUnit 的 @RunWith 注解实现单元测试。代码如下:
import com.alibaba.fastjson.JSONObject; import com.huangx.entity.UserEntity; import com.huangx.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.List; @RunWith(SpringRunner.class) @SpringBootTest public class SpringbootMybatisApplicationTests { @Autowired private UserMapper userMapper; @Test public void findAll() { // 调用 MyBatis Mapper 接口 List<UserEntity> userEntities = userMapper.findAll(); System.out.println(JSONObject.toJSONString(userEntities)); } }
注意:@MapperScan 注解允许指定多个 mapper 基础扫描位置,例如:@MapperScan({"com.huangx.mapper", "com.huangx.mapper2"})
上面的实例介绍了怎样使用注解的方式集成 MyBatis。但是,有的时候 SQL 过于复杂、或动态 SQL,使用注解就不适合了。因此下面将介绍怎样集成 MyBatis 的 Mapper 文件,Mapper 文件更容易管理 SQL 语句。
(1)添加数据库配置信息,如:数据库URL、driverclass、用户名、密码等。如下:
# datasource spring.datasource.driverClassName=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=aaaaaa
(2)定义 user 表对应的实体 UserEntity,代码如下:
public class UserEntity { private long id; private String name; private int age; private String sex; // 忽略 getter 和 setter }
(3)定义一个 Mapper 接口 UserMapper,代码如下:
import com.huangx.entity.UserEntity; import java.util.List; public interface UserMyMapper { // SQL 语句放到 Mapper 文件中 List<UserEntity> findAll(); }
(4)在 resources/mybatis/mapper 目录下面创建 UserMapper.xml Mapper 文件,该文件内容如下:
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.huangx.mapper.UserMyMapper"> <resultMap id="userMap" type="com.huangx.entity.UserEntity"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="age" property="age" jdbcType="INTEGER"/> <result column="sex" property="sex" jdbcType="VARCHAR"/> </resultMap> <select id="findAll" resultMap="userMap"> SELECT id, name, age, sex from user </select> </mapper>
上面 Mapper 文件仅仅定义了一个查询。定义好 Mapper 文件后,需要告诉 MyBatis 到哪里去查找 Mapper 文件和配置文件。在 application.properties 或 application.yml 文件中添加如下配置:
# 定义 mybatis 配置文件的位置 mybatis.config-locations=classpath:mybatis/mybatis-config.xml # 定义 mapper 文件位置 mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
(5)在 Spring Boot 的主类上面使用 @MapperScan 注解定义 MyBatis mapper 的位置,便于 MyBatis 扫描这些 mapper。代码如下:
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan({"com.huangx.mapper"}) public class SpringbootMybatisApplication { public static void main(String[] args) { SpringApplication.run(SpringbootMybatisApplication.class, args); } }
(6)客户端代码,还是使用 Spring Boot 和 JUnit 进行单元测试,代码如下:
import com.huangx.entity.UserEntity; import com.huangx.mapper.UserMyMapper; 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 SpringbootMybatis2ApplicationTests { // 注入 Mapper @Autowired private UserMyMapper userMapper; @Test public void findAll() { List<UserEntity> userEntityList = userMapper.findAll(); for (UserEntity userEntity : userEntityList) { System.out.println(userEntity); } } }