10.spring整合mybatis
步骤:
- 导入依赖
junit/mybatis/mysql/spring/aop织入/mybatis-spring(new)
- 编写配置文件
- 测试
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.19</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!--spring 操作数据库需要spring-jdbc,并且事务包也包含进去了spring-tx-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
- 注意:MyBatis-Spring 版本区别:
MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
---|---|---|---|---|
2.0 | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
1.3 | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
10.1 使用SqlSession
- 官方文档:http://mybatis.org/spring/zh/index.html
- Spring 使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个
SqlSessionFactory
和至少一个数据映射器类。 - 在 MyBatis-Spring 中,可使用
SqlSessionFactoryBean
来创建SqlSessionFactory
。 要配置这个工厂 bean;
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--mybatis有mapper和configuration两种配置文件 后者中的所有配置都可以被Spring整合到sessionFactory中来-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zk/dao/*.xml"/>
</bean>
注意:
SqlSessionFactory
需要一个DataSource
(数据源)。这可以是任意的DataSource
,只需要和配置其它 Spring 数据库连接一样配置它就可以了。
- 数据库配置文件db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
#导入的properties文件中不要将user定为username,否者会获取系统用户名
usernames=root
password=123456
- 定义jdbc类型数据源
<!--引入 db.properties 中的配置-->
<context:property-placeholder location="classpath:db.properties"/>
<!--定义数据源 Bean
使用spring数据源替换mybatis的数据源c3p0,druid,dbcp,这里使用的是spring-jdbc提供的org.springframework.jdbc.datasource-->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="${driver}"/>
<property name="username" value="${usernames}"/>
<property name="url" value="${url}"/>
<property name="password" value="${password}"/>
</bean>
- 定义c3p0类型数据源,其他类型的数据源配置与此相同
<!--1.关联数据库配置文件-->
<context:property-placeholder location="classpath:database.properties"/>
<!--2.连接池
dpcp:半自动化操作,不能自动连接
c3p0:自动化操作(自动化的加载配置文件,并且可以自动设置到对象中)
druid:
hikari:-->
<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}"/>
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="1"/>
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false"/>
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000"/>
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2"/>
</bean>
- 在SqlSessionFactory中整合mybatis,可以完全不用配置mybatis-config.xml文件,在SqlSessionFactoryBean中都有替换的属性,但一般保留mybatis-config.xml在其中配置别名和设置(日志)信息
<!--要让Spring使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:
一个 SqlSessionFactory 和至少一个数据映射器类。-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--mybatis有mapper和configuration两种配置文件 后者中的所有配置都可以被Spring整合到sessionFactory中来-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zk/dao/*.xml"/>
</bean>
- mybatis-config.xml文件留存信息
<?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>
<!--只保留两项,setting,typeAliases-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.zk.pojo"/>
</typeAliases>
</configuration>
- 接下来就可以使用SqlSession了,可以通过以下两种方式来实现session
在 MyBatis 中,你可以使用
SqlSessionFactory
来创建SqlSession
。 一旦你获得一个 session 之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭 session。使用 MyBatis-Spring 之后,你不再需要直接使用
SqlSessionFactory
了,因为你的 bean 可以被注入一个线程安全的SqlSession
,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。
10.2 方式1:通过SqlSessionTemplate来实现通过SqlSession
SqlSessionTemplate
是 MyBatis-Spring 的核心。作为SqlSession
的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的SqlSession
。SqlSessionTemplate
是线程安全的,可以被多个 DAO 或映射器所共享使用。SqlSessionTemplate
使用的SqlSession
与当前 Spring 的事务相关。 此外,它管理 session 的生命周期,包含必要的关闭、提交或回滚操作
由于模板可以参与到 Spring 的事务管理中,并且由于其是线程安全的,可以供多个映射器类使用,你应该总是用
SqlSessionTemplate
来替换 MyBatis 默认的DefaultSqlSession
实现。在同一应用程序中的不同类之间混杂使用可能会引起数据一致性的问题。
<!--SqlSessionTemplate就是sqlSession,这个sqlSession是线程安全的,
基于Spring 的事务配置来自动提交、回滚、关闭 session。
批量创建一些 SqlSession-->
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
<!--只能用构造器,SqlSessionTemplate没有setter方法-->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
- 然后将这个 bean 就可以直接注入到你的 DAO bean 中了。你需要在你的 bean 中添加一个 SqlSession 属性,所以需要一个dao实现类来使用SqlSession,并将实现类注册bean,供业务层使用。
要用spring管理的sqlSession,不能直接从容器中getBean取dao接口的bean,所以需要实现类来封装
之前需要业务层实例sqlSession,管理sqlSession,现在只调用实现类即可,sqlSession管理交给spring去做
public class UserMapperImpl implements UserMapper{
/*
* spring整合mybatis体现在这个sqlSession实例上
* */
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> getUserList() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
return userList;
}
}
- 注册实现类,之后就可以从spring中使用这个实现类,即spring整合mybatis步骤完成
<bean class="com.zk.dao.UserMapperImpl" id="userMapper">
<property name="sqlSession" ref="sqlSession"/>
</bean>
-
完整整合步骤见下面例子:
-
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
- dao接口及mapper.xml
public interface UserMapper {
List<User> getUserList();
}
<?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">
<!--namespace绑定对应的UserMapper即实现-->
<mapper namespace="com.zk.dao.UserMapper">
<!--返回集合对象类型也是用resultType指明集合泛型-->
<select id="getUserList" resultType="user">
select * from school.user
</select>
</mapper>
- 编写数据源db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
#导入的properties文件中不要将user定为username,否者会获取系统用户名
usernames=root
password=123456
- 在spring配置文件整合mybatis,spring-mybatis-congfig.xml
- spring管理数据源
- spring管理sqlSessionFactory
- spring管理SqlSessionTemplate
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--引入 db.properties 中的配置-->
<context:property-placeholder location="classpath:db.properties"/>
<!--定义数据源 Bean
使用spring数据源替换mybatis的数据源c3p0,druid,dbcp,这里使用的是spring-jdbc提供的org.springframework.jdbc.datasource-->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
<property name="driverClassName" value="${driver}"/>
<property name="username" value="${usernames}"/>
<property name="url" value="${url}"/>
<property name="password" value="${password}"/>
</bean>
<!--要让Spring使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:
一个 SqlSessionFactory 和至少一个数据映射器类。-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!--mybatis有mapper和configuration两种配置文件 后者中的所有配置都可以被Spring整合到sessionFactory中来-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/zk/dao/*.xml"/>
</bean>
<!--SqlSessionTemplate就是sqlSession,这个sqlSession是线程安全的,
基于Spring 的事务配置来自动提交、回滚、关闭 session。
批量创建一些 SqlSession-->
<bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">
<!--只能用构造器,SqlSessionTemplate没有setter方法-->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
- 依据面向对象封装思想,引用spring管理的SqlSessionTemplate进行dao操作需要一个dao接口实现类
/**
* 面向对象:封装思想:service不要直接使用sqlSession操作数据库,
* 要调用mapper的方法,但是mapper是个接口,没有实现类,这边要给他建一个实现类来让mapper去调用
* 主要是三个mapper放在一个包里显得乱,xml该放在resources里面,然后实现类放在mapper下面的impl包里会好一点
**/
public class UserMapperImpl implements UserMapper{
/*
* spring整合mybatis体现在这个sqlSession实例上
* */
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
@Override
public List<User> getUserList() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
return userList;
}
}
- 将dao接口实现类注册到spring中,此处注意分工思想applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.zk"/>
<!--spring-mybatis-congfig整合逻辑放这个配置文件不动了-->
<import resource="classpath:spring-mybatis-congfig.xml"/>
<!--同样的还有spring-mvc配置也是这样集成进来-->
<!--本文件注入bean被调用-->
<bean class="com.zk.dao.UserMapperImpl" id="userMapper">
<property name="sqlSession" ref="sqlSession"/>
</bean>
</beans>
- 测试及结果
@Test
public void test02(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//要用spring管理的sqlSession,不能直接getBean取dao接口的bean,所以需要实现类来封装
UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
//之前需要业务层实例sqlSession,管理sqlSession,现在只调用实现类即可,sqlSession管理交给spring去做
List<User> userList = userMapper.getUserList();
userList.forEach(var-> System.out.println(var.toString()));
}
Connected to the target VM, address: '127.0.0.1:50031', transport: 'socket'
User(id=1, name=zs, pwd=123456)
User(id=2, name=mary, pwd=123456)
User(id=3, name=sandy, pwd=789456)
User(id=4, name=tony, pwd=132456)
User(id=5, name=test, pwd=111111)
User(id=6, name=tom, pwd=789456)
User(id=7, name=Jom, pwd=123456)
User(id=8, name=小明, pwd=789)
User(id=9, name=小龙, pwd=456)
User(id=10, name=小林, pwd=123)
User(id=11, name=Jom, pwd=123456)
User(id=12, name=hom, pwd=123456)
User(id=13, name=zail, pwd=987654)
Disconnected from the target VM, address: '127.0.0.1:50031', transport: 'socket'
10.3 方式二:使用SqlSessionDaoSupport
-
SqlSessionDaoSupport
是一个抽象的支持类,用来为你提供SqlSession
。调用getSqlSession()
方法你会得到一个SqlSessionTemplate
,之后可以用于执行 SQL 方法,使得整合过程更加简单。 -
修改dao实现类,会发现不用在实现类中注入SqlSession,容器也不用在配置SqlSessionTemplate类型的bean了,SqlSessionDaoSupport帮助做了SqlSessionTemplate的注入。
public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> getUserList() {
return getSqlSession().getMapper(UserMapper.class).getUserList();
}
}
- 注册这个实现类,需要注入sqlSessionFactory这个属性。
SqlSessionDaoSupport
需要通过属性设置一个sqlSessionFactory
或SqlSessionTemplate
。如果两个属性都被设置了,那么SqlSessionFactory
将被忽略。
<bean class="com.zk.dao.UserMapperImpl2" id="userMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
- 测试即结果
@Test
public void test03(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//要用spring管理的sqlSession,不能直接getBean取dao接口的bean,所以需要实现类来封装
UserMapper userMapper = context.getBean("userMapperImpl2", UserMapper.class);
//之前需要业务层实例sqlSession,管理sqlSession,现在只调用实现类即可,sqlSession管理交给spring去做
List<User> userList = userMapper.getUserList();
userList.forEach(var-> System.out.println(var.toString()));
}
JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@82ea68c] will not be managed by Spring
==> Preparing: select * from school.user
==> Parameters:
<== Columns: id, name, pwd
<== Row: 1, zs, 123456
<== Row: 2, mary, 123456
<== Row: 3, sandy, 789456
<== Row: 4, tony, 132456
<== Row: 5, test, 111111
<== Row: 6, tom, 789456
<== Row: 7, Jom, 123456
<== Row: 8, 小明, 789
<== Row: 9, 小龙, 456
<== Row: 10, 小林, 123
<== Row: 11, Jom, 123456
<== Row: 12, hom, 123456
<== Row: 13, zail, 987654
<== Total: 13
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@272ed83b]
本专栏下一篇:声明式事务
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/123907.html