使用Spring IoC能夠有效管理各種Java資源,達到即插即拔功能;經過AOP框架,數據庫事務能夠委託給Spring處理,消除很大一部分的事務代碼,配合MyBatis的高靈活、可配置、可優化SQL等特性,徹底能夠構建高性能的大型網站。
MyBatis和Spring兩大框架已經成了Java互聯網技術主流框架組合,它們經受住了大數據量和大批量請求的考驗,在互聯網系統中獲得了普遍的應用。使用MyBatis-Spring使得業務層和模型層獲得了更好的分離,與此同時,在Spring環境中使用MyBatis也更加簡單,節省了很多代碼,甚至能夠不用SqlSessionFactory、SqlSession等對象。由於MyBatis-Spring爲咱們封裝了它們。java
配置MyBatis-Spring項目須要這麼幾步:
•配置數據源。
•配置SqlSessionFactory。
•能夠選擇的配置有SqlSessionTemplate,在同時配置SqlSessionTemplate和SqlSessionFactory的狀況下,優先採用SqlSessionTemplate。
•配置Mapper,能夠配置單個Mapper,也能夠經過掃描的方法生成Mapper,比較靈活。此時Spring IoC會生成對應接口的實例,這樣就能夠經過注入的方式來獲取資源了。spring
從MyBatis的介紹中,能夠知道SqlSessionFactory是產生SqlSession的基礎,所以配置SqlSessionFactory十分關鍵。在MyBatis-Spring項目中提供了SqlSessionFactoryBean去支持SqlSessionFactory的配置
幾乎能夠配置全部關於MyBatis的組件,而且它也提供了對應的setter方法讓Spring設置它們,因此徹底能夠經過Spring IoC容器的規則去配置它們。因爲使用了第三方的包,通常而言,咱們更傾向於XML的配置。sql
代碼清單:配置SqlSessionFactoryBean數據庫
<!--配置SqlSessionFactoryBean--> <bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:ssm/chapter12/sqlMapConfig.xml"/> </bean>
這裏配置了SqlSesionFactoryBean,可是隻是配置了數據源,而後引入一個MyBatis配置文件,固然若是你所配置的內容很簡單,是能夠徹底不引入MyBatis配置文件的,只須要經過Spring IoC容器注入便可,可是通常而言,較爲複雜的配置,筆者仍是推薦你使用MyBatis的配置文件,這樣的好處在於不至於使得SqlSessionFactoryBean的配置所有依賴於Spring提供的規則,致使配置的複雜性。apache
代碼清單:MyBatis配置文件——sqlMapConfig.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> <settings> <!-- 這個配置使全局的映射器啓用或禁用緩存 --> <setting name="cacheEnabled" value="true"/> <!-- 容許 JDBC 支持生成的鍵。須要適當的驅動。若是設置爲 true,則這個設置強制生成的鍵被使用,儘管一些驅動拒絕兼容但仍然有效(好比 Derby) --> <setting name="useGeneratedKeys" value="true"/> <!-- 配置默認的執行器。SIMPLE 執行器沒有什麼特別之處。REUSE 執行器重用預處理語句。BATCH 執行器重用語句和批量更新 --> <setting name="defaultExecutorType" value="REUSE"/> <!-- 全局啓用或禁用延遲加載。當禁用時,全部關聯對象都會即時加載 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 設置超時時間,它決定驅動等待一個數據庫響應的時間 --> <setting name="defaultStatementTimeout" value="25000"/> </settings> <!-- 別名配置 --> <typeAliases> <typeAlias alias="role" type="com.ssm.chapter12.pojo.Role"/> </typeAliases> <!-- 指定映射器路徑 --> <mappers> <mapper resource="ssm/chapter12/mapper/RoleMapper.xml"/> </mappers> </configuration>
代碼清單:RoleMapper.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.chapter12.mapper.RoleMapper"> <insert id="insertRole" useGeneratedKeys="true" keyProperty="id"> insert into t_role (role_name, note) values (#{roleName}, #{note}) </insert> <delete id="deleteRole" parameterType="long"> delete from t_role where id = #{id} </delete> <select id="getRole" parameterType="long" resultType="role"> select id, role_name as roleName, note from t_role where id = #{id} </select> <update id="updateRole" parameterType="role"> update t_role set role_name = #{roleName}, note = #{note} where id = #{id} </update> </mapper>
定義了一個命名空間(namespace)——com.ssm.chapter12.mapper.RoleMapper,而且提供了對角色的增、刪、查、改方法。按照MyBatis的規則須要定義一個接口RoleMapper.java,纔可以調用它安全
代碼清單:RoleMapper.javamybatis
package com.ssm.chapter12.mapper; import com.ssm.chapter12.pojo.Role; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; @Repository public interface RoleMapper { public int insertRole(Role role); public Role getRole(@Param("id") Long id); public int updateRole(Role role); public int deleteRole(@Param("id") Long id); }
到這裏就完成了關於MyBatis框架的主要代碼,因爲RoleMapper是一個接口,而不是一個類,它沒有辦法產生實例,那麼應該如何配置它呢app
嚴格來講,SqlSessionTemplate並非一個必須配置的組件,可是它也存在必定的價值。首先,它是線程安全的類,也就是確保每一個線程使用的SqlSession惟一且不互相沖突。其次,它提供了一系列的功能,好比增、刪、查、改等經常使用功能
代碼清單:配置SqlSessionTemplate
<!--配置SqlSessionTemplate--> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="SqlSessionFactory"/> <!-- <constructor-arg value="BATCH"/> --> </bean>
SqlSessionTemplate要經過帶有參數的構造方法去建立對象,經常使用的參數是SqlSessionFactory和MyBatis執行器(Ex-ecutor)類型,取值範圍是SIMPLE、REUSE、BATCH,這是咱們以前論述過的執行器的3種類型。
代碼清單:SqlSessionTemplate的應用
ApplicationContext ctx = new ClassPathXmlApplicationContext("ssm/chapter12/spring-cfg.xml");//ctx爲Spring IoC容器 SqlSessionTemplate sqlSessionTemplate = ctx.getBean(SqlSessionTemplate.class); Role role = new Role(); role.setRoleName("role_name_sqlSessionTemplate"); role.setNote("note_sqlSessionTemplate"); sqlSessionTemplate.insert("com.ssm.chapter12.mapper.RoleMapper.insertRole", role); Long id = role.getId(); sqlSessionTemplate.selectOne("com.ssm.chapter12.mapper.RoleMapper.getRole", id); role.setNote("update_sqlSessionTemplate"); sqlSessionTemplate.update("com.ssm.chapter12.mapper.RoleMapper.updateRole", role); sqlSessionTemplate.delete("com.ssm.chapter12.mapper.RoleMapper.deleteRole", id);
當運行一個SqlSessionTemplate時,它就會從新獲取一個新的SqlSession,也就是說每個SqlSession-Template運行的時候會產生新的SqlSession,因此每個方法都是獨立的SqlSession,這意味着它是安全的線程。
關於SqlSessionTemplate,目前運用已經很少,正如代碼清單同樣所示,它須要使用字符串代表運行哪一個SQL,字符串不包含業務含義,只是功能性代碼,並不符合面向對象的規範。與此同時,使用字符串時,IDE沒法檢查代碼邏輯的正確性,因此這樣的用法漸漸被人們拋棄了。注意,SqlSessionTemplate容許配置執行器的類型,當同時配置SqlSessionFactory和SqlSessionTemplate的時候,SqlSessionTemplate的優先級大於SqlSessionFactory。
MyBatis的運行只須要提供相似於RoleMapper.java的接口,而無須提供一個實現類。經過學習MyBatis運行原理,能夠知道它是由MyBatis體系建立的動態代理對象運行的,因此Spring也沒有辦法爲其生成實現類。爲了解決這個問題,MyBatis-Spring團隊提供了一個MapperFactoryBean類做爲中介,咱們能夠經過配置它來實現咱們想要的Mapper。使用了Mapper接口編程方式能夠有效地在你的邏輯代碼中擦除SqlSessionTemplate,這樣代碼就按照面向對象的規範進行編寫了,這是人們樂於採用的形式。
代碼清單:配置RoleMapper對象
<!--配置RoleMapper對象--> <bean id="roleMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!--RoleMapper接口將被掃描爲Mapper --> <property name="mapperInterface" value="com.ssm.chapter12.mapper.RoleMapper"/> <property name="SqlSessionFactory" ref="SqlSessionFactory"/> <!--若是同時注入 sqlSessionTemplate 和 SqlSessionFactory,則只會啓用sqlSessionTemplate --> <!-- <property name="sqlSessionTemplate" ref="sqlSessionTemplate"/> --> </bean>
這裏能夠看到MapperFactoryBean存在3個屬性能夠配置,分別是mapperInterface、sqlSessionTemplate和SqlSessionFac-tory,其中:
•mapperInterface是映射器的接口。
•若是同時配置sqlSessionTemplate和SqlSessionFactory,那麼它就會啓用sqlSessionTemplate,而SqlSessionFac-tory做廢。當咱們配置這樣的一個Bean,那麼咱們就可使用下面的代碼去獲取映射器了。
RoleMapper roleMapper = ctx.getBean(RoleMapper.class);
這是一個經過掃描的形式進行配置Mapper的類,若是一個個去配置Mapper,顯然工做量大,而且致使配置氾濫,有了它只須要給予一些簡單的配置,它就可以生成大量的Mapper,從而減小工做量。首先咱們須要知道它可以配置哪些屬性,對於MapperScannerConfigurer它的主要配置項有如下幾個:
•basePackage,指定讓Spring自動掃描什麼包,它會逐層深刻掃描,若是遇到多個包可使用半角逗號分隔。
•annotationClass,表示若是類被這個註解標識的時候,才進行掃描。對於開發而言,筆者建議使用這個方式進行註冊對應的Mapper。在Spring中每每使用註解@Repository表示數據訪問層(DAO,Data Access Object),因此本書的例子也是以此方式爲主進行介紹的。
•SqlSessionFactoryBeanName,指定在Spring中定義SqlSessionFactory的Bean名稱。若是sqlSessionTemplateBeanName被定義,那麼它將失去做用。
•markerInterface,指定實現了什麼接口就認爲它是Mapper。咱們須要提供一個公共的接口去標記。
代碼清單:經過掃描的方式配置RoleMapper
<!--經過掃描的方式配置RoleMapper--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.ssm.chapter12.mapper"/> <property name="SqlSessionFactoryBeanName" value="SqlSessionFactory"/> <!--使用sqlSessionTemplateBeanName將覆蓋SqlSessionFactoryBeanName的配置--> <!--<property name="sqlSessionTemplateBeanName" value="SqlSessionFactory"/>--> <!--指定標註才掃描成爲Mapper--> <property name="annotationClass" value="org.springframework.stereotype.Repository"/> </bean>