MyBatis, MyBatis-Spring 常用訪問資料庫的方式
一、MyBatis 訪問資料庫的方式
使用 MyBatis 的主要 Java 介面就是 SqlSession,可通過 SqlSessionFactoryBuilder 建立 SqlSession。
二、MyBatis-Spring 訪問資料庫的方式
先放出結論,MyBatis-Spring 訪問資料庫的方式主要有三種:
- SqlSessionTemplate
- MapperFactoryBean
- MapperScannerConfigurer
1、SqlSessionTemplate 簡介:
SqlSessionTemplate 是 MyBatis-Spring 的核心,這個類負責管理 MyBatis 的 SqlSession。
SqlSessionTemplate 實現了 SqlSession 介面,這就是說,在程式碼中無需對 MyBatis 的 SqlSession 進行替換。 SqlSessionTemplate 通常是被用來替代預設的 MyBatis 實現的 DefaultSqlSession 。
2、SqlSessionDaoSupport 簡介:
SqlSessionDaoSupport 是 一 個抽象的支援類, 用來為你提供 SqlSession 。 呼叫 getSqlSession() 方法你會得到一個 SqlSessionTemplate,之後可以用於執行 SQL 方法, 就像下面這樣:
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
public User getUser(String userId) {
return (User) getSqlSession().selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
}
}
3、MapperFactoryBean 簡介:
為了代替手工使用 SqlSessionDaoSupport 或 SqlSessionTemplate 編寫資料訪問物件 (DAO)的程式碼, MyBatis-Spring 提供了一個動態代理的實現: MapperFactoryBean
如:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
即 MapperFactoryBean 建立的代理類實現了 UserMapper 介面,並且注入到應用程式中。 因為代理建立在執行時環境中(Runtime,譯者注) ,那麼指定的對映器必須是一個介面,而 不是一個具體的實現類。
如果 xml 對映器檔案在類路徑的 位置和對映器類相同時, 它會被 MapperFactoryBean 自動解析,否則需要配置 configLocation 路徑來指定 mybatisConfig.xml 檔案(該檔案中有配置 xml 對映器檔案路徑)。
4、MapperScannerConfigurer 簡介:
此種方式即通過 MapperScannerConfigurer 查詢類路徑下的對映器並自動將它們建立成 MapperFactoryBean。與 MapperFactoryBean 相比,不用在 spring.xml 檔案中定義所有的 dao 類的對應的 bean 宣告。
三種實現方式如下:
0、spring 公共模組的配置: dataSource 和 sqlSessionFactory:
<bean id="mysqlTestDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.c3p0.driverClass}"/>
<property name="url" value="${mysql.test.jdbc.c3p0.jdbcUrl}"/>
<property name="username" value="${mysql.test.jdbc.c3p0.user}"/>
<property name="password" value="${mysql.test.jdbc.c3p0.password}"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="mysqlTestDataSource" />
<property name="configLocation" value="classpath:context/mybatis/mapperConfig.xml" />
<!--<property name="mapperLocations" value="classpath*:mappers/mysql_test/*Mapper.xml" />-->
</bean>
注:sqlSessionFactory 裡配置xml對映檔案的兩種方式:
1、configLocation:配置 mybatisConfig.xml 檔案的路徑,在該檔案內配置xml 對映檔案的路徑即可;
2、mapperLocations:配置所有 xml 對映檔案路徑。
方式1、使用 SqlSessionTemplate 方式:
spring.xml 配置:
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
mapperConfig.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>
<mappers>
<mapper resource="mappers/mysql_test/AwardMapper.xml" />
</mappers>
</configuration>
AwardMapper.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="AwardDao" >
<insert id="insert" parameterType="com.wlm.test.award.Award">
insert into award (award, count, created_time, updated_time)
values (#{award}, #{count}, #{createdTime}, #{updatedTime})
</insert>
</mapper>
注:當使用 SqlSessionTemplate 方式時,namespace 可任意。
AwardDao 介面:
public interface AwardDao {
public void insert(Award award);
}
AwardDaoImpl 實現類:
@Repository
public class AwardDaoImpl implements AwardDao {
@Resource(name = "sqlSessionTemplate")
private SqlSession sqlSession;
@Override
public void insert(Award award) {
sqlSession.insert("AwardDao.insert", award);
}
}
執行測試程式碼:
@Test
public void awardTest() {
Award award = new Award();
award.setAward(2);
awardMapper.insert(award);
}
執行結果:
方式2、MapperFactoryBean 方式:
spring.xml 配置:
<bean id="awardDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.wlm.test.award.AwardDao" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
AwardMapper.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.wlm.test.award.AwardDao" >
<insert id="insert" parameterType="com.wlm.test.award.Award">
insert into award (award, count, created_time, updated_time)
values (#{award}, #{count}, #{createdTime}, #{updatedTime})
</insert>
</mapper>
注:此處 namespace 和 SqlSessionTemplate 方式不同。與 介面 關聯時(即通過MyBatis-Spring的動態代理實現), MyBatis 通過介面的完整名稱(包名+類名)查詢對應的 mapper 配置,保證唯一性。
測試程式碼為:
@Test
public void awardTest() {
Award award = new Award();
award.setAward(3);
awardDao.insert(award);
}
執行結果如下:
方式3、MapperScannerConfigurer 方式:
spring.xml 檔案:
<!-- 只有一個 dataSource 時, 自動裝配, 多個 dataSource 時, 通過 sqlSessionFactoryBeanName 指定 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.wlm.test.award" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
注: 此處 AwardMapper.xml 對映檔案和上方 MapperFactoryBean 方式相同。
三、如何配置多套資料庫環境
使用 MyBatis-Spring 時,配置多個 dataSource 資料來源,且使用 SqlSessionTemplate 的方式實現資料庫訪問。
在實現類中,注入不同的 SqlSesion 即可。
即:
<bean id="sqlSessionTemplate1" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory1" />
</bean>
<bean id="sqlSessionTemplate2" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory2" />
</bean>
@Repository
public class AwardDaoImpl implements AwardDao {
@Resource(name = "sqlSessionTemplate1")
private SqlSession sqlSession1;
@Resource(name = "sqlSessionTemplate2")
private SqlSession sqlSession2;
@Override
public void insert(Award award) {
sqlSession1.insert("AwardDao.insert", award);
sqlSession2.insert("AwardDao.insert", award);
}
}