13. Spring整合Mybatis
1.导入相关依赖
-
junit
-
mybatis
-
mysql数据库
-
spring相关依赖
-
aop依赖
-
mybatis-spring
<dependencies> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency><!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <!--spring配置数据库需要 spring-jdbc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.7.M2</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.6</version> </dependency> </dependencies>
2.Mybatis-Spring
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession
并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException
。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 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+ |
官网: http://mybatis.org/spring/zh/factorybean.html
使用spring的数据池来代替mybatis的datasource
<!--mybatis数据池-->
<configuration>
<environments default="development"> <!--环境标签-->
<environment id="development"> <!--环境id-->
<transactionManager type="JDBC"> <!--事物处理器-->
<property name="..." value="..."/>
</transactionManager>
<dataSource type="POOLED"> <!--数据源-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>
<!--spring的bean配置spring datasource-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"></property>
<property name="username" value="root"></property>
<property name="password" value="180018ly"></property>
</bean>
使用spring的bean来配置SqlSessionFacotory
设置
要创建工厂 bean,将下面的代码放到 Spring 的 XML 配置文件中:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
等效的 Java 代码如下:
@Configuration
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory() {
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource());
return factoryBean.getObject(); //返回SqlSessionFactory
}
}
属性
-
SqlSessionFactory
有一个==唯一的必要属性:用于 JDBC 的DataSource
。==这可以是任意的DataSource
对象,它的配置方法和其它 Spring 数据库连接是一样的。 -
一个常用的属性是
configLocation
,它用来指定 MyBatis 的 XML 配置文件路径。它在需要修改 MyBatis 的基础配置非常有用。==通常,基础配置指的是<settings>
或<typeAliases>
元素。==需要注意的是,这个配置文件并不需要是一个完整的 MyBatis 配置。确切地说,任何环境配置(<environments>
),数据源(<DataSource>
)和 MyBatis 的事务管理器(<transactionManager>
)都会被忽略。SqlSessionFactoryBean
会创建它自有的 MyBatis 环境配置(Environment
),并按要求设置自定义环境的值。 -
如果 MyBatis 在映射器类对应的路径下找不到与之相对应的映射器 XML 文件,那么也需要配置文件。这时有两种解决办法:第一种是手动在 MyBatis 的 XML 配置文件中的
<mappers>
部分中指定 XML 文件的类路径;第二种是设置工厂 bean 的mapperLocations
属性。mapperLocations
属性接受多个资源位置。这个属性可以用来指定 MyBatis 的映射器 XML 配置文件的位置。属性的值是一个 Ant 风格的字符串,可以指定加载一个目录中的所有文件,或者从一个目录开始递归搜索所有目录。比如:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
</bean>
这会从类路径下加载所有在 sample.config.mappers
包和它的子包中的 MyBatis 映射器 XML 配置文件。在容器管理事务的时候,你可能需要的一个属性是 transactionFactoryClass
。
如果你使用了多个数据库,那么需要设置 databaseIdProvider
属性:
<bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider">
<property name="properties">
<props>
<prop key="SQL Server">sqlserver</prop>
<prop key="DB2">db2</prop>
<prop key="Oracle">oracle</prop>
<prop key="MySQL">mysql</prop>
</props>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
<property name="databaseIdProvider" ref="databaseIdProvider"/>
</bean>
提示 自 1.3.0 版本开始,新增的 configuration
属性能够在没有对应的 MyBatis XML 配置文件的情况下,直接设置 Configuration
实例。例如:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> <!--数据源-->
<property name="configuration"> <!--configuration属性-->
<bean class="org.apache.ibatis.session.Configuration">
<property name="mapUnderscoreToCamelCase" value="true"/> <!--开启数据库对应驼峰命名-->
</bean>
</property>
</bean>
使用spring对SqlSessionFactory进行配置 代码实例
spring.xml
<?xml version="1.0" encoding="UTF8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--DataSource 使用spring的数据源替换mybatis数据源-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"></property>
<property name="username" value="root"></property>
<property name="password" value="180018ly"></property>
</bean>
<!--sqlSessionFactory 以bean的形式导入-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"></property> <!--必填属性-->
<!--导入mybatis配置文件 推荐在mybatis配置文件中只存放setting(设置)与typeAlias(别名)元素(官方推荐) classpath:路径=-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--配置mapper映射 mapperLocations-->
<property name="mapperLocations" value="classpath:com/liu/mapper/*.xml"></property>
</bean>
</beans>
mybatis-config.xml
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--只剩下了 settings和typeAliases-->
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/> <!--标准日志工厂-->
</settings>
<typeAliases>
<package name="com.liu.pojo"/>
</typeAliases>
</configuration>
spring-mybatis创建sqlsession
在 MyBatis 中,你可以使用 SqlSessionFactory
来创建 SqlSession
。 一旦你获得一个 session 之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭 session。 使用 MyBatis-Spring 之后,你不再需要直接使用 SqlSessionFactory
了,因为你的 bean 可以被注入一个线程安全的 SqlSession
,它能基于 Spring 的事务配置来自动提交、回滚、关闭 session。
SqlSessionTemplate
SqlSessionTemplate
是 MyBatis-Spring 的核心。作为 SqlSession
的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的 SqlSession
。 SqlSessionTemplate
是线程安全的,可以被多个 DAO 或映射器所共享使用。(mybatis中是线程不安全的)。
SqlSessionTemplate的使用方式和SqlSession完全相同
代码实例
首先配置spring.xml
<?xml version="1.0" encoding="UTF8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--DataSource 使用spring的数据源替换mybatis数据源-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"></property>
<property name="username" value="root"></property>
<property name="password" value="180018ly"></property>
</bean>
<!--sqlSessionFactory纳入spirng的管理-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"></property>
<!--导入mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--配置mapper映射 mapperLocations-->
<property name="mapperLocations" value="classpath:com/liu/mapper/*.xml"></property>
</bean>
<!--配置SqlSessionTemplate-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--sqlSessionTemplate只有有参构造,需要一个SqlSessionFactory使用构造器注入sqlSessionFactory-->
<constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!--UserMapperImpl实现类纳入spring管理-->
<bean id="userMapper" class="com.liu.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"></property>
</bean>
</beans>
构建UserMapperImpl实现类
//直接在UserMapperImpl里实现所有的结果,给主类发挥的是直接的结果
public class UserMapperImpl {
//所有操作都是用sqlSessionTemplate执行(操作方式与SqlSession相同)
private SqlSessionTemplate sqlSession ;
//setSqlSession , 为了spring中的sqlSession注入
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> getUserList() {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
return userMapper.getUserList();
}
}
在总的配置文件applicationContext.xml中整合spring与mybatis
<!--是一个spirng配置文件-->
<?xml version="1.0" encoding="UTF8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--导入mybatis配置-->
<import resource="spring-config.xml"></import>
</beans>
主类(测试类)
public class Test {
@org.junit.Test
public void test() {
/*导入Spring*/
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//通过context.getBean()得到UserMapperImpl(id=userMapper纳入了spring管理)
UserMapper userMapper = context.getBean("userMapper",UserMapper.class);
//直接执行即可
List<User> userList = userMapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
}
}
相比于myabtis , spirng-mybaits整合的不同点
-
SqlSessionFactory和SqlSession的实现方式改变了。 在Mybatis中,SqlSessionFactory和SqlSession通过Java代码实现 。 整合之后全部纳入了spring管理 , 基本避开了Java代码
-
SqlSession与SqlSessionTemplate
在Mybatis中使用 SqlSession ,线程不安全。 一般放在工具类里面作为一个函数 ,用完即close()
然而SqlSessionTemplate 作用与 SqlSession完全相同 , 同时线程安全
-
SqlSession的使用位置
在单Mybatis项目当中 , SqlSession在主类中使用 ,例如
public User getUserById(int id) { SqlSession sqlSession = MybatisUtil.getSqlSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.getUserById(id); sqlSession.close(); return user; }
而在spring+Mybatis整合项目中 ,新加了一个实现类 , SqlSessionTemplate在实现类中使用 ,主类直接调用结果
public class UserMapperImpl implements UserMapper{ //所有操作都是用sqlSessionTemplate执行 private SqlSessionTemplate sqlSession ; //setSqlSession public void setSqlSession(SqlSessionTemplate sqlSession) { this.sqlSession = sqlSession; } @Override public List<User> getUserList() { UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //使用了SqlSessionTemplate return userMapper.getUserList(); } }
-
项目结构的变化
spring+mybatis多了一个 dao的Impl实现类
-
整合项目可以不需要mybaits配置文件 , spring配置可以完成所有的mybatis配置
Impl实现类的简化
SqlSessionDaoSupport
SqlSessionDaoSupport
是一个抽象的支持类,用来为你提供 SqlSession
。调用 getSqlSession()
方法你会得到一个 SqlSessionTemplate
,之后可以用于执行 SQL 方法,就像下面这样:
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
//所有操作都是用sqlSessionTemplate执行
/*
private SqlSessionTemplate sqlSession ;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}*/ //SqlSession由父类提供,这段代码直接可以省略
@Override
public List<User> getUserList() {
return getSqlSession().getMapper(UserMapper.class).getUserList() ; //直接简化为了一行代码
}
}
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
@Override
public List<User> getUserList() {
return getSqlSession().getMapper(UserMapper.class).getUserList() ;
}
}
<!--配置文件的简化-->
<?xml version="1.0" encoding="UTF8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--DataSource 使用spring的数据源替换mybatis数据源-->
<bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false"></property>
<property name="username" value="root"></property>
<property name="password" value="180018ly"></property>
</bean>
<!--sqlSessionFactory纳入spirng的管理-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"></property>
<!--导入mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--配置mapper映射 mapperLocations-->
<property name="mapperLocations" value="classpath:com/liu/mapper/*.xml"></property>
</bean>
<!--配置文件改变 Impl纳入spring管理-->
<bean id="userMapper" class="com.liu.mapper.UserMapperImpl">
<!--父类需要一个SqlSessionFactory 只需要impl注入即可-->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
显然 ,采用这种方式 , spring.xml 配置文件 不再需要注入SqlSessionTemplate , 只需要注册Impl实现类即可