MyBatis快速入門(四) MyBatis和Spring整合
匯入依賴包
前面介紹了MyBatis的相關知識,現在來介紹一下如何和Spring進行整合。MyBatis和Spring的整合工作是由MyBatis團隊完成的。所以我們首先要先引入MyBatis和Spring的整合依賴包。這裡我用的是Gradle,如果使用其他構建工具,將下面的語句改為相應的。
compile group: 'org.mybatis', name: 'mybatis-spring', version: '1.3.1'
宣告Spring Bean
整合包中包含了org.mybatis.spring.SqlSessionFactoryBean
類,這是一個工廠類,可以方便的建立MyBatis的SqlSessionFactory
configLocation
屬性為MyBatis配置檔案。
<!--MyBatis的SqlSessionFactory-->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value ="configuration.xml"/>
</bean>
<!--資料來源-->
<bean id="dataSource"
class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<property name="user" value="root"/>
<property name="password" value="12345678"/>
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="useSSL" value="false"/>
</bean>
事務管理
MyBatis是一個輕量級的框架,沒有自己的事務管理器。我們直接使用JDBC事務管理器即可。其它地方和別的事務配置方法差不多,就不詳細介紹了。
<!--MyBatis使用JDBC的事務管理器-->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:advice id="txAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--使用AOP設定事務管理-->
<aop:config>
<aop:pointcut id="dao"
expression="execution(* yitian.study.dao.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="dao"/>
</aop:config>
使用SqlSession
MyBatis還提供了一個MyBatisTemplate
類,會將SqlSession
交由Spring管理。我們只要宣告該物件,並注入到程式碼中使用即可。
<!--MyBatis的SqlSession模板,封裝了SqlSession-->
<bean id="sqlSessionTemplate"
class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg type="org.apache.ibatis.session.SqlSessionFactory"
ref="sqlSessionFactory"/>
</bean>
或者還可以繼承SqlSessionDaoSupport
類,它提供了getSqlSession()
方法,可以直接獲取當前由Spring管理的SqlSession。
注入對映器
MyBatis的對映器可以通過MapperFactoryBean
工廠類來註冊。註冊之後,我們就可以直接注入到DAO中使用,連MyBatisTemplate
都免了。
<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>
如果有多個對映器的話,我們甚至可以利用MyBatis提供的名稱空間直接掃描所有對映器。
<!--自動搜尋Mapper-->
<mybatis:scan base-package="yitian.study.mapper"/>
然後我們的程式碼就變得非常乾淨。
@Repository
public class AuthorDaoImpl implements AuthorDao {
private SqlSessionTemplate template;
private MultiMapper mapper;
@Autowired
public AuthorDaoImpl(SqlSessionTemplate template, MultiMapper mapper) {
this.template = template;//模板物件甚至都沒使用
this.mapper = mapper;
}
@Override
public void add(Author author) {
mapper.insertAuthor(author);
}
@Override
public Author getById(int id) {
return mapper.selectAuthorById(id);
}
@Override
public Author getByName(String username) {
return mapper.selectAuthorByName(username);
}
@Override
public void update(Author author) {
mapper.updateAuthor(author);
}
@Override
public void delete(Author author) {
mapper.deleteAuthor(author);
}
}
封裝異常
Spring可以將Hibernate、JPA等不同技術的異常,統一封裝為Spring自己的異常層次。這樣我們就能在Spring程式中統一處理異常了。
首先我們的DAO類需要@Repository註解。
@Repository
public class AuthorDaoImpl implements AuthorDao {
private SqlSessionTemplate template;
private MultiMapper mapper;
@Autowired
public AuthorDaoImpl(SqlSessionTemplate template, MultiMapper mapper) {
this.template = template;
this.mapper = mapper;
}
//其他程式碼省略了
}
然後我們需要宣告下面兩個Spring Bean。
<!--異常攔截器,用於將MyBatis封裝為Spring異常-->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.mybatis.spring.MyBatisExceptionTranslator">
<constructor-arg type="javax.sql.DataSource" ref="dataSource"/>
<constructor-arg type="boolean" value="false"/>
</bean>
這樣程式碼中丟擲的JDBC異常都會被翻譯成Spring的異常。由於Spring中包含了對常見JDBC異常的封裝,所以即使沒有上面的宣告,我們得到的異常也是Spring的DataAccessException。一開始我以為Spring沒有進行異常轉換,後來我發現原來由於Spring貼心的列印了原異常,把我搞暈了。如果捕獲異常然後檢視一下異常型別,就會發現已經是Spring的異常了。