share-image
ESC

整合Spring和Mybatis

在实际的开发过程中,我们经常需要使用Spring 和Mybatis,那么如何去整合Spring 与Mybatis 呢?本文我们一起来通过详细的案例的方式进行讲解

准备工作

首先,还是介绍下环境

  • idea
  • mysql
  • maven

我们先使用idea 创建一个maven工程,工程名称叫com.ssm,然后在pom.xml中加入以下jar包,可以看到所需要的jar包还是很多的

<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-launcher</artifactId>
<version>1.9.6</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>5.1</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.27.0-GA</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>

然后我们编写配置文件,在mian-java 这个目录上点击右键创建一个文件夹,然后选择resource,然后在resource 下创建db.properties 文件,内容如下

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.10.128:3306/mybatis_db
jdbc.username=root
jdbc.password=123456
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5

其对应的数据库创建方式以及数据插入如下

mysql> create database mybatis_db;
Query OK, 1 row affected (0.01 sec)

mysql> use mybatis_db;
Database changed
mysql> create table t_user(
-> id int(32) primary key auto_increment,
-> username varchar(50),
-> jobs varchar(50),
-> phone varchar(16));
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> insert into t_user values(1,"zhangsan","teacher","13142767333");
Query OK, 1 row affected (0.01 sec)

mysql> insert into t_user values(2,"lisi","engineer","13142767334");
Query OK, 1 row affected (0.01 sec)

mysql> insert into t_user values(3,"wangwu","pilot","12342767334");
Query OK, 1 row affected (0.00 sec)

mysql>

然后还是在resource 目录下创建一个applicationContext.xml文件,内容如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--读取db.properties-->
<context:property-placeholder location="classpath:db.properties"/>
<!--配置数据源 -->
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<!--数据库驱动 -->
<property name="driverClassName" value="${jdbc.driver}" />
<!--连接数据库的ur1 -->
<property name="url" value="${jdbc.url}" />
<!--连接数据库的用户名 -->
<property name="username" value="${jdbc.username}" />
<!--连接数据库的密码-->
<property name="password" value="${jdbc.password}" />
<!--最大连接数-->
<property name="maxTotal" value="${jdbc.maxTotal}" />
<!--最大空闲连接-->
<property name="maxIdle" value="${jdbc.maxIdle}" />
<!--初始化连接数-->
<property name="initialSize" value="${jdbc.initialSize}" />
</bean>
<!--事务管理器,依赖于数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--注册事务管理器驱动,开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--配置MyBatis工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源 -->
<property name="dataSource" ref="dataSource" />
<!--指定核心配置文件位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
</beans>

这个配置文件中主要是定义了数据库的驱动以及连接池、事务管理器等,在最后配置了Mybatis 的工厂,制定其核心配置文件为mybatis-config.xml,并且使用typeAliases 创建一个别名,关于别名,你可以参考官网文档 https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases

<?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>
<!--配置别名 -->
<typeAliases>
<package name="com.ssm"/>
</typeAliases>
</configuration>

然后我们开始整合,我们先看下使用传统的DAO 方式如何整合,采用传统DAO 方式整合,我们需要编写DAO 接口以及实现类,并且需要向DAO实现类注入SqlSessionFactory,然后通过方法体通过SqlSessionFactory 创建SqlSession。具体怎么做呢?

首先,我们创建一个User.java 的用户类,并生成get和set方法以及tostring方法

package com.ssm;

public class User {
private Integer id;
private String username;
private String jobs;
private String phone;

public Integer getId() {
return id;
}

public String getUsername() {
return username;
}

public String getJobs() {
return jobs;
}

public String getPhone() {
return phone;
}

public void setId(Integer id) {
this.id = id;
}

public void setUsername(String username) {
this.username = username;
}

public void setJobs(String jobs) {
this.jobs = jobs;
}

public void setPhone(String phone) {
this.phone = phone;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", jobs='" + jobs + '\'' +
", phone='" + phone + '\'' +
'}';
}


}

然后我们创建一个UserMappler.xml,编写一个根据用户id查询用户的select 语句

<?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="UserMapper">
<!--根据用户编号获取用户信息 -->
<select id="findUserById" parameterType="Integer" resultType="User">
select * from t_user where id=#{id}
</select>
</mapper>

接着我们在Mybatis-config.xml中创建一个映射文件

<mappers>
<mapper resource="UserMapper.xml" />
</mappers>

接着我们创建一个UserDao.java,我们创建一个findUserById 的接口

package com.ssm;

public interface UserDao {
public User findUserById(Integer id);
}

我们需要在applicationContext.xml 中定义一个bean,其id 为userDao,并指向clas路径,同时定义一个property,引用sqlSessionFactory,
其表示将sqlSessionFactory对象注入该bean 的实例化对象中

<bean id="userDao" class="com.ssm.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>

然后我们需要实现UserDao,我们创建一个UserDaoImpl.java文件,内如下

package com.ssm;

import com.ssm.User;
import com.ssm.UserDao;
import org.mybatis.spring.support.SqlSessionDaoSupport;

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
@Override
public User findUserByID(Integer id) {
return this.getSqlSession().selectOne("findUserById",id);
}
}

接着,我们创建一个测试类

package com.ssm;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DaoTest {
@Test
public void findUserByIdTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
User user = userDao.findUserByID(1);
System.out.println(user);
}
}

执行结果如下

20200412120832

以上是使用传统Dao方式来进行整合,但是我们会发现采用这种方法实现整合会出现大量冗余代码,为此,我们可以使用Mybatis 提供的Mapper 接口进行实现

MapperFactoryBean 是Mybatis-Spring 提供的一个用于根据Mapper 接口生成Mapper 对象的类,这个类在Spring 配置时候可以配置一下参数

  • mapperInterface 用于指定接口
  • SqlSessionFactory 用户指定 SqlSessionFactory
  • SqlSessionTemplate 用户指定 SqlSessionTemplate,如果与SqlSessionFactory同时设定,则只会启用SqlSessionTemplate

了解了基本的配置后,我们就开始使用Mapper 接口的方式进行整合了

首先,我们创建一个UserMapper.java,内容如下

package com.ssm;

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

同时,创建一个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="com.ssm.UserMapper">
<!--根据用户编号获取用户信息 -->
<select id="findUserById" parameterType="Integer" resultType="User">
select * from t_user where id=#{id}
</select>
</mapper>

仔细看你会发现和传统Dao 方式中我们定义接口其实一模一样,不过,接下来可就不一样了,我们需要在spring的配置文件中创建一个id为userMapper 的bean,代码如下

<!--     Mapper代理开发(基于MapperFactoryBean)-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.ssm.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

这段配置是用来定义Mapper代理开发,也就是基于MapperFactoryBean的配置,然后我们在测试类中进行测试,你会发现我们并没有写UserMapper 的实现类UserMapperImpl,这是与传统DAO方式的区别

@Test
public void findUserByIdMapperTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
User user = userMapper.findUserById(1);
System.out.println(user);

}

执行代码

20200412122058

接下里我们看下给予MapperScannerConfigUre 的整合,在实际的开发过程中,Dao 层会包含很多的接口,如果我们每一个接口都要在Spring中配置对应的Bean,那么这个工作量是相当大的,因此mybatis-spring提供了一种自动扫描的兴衰来配置mybatis中的映射器,即可采用MapperScannerConfigure 类
只需要在spring配置文件中定义如下配置即可,我们将spring配置文件中的传统Dao 和基于MapperFactoryBean 的bean 注释掉,增加如下配置

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.ssm" />
</bean>

其中

  • basePackage 是指定映射接口文件所在的包路径,如果你需要扫描多个包,需要加分号或逗号作为分隔符,它会扫描包内的所有文件

然后我们再次执行对应的测试类,发现一样的效果。你会发现通过这样整合,这种是不是特别简单呢?

文章作者:阿文
文章链接: https://www.awen.me/post/4442599114.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 阿文的博客
本文于 2020-04-16 发布,已超过半年(2114天),请注意甄别内容是否已过期。