SpringBoot(三)整合MyBatis

Spring Boot 整合 MyBatis有多种方式,本文使用的是starter的方式,还可以使用注解+bean配置的方式等。此外本文使用的是xml配置SQL而不是用注解。主要是 SQL 和业务代码应该隔离,方便和 DBA 校对 SQL,此外 XML 对较长的 SQL 比较清晰。

一.数据库准备

使用mySQL数据库,创建一张book表:

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `book` (
`id` INT(6) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(100) NULL DEFAULT NULL,
`author` VARCHAR(100) NULL DEFAULT NULL,
`price` DOUBLE NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=3
;

二.代码示例

项目结构如下:

1.pom.xml文件中添加 Spring Boot 的 mybatis starter 依赖,由于要使用 mysql 数据库,还需要增加 mysql 的依赖

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>

2.增加controller、service、dao、entity等类

entity实体类(使用MyBatis逆向工程生成):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.ddcx.springboot.demodatabase.entity;

public class Book {

private Integer id;

private String name;

private String author;

private Double price;

//get、set方法省略
}

dao:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.ddcx.springboot.demodatabase.mapper;


import com.ddcx.springboot.demodatabase.entity.Book;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface BookMapper {

int insert(Book record);
List<Book> selectAll();
Book getById(@Param(value = "id") Integer id);

}

service:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.ddcx.springboot.demodatabase.service;

import com.ddcx.springboot.demodatabase.entity.Book;
import com.ddcx.springboot.demodatabase.mapper.BookMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
* Created by liaosi on 2017/9/26.
*/
@Service
public class BookService {

@Autowired
private BookMapper bookMapper;

public List<Book> getAllBooks() {
return bookMapper.selectAll();
}

public Book getById(Integer id) {
return bookMapper.getById(id);
}
}

controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.ddcx.springboot.demodatabase.controller;

import com.ddcx.springboot.demodatabase.service.BookService;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
* Created by liaosi on 2017/9/26.
*/
@RestController
public class DemoController {

private static Gson gson = new Gson();

@Autowired
private BookService bookService;


@RequestMapping("/getBook/{id}")
String bookInfo(@PathVariable("id") Integer id) {
return gson.toJson(bookService.getById(id));
}

}

3.将 MyBatis 的SQL映射的xml文件(也即是dao的实现)添加到 resource 下的 mapper 目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?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.ddcx.springboot.demodatabase.mapper.BookMapper">

<resultMap id="BaseResultMap" type="Book">
<result column="id" jdbcType="INTEGER" property="id" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="author" jdbcType="VARCHAR" property="author" />
<result column="price" jdbcType="DOUBLE" property="price" />
</resultMap>


<insert id="insert" parameterType="Book">
insert into book (id, name, author,
price)
values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{author,jdbcType=VARCHAR},
#{price,jdbcType=DOUBLE})
</insert>

<select id="selectAll" resultMap="BaseResultMap">
select id, name, author, price
from book
</select>

<select id="getById" resultMap="BaseResultMap">
select id, name, author, price
from book
WHERE id = #{id}
</select>

</mapper>

为什么要将SQL映射的xml文件的文件放在 resource 下?
因为在这个示例中使用的开发工具是IDEA,IDEA不会编译src的java目录下的xml文件,具体可参考:[IDEA不编译src的java目录下的xml文件问题及解决][2]

4.应用启动类,需要添加 @MapperScan 注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.ddcx.springboot.demodatabase;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//mapper 接口类包扫描
@MapperScan(basePackages = "com.ddcx.springboot.demodatabase.mapper")
public class ConfigApplication {

public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}

@MapperScan注解的作用类似于 MapperScannerConfigurer ,可以扫描该包下 MyBatis 的 mapper.java 接口类注册到 IOC 容器中。
如果不使用@MapperScan注解,还可以在每个 mapper 接口类上加上 @Mapper 这个注解,但是这样做比较麻烦,如果所有的mapper接口类都在一个包下,还是使用@MapperScan注解更为方便。

5.在application.properties配置文件中,增加 SpringBoot 和 MyBatis 整合的相关配置:

1
2
3
4
5
6
7
8
9
10
11
#SpringBoot整合MyBatis框架

#1.加载MyBatis配置文件
mybatis.mapper-locations=classpath:mapper/*.xml //扫描classpath下mapper目录下的所有.xml文件。如果xmlwe文件是在src的目录下,可以用**/demodatabase/dao/*.xml这种形式。
mybatis.type-aliases-package=com.ddcx.springboot.demodatabase.entity //实体类的包路径

#2.数据库配置
spring.datasource.url=jdbc:mysql://192.168.0.1:3306/java_test
spring.datasource.username=root
spring.datasource.password=********
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

mybatis.mapper-locations :用来指定sql映射的xml文件的位置。
mybatis.type-aliases-package :用来指定实体类的包路径。有了这个配置,在sql映射文件中,将数据库中的数据映射成某个类的对象时,不用设置该类的全类名了。例如本来在xml文件中需要这样配置的

如果配置了mybatis.type-aliases-package=com.ddcx.springboot.demodatabase.entity,则可以写成这样:

可以看出这个配置的作用有点类似于MyBatis配置文件中的别名处理器(typeAliases标签)中的package配置。
还有其他的一些MyBatis的配置也都可以配置到application.properties文件里,此处不再详细研究。

6.测试

启动Spring Boot应用,在postman或浏览器中访问即可。


本节示例代码已上传到github: https://github.com/liaosilzu2007/spring-boot.git

------ 本文完 ------