之前我们将Spring Boot的基础以及各项配置进行了讲解,众所周知,在一个Web项目中,最重要的是与数据库进行连接,本篇就利用我们之前学过的知识,使用Spring Boot工程的方式来配置数据库的连接,并读取数据库中数据,然后升级数据库连接,进行Spring Boot与Mybatis的结合。

一、使用Spring Boot准备连接数据库的环境

打开Eclipse,创建一个Maven工程

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_Spring boot

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_spring boot整合mybatis_02


【Spring Boot学习总结】12.Spring Boot与MyBatis结合_Spring boot_03


创建成功之后,打开POM文件,添加Spring Boot的相关依赖,并指定JDK编译版本为1.7:

<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.com.springboot.database</groupId>
<artifactId>SpringBootDataConnection</artifactId>
<version>0.0.1-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>

<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

这里除了spring-boot-starter-parent父工程,还有web以及test相关依赖,为web开发和单元测试提供环境支持和自动配置。然后添加了spring-jdbc依赖、spring的事务依赖、mysql数据库连接依赖以及c3p0数据库连接池的依赖。

工程目录结构:

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_Spring boot_04


然后在src/main/resources下面创建核心配置文件application.properties:

server.port=8082
server.servlet-path=/

logging.level.org.springframework=DEBUG

在其中配置了服务启动的端口号,访问路径的匹配规则,以及日志的输出级别(这里是Debug方便我们调试)

因为需要连接数据库,所以在src/main/resources下同样需要创建一个存放数据库连接信息的资源配置文件jdbc.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_test
jdbc.username=root
jdbc.password=1234
c3p0.pool.maxPoolSize=400
c3p0.pool.minPoolSize=50
c3p0.pool.initialPoolSize=50
c3p0.pool.acquireIncrement=100

然后我们就需要编写Spring Boot的核心启动以及自动配置引入类,在src/main/java下创建一个名为“MainApplication”的类,编写如下:

package cn.com.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//Sprnig Boot项目的核心注解,主要目的是开启自动配置
public class MainApplication {
//该main方法作为项目启动的入口
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}

这里很简单,就是使用@SpringBootApplication注解开启Spring、Web以及Test测试的相关的自动配置(主要是其中的@EnableAutoConfiguration注解起到的作用),当然根据前面的学习,我们也会知道同时也会引入其他的自动配置,如果我们不需要某些配置,可以选择单独关闭那些配置(使用“exclude”参数来排除不需要的自动配置依赖,如去除Redis的配置,可以为注解添加相关exclude排除属性:@SpringBootApplication(exclude={RedisAutoConfiguration.class})),这里我们就默认使用所有的自动配置。既然要连接数据库,自然要加载数据库的核心连接类,形成数据源。此时就需要读取前面配置的数据库连接数据,进行数据库连接类、数据源的加载。此时在非Spring Boot的开发模式中,我们一般是这样配置数据源的:

<!-- 1.加载数据库配置的属性文件 -->    
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- 2.dataSource数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>

<!-- 连接池中保留的最大连接数。默认为15 -->
<property name="maxPoolSize" value="${c3p0.pool.maxPoolSize}"/>
<!-- 连接池中保留的最小连接数。默认为15 -->
<property name="minPoolSize" value="${c3p0.pool.minPoolSize}" />
<!-- 初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。默认为3 -->
<property name="initialPoolSize" value="${c3p0.pool.initialPoolSize}"/>
<!-- 定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30 -->
<property name="acquireIncrement" value="${c3p0.pool.acquireIncrement}"/>
</bean>

这种传统的XML配置,先是加载数据配置的属性文件,然后在配置数据源,将配置文件中的信息指定到相关位置。我们使用Spring Boot来配置数据源时,使用官方推荐的Java类配置的方式进行配置。在src/main/java下创建一个名为“DataSourceConfiguration”的类,用于配置数据源:

package cn.com.springboot.data;

import java.beans.PropertyVetoException;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.mchange.v2.c3p0.ComboPooledDataSource;

@Configuration
@PropertySource(value={"classpath:jdbc.properties"})
public class DataSourceConfiguration {

@Value("${jdbc.url}")
private String jdbcUrl;
@Value("${jdbc.driver}")
private String jdbcDriverClassName;
@Value("${jdbc.username}")
private String userName;
@Value("${jdbc.password}")
private String passWord;
@Value("${c3p0.pool.maxPoolSize}")
private int maxPoolSize;
@Value("${c3p0.pool.minPoolSize}")
private int minPoolSize;
@Value("${c3p0.pool.initialPoolSize}")
private int initialPoolSize;
@Value("${c3p0.pool.acquireIncrement}")
private int acquireIncrement;

@Bean(destroyMethod="close")
public DataSource dataSource() throws PropertyVetoException{
//使用c3p0数据库连接池
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//数据库驱动
comboPooledDataSource.setDriverClass(jdbcDriverClassName);
//数据库连接地址
comboPooledDataSource.setJdbcUrl(jdbcUrl);
//数据库用户名
comboPooledDataSource.setUser(userName);
//数据库密码
comboPooledDataSource.setPassword(passWord);
//连接池中保留的最大连接数。默认为15
comboPooledDataSource.setMaxPoolSize(maxPoolSize);
//连接池中保留的最小连接数。默认为15
comboPooledDataSource.setMinPoolSize(minPoolSize);
//初始化时创建的连接数,应在minPoolSize与maxPoolSize之间取值。默认为3
comboPooledDataSource.setInitialPoolSize(initialPoolSize);
//定义在从数据库获取新连接失败后重复尝试获取的次数,默认为30
comboPooledDataSource.setAcquireIncrement(acquireIncrement);
return comboPooledDataSource;
}
}

在该类中,首先使用@Configuration注解来表明这是一个配置类,这里的配置会加载到Spring容器中,然后@PropertySource注解用来加载相关的资源配置文件,这里我们加载位于类根目录的jdbc.properties文件。然后在配置类中使用@Value为各个参数绑定配置文件中的相关数据。之后创建数据源类的注入方法,返回一个配置好的数据库信息的数据源bean,添加@Bean注解,表示该方法返回的Bean对象将被加入Spring容器。

二、Spring Boot整合MyBatis

所有为MyBatis引入的工作已经完成,下面我们就开始使用Spring Boot的配置方式来完成Spring与MyBatis的整合。在传统的非Spring Boot的工程中,使用XML的配置方式如下:

<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 整合mybatis,包扫描mapper文件 -->
<property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
<!-- 别名设置 -->
<property name="typeAliasesPackage" value="cn.com.xxx.pojo"></property>
<property name="mapperLocations" value="classpath:con/com/xxx/mapper/*.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.com.xxx.mapper" />
</bean>

即是使用配置好的数据源,为mybatis与Spring整合依赖提供的SqlSessionFactoryBean配置相关数据源类和MyBatis自己的配置文件路径,以及Mapper配置文件的路径、Mapper映射接口的扫描配置。这样使用sessionFactory就可以获得与数据库交互的会话对象SqlSession,进行数据的增删改查了。

而事实上,使用Spring Boot整合MyBatis目前有两种方式:
(1)使用MyBatis官方提供的Spring Boot整合包实现,地址:https://github.com/mybatis/spring-boot-starter (2)使用传统MyBatis-Spring整合的方式

这里因为MyBatis官方提供的Spring Boot整合包后,由于相关的配置封装的比较完美,对于配置后期的拓展不方便,所以推荐使用第二种配置,这样我们可以很方便的控制MyBatis的各种配置。

所以这里我们在POM文件中添加MyBatis与Spring整合的依赖,以及MyBatis的依赖:

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>

那么下面我们在src/main/java下创建一个名为“MyBatisConfiguration”的类,用于配置MyBatis的相关配置:

package cn.com.springboot.data;

import java.io.IOException;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;

@Configuration
public class MyBatisConfiguration {

@Autowired
private DataSource dataSource;

@Bean
public SqlSessionFactory sqlSessionFactoryBean() throws Exception{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
//设置MyBatis的主配置文件
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource mybatisConfigXml = resolver.getResource("classpath:mybatis/mybatis-config.xml");
sqlSessionFactoryBean.setConfigLocation(mybatisConfigXml);
//设置别名包
sqlSessionFactoryBean.setTypeAliasesPackage("cn.com.springboot.data.pojo");
//配置mapper的扫描,找到所有的mapper.xml映射文件
Resource[] resources = resolver.getResources("classpath:mapper/*.xml");
sqlSessionFactoryBean.setMapperLocations(resources);
return sqlSessionFactoryBean.getObject();
}
}

这里首先使用@Configuration注解来表明这是一个配置类,然后从Spring容器中注入DataSource,并创建sqlSessionFactoryBean的bean声明方法,为sqlSessionFactoryBean注入数据源对象。可以发现,其实和上面的XML配置模式是一样的,但是这种配置更符合Java的风格,使开发者更好理解各个依赖配置类之间的关系。
然后配置mybatis自己的配置文件,在src/main/resources下创建mybatis文件夹,在其中放置mybatis-config.xml文件,内容为mybatis的配置:

<?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>

</configuration>

因为这里我们将Mybatis整合进了spring,相关的设置在spring中已经配置,这里可以配置一些mybatis的特殊设置。前面的xml配置时,使用MapperScannerConfigurer来指定mapper接口文件的扫描位置,这里我们可以配置mapper接口的扫描类“MapperScannerConfiguration”:

package cn.com.springboot.data;

import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@AutoConfigureAfter(MyBatisConfiguration.class)//保证在MyBatisConfiguration实例化之后再实例化该类
public class MapperScannerConfiguration {
//mapper接口的扫描器
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("cn.com.springboot.mapper");
return mapperScannerConfigurer;
}
}

此时有关MyBtais的相关配置已经完成,我们来进行测试。在连接的测试数据库中有一个user表,我们下面使用它来测试:

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_@Configuration_05

首先在src/main/resources下创建mapper文件夹,在其中创建一个针对user表的数据库配置文件UserMapper.xml:

<?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="cn.com.springboot.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="cn.com.springboot.pojo.User">
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>

然后创建相关的User的JavaBean以及Mapper映射

package cn.com.springboot.pojo;

import java.io.Serializable;
import java.util.Date;

public class User implements Serializable{
private int id;
private String username;
private String password;
private String gender;
private String email;
private String province;
private String city;
private Date birthday;
//此处省略Get与Set方法...
}

UserMapper :

package cn.com.springboot.mapper;

import cn.com.springboot.pojo.User;

public interface UserMapper {
User findUserById(int id);
}

然后创建相关Service接口:

package cn.com.springboot.service;

import cn.com.springboot.pojo.User;

public interface UserService {
User findUserById(int id);
}

实现类

package cn.com.springboot.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.springboot.mapper.UserMapper;
import cn.com.springboot.pojo.User;
import cn.com.springboot.service.UserService;

@Service("userService")
public class UserServiceImpl implements UserService{

@Autowired
private UserMapper userMapper;

@Override
public User findUserById(int id) {
return userMapper.findUserById(id);
}
}

然后我们创建一个RESTful请求处理的Controller类:

package cn.com.springboot.controller;

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;

import cn.com.springboot.pojo.User;
import cn.com.springboot.service.UserService;

@RestController
//该注解等价于@Controller+@ResponseBody的结合,使用这个注解的类里面的方法都以json格式输出。
public class UserController {

@Autowired
private UserService userService;

@RequestMapping("/user/{id}")
public String findById(@PathVariable Integer id) {
User user = userService.findUserById(id);
if(user!=null){
return "你好,用户:" + user.getUsername();
}else{
return "用户信息不存在!";
}
}
}

在其中调用了userService,通过id取得用户数据。

工程的最终结构:

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_Spring boot_06

在MainApplication类上启动该工程,在浏览器中访问用户信息查询服务:

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_spring boot整合mybatis_07

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_@AutoConfigureAfter_08

【Spring Boot学习总结】12.Spring Boot与MyBatis结合_Spring boot_09


可以看到数据获取成功,说明我们的数据库连接以及MyBatis环境配置成功!

下一篇我们将讲解如何在Spring Boot中配置事务的处理。

参考:
传智播客《Spring Boot实战与原理分析》视频课程
(​​​https://pan.baidu.com/s/1o9M2bGI​​ 密码:jxg8)