本章节将介绍怎样将 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);
        }
    }
}
            