1)、要實現MyBatis與Spring的整合,很明顯須要這兩個框架的JAR包,可是隻使用這兩個框架中所提供的JAR包是不夠的,還須要其餘的JAR包來配合使用,整合時所需準備的JAR包具體以下。Spring框架所需的JAR包:java
注意:核心容器依賴的commons-logging的JAR在MyBatis框架的lib包中已經包含!mysql
2)、MyBatis框架所需的JAR包:(共13個)spring
3)、MyBatis與Spring整合的中間JAR:mybatis-spring-1.3.1.jarsql
4)、數據庫驅動JAR(MySQL):mysql-connector-java-5.1.40-bin.jar數據庫
5)、數據源所需JAR(DBCP數據庫鏈接池):commons-dbcp2-2.1.1.jar、commons-pool2-2.4.2.jarapache
6)、編寫配置文件:編程
①建立項目,引入JAR包;mybatis
②編寫db.properties ;app
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=******
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5框架#密碼本身設置
③編寫Spring配置文件applicationContext.xml;
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 9 http://www.springframework.org/schema/tx 10 http://www.springframework.org/schema/tx/spring-tx-4.3.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.3.xsd 13 http://www.springframework.org/schema/aop 14 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> 15 16 <!--一、讀取db.properties文件的位置 --> 17 <context:property-placeholder location="classpath:db.properties"/> 18 19 <!-- 二、配置數據源 --> 20 <bean id="dataSourceID" class="org.apache.commons.dbcp2.BasicDataSource"> 21 22 <!--2.一、數據庫驅動 --> 23 <property name="driverClassName" value="${jdbc.driver}" /> 24 25 <!--2.二、鏈接數據庫的url --> 26 <property name="url" value="${jdbc.url}" /> 27 28 <!--2.三、鏈接數據庫的用戶名 --> 29 <property name="username" value="${jdbc.username}" /> 30 31 <!--2.四、鏈接數據庫的密碼 --> 32 <property name="password" value="${jdbc.password}" /> 33 34 <!--2.五、最大鏈接數 --> 35 <property name="maxTotal" value="${jdbc.maxTotal}" /> 36 37 <!--2.六、最大空閒鏈接 --> 38 <property name="maxIdle" value="${jdbc.maxIdle}" /> 39 40 <!--2.七、初始化鏈接數 --> 41 <property name="initialSize" value="${jdbc.initialSize}" /> 42 43 </bean> 44 45 <!-- 三、事務管理器,依賴於數據源 --> 46 <bean id="transactionManagerID" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 47 <property name="dataSource" ref="dataSourceID" /> 48 </bean> 49 50 <!--四、開啓事務註解 --> 51 <tx:annotation-driven transaction-manager="transactionManagerID"/> 52 53 <!--五、配置MyBatis工廠來於Spring整合, 54 構建sqlSessionFactory是經過mybatis.spring包中提供的org.mybatis.spring.SqlSessionFactoryBean類配置的; 55 配置時一般須要2個參數:①數據源;②MyBatis的配置文件路徑 56 --> 57 <bean id="sqlSessionFactoryID" class="org.mybatis.spring.SqlSessionFactoryBean"> 58 59 <!--5.一、注入數據源 --> 60 <property name="dataSource" ref="dataSourceID" /> 61 62 <!--5.二、指定核心配置文件位置 :mybatis-config.xml--> 63 <property name="configLocation" value="classpath:mybatis-config.xml"/> 64 65 </bean> 66 67 <!--六、實例化Dao --> 68 <bean id="customerDaoID" class="com.itheima.dao.impl.CustomerDaoImpl"> 69 <!-- 6.一、注入SqlSessionFactory對象實例--> 70 <property name="sqlSessionFactory" ref="sqlSessionFactoryID" /> 71 </bean> 72 73 <!-- 七、Mapper代理開發(基於MapperFactoryBean) --> 74 <!-- <bean id="customerMapperID" class="org.mybatis.spring.mapper.MapperFactoryBean"> 75 76 指定了接口mapperInterface和工廠sqlSessionFactory 77 <property name="mapperInterface" value="com.itheima.mapper.CustomerMapper" /> 78 <property name="sqlSessionFactory" ref="sqlSessionFactoryID" /> 79 80 </bean> --> 81 82 <!-- 八、Mapper代理開發(基於MapperScannerConfigurer) 83 配置類路徑:org.mybatis.spring.mapper.MapperScannerConfigurer 84 指定映射文件所在的包路徑:com.itheima.mapper 85 --> 86 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 87 <property name="basePackage" value="com.itheima.mapper" /> 88 </bean> 89 90 <!-- 九、使用註解,開啓掃描 91 Spring註解提供了另一種高效的註解配置方式,(對包路徑下的全部Bean文件進行掃描) 92 使用 context 命名空間 ,通知Spring掃描指定包下全部Bean類,進行註解解析 93 --> 94 <context:component-scan base-package="com.itheima.service" /> 95 96 </beans>
④編寫MyBatis配置文件mybatis-config.xml;
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 4 <configuration> 5 6 <!--一、配置別名:POJO類過多時,使用自動掃描包的形式定義別名 7 目的:在於減小全限定類名的冗餘。 8 --> 9 <typeAliases> 10 <package name="com.itheima.po" /> 11 </typeAliases> 12 13 <!--二、配置Mapper的位置 --> 14 <mappers> 15 16 <mapper resource="com/itheima/po/CustomerMapper.xml" /> 17 18 <!-- Mapper接口開發方式 --> 19 <mapper resource="com/itheima/mapper/CustomerMapper.xml" /> 20 21 </mappers> 22 </configuration>
⑤引入log4j.properties。
# Global logging configuration
log4j.rootLogger=ERROR, stdout# MyBatis logging configuration...
log4j.logger.com.itheima=DEBUG# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
1)、採用傳統DAO開發方式進行MyBatis與Spring框架的整合時,可使用mybatis-spring包中所提供的SqlSessionTemplate類或SqlSessionDaoSupport類來實現。
2)、SqlSessionTemplate:是mybatis-spring的核心類,它負責管理MyBatis的SqlSession(會話對象),調用MyBatis的SQL方法。當調用SQL方法時,SqlSessionTemplate將會保證使用的SqlSession和當前Spring的事務是相關的。它還管理SqlSession的生命週期,包含必要的關閉、提交和回滾操做。
3)、SqlSessionDaoSupport:是一個抽象支持類,它繼承了DaoSupport類,主要是做爲DAO的基類來使用。能夠經過SqlSessionDaoSupport類的getSqlSession()方法來獲取所需的SqlSession。
4)、實現持久層:
①客戶持久化類:src/com/itheima/po/Customer.java
1 package com.itheima.po; 2 /** 3 * 客戶持久化類 4 */ 5 public class Customer { 6 private Integer id; // 主鍵id 7 private String username; // 客戶名稱 8 private String jobs; // 職業 9 private String phone; // 電話 10 11 public Integer getId() { 12 return id; 13 } 14 15 public void setId(Integer id) { 16 this.id = id; 17 } 18 19 public String getUsername() { 20 return username; 21 } 22 23 public void setUsername(String username) { 24 this.username = username; 25 } 26 27 public String getJobs() { 28 return jobs; 29 } 30 31 public void setJobs(String jobs) { 32 this.jobs = jobs; 33 } 34 35 public String getPhone() { 36 return phone; 37 } 38 39 public void setPhone(String phone) { 40 this.phone = phone; 41 } 42 43 @Override 44 public String toString() { 45 return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]"; 46 } 47 }
②建立客戶映射(映射數據庫表)文件:src/com/itheima/po/CustomerMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 5 <mapper namespace="com.itheima.po.CustomerMapper"> 6 7 <!--根據id查詢客戶信息 --> 8 <select id="findCustomerById" parameterType="Integer" 9 resultType="customer"> 10 <!-- 屬性resultType:用於指定返回結果的類型,這裏表示返回的數據是customer對象類型, 11 可見,其直接使用了別名,減小全限定名稱的冗餘。 12 至關於把 com.itheima.po.Customer 換成了customer 13 --> 14 select * from t_customer where id = #{id} 15 </select> 16 </mapper>
③在MyBatis的配置文件mybatis-config.xml中,配置映射文件src/com/itheima/po/CustomerMapper.xml
<mapper resource="com/itheima/po/CustomerMapper.xml" />
5)、實現DAO層
①建立Dao的接口:CustomerDao
package com.itheima.dao; import com.itheima.po.Customer; public interface CustomerDao { // 經過id查詢客戶 public Customer findCustomerById(Integer id); }
②建立接口CustomerDao的實現類:src/com/itheima/dao/impl/CustomerDaoImpl.java
1 package com.itheima.dao.impl; 2 import org.mybatis.spring.support.SqlSessionDaoSupport; 3 import com.itheima.dao.CustomerDao; 4 import com.itheima.po.Customer; 5 6 7 /* CustomerDaoImpl類繼承了SqlSessionDaoSupport類,並實現了CustomerDao接口。 8 * 其中SqlSessionDaoSupport類在使用時須要一個SqlSessionFactory或一個SqlSessionTemplate對象 9 * 因此須要Spring給SqlSessionDaoSupport類的子類對象注入一個SqlSessionFactory或SqlSessionTemplate。 10 * 這樣子類中就能經過調用SqlSessionDaoSupport類的getSqlSession()方法來獲取SqlSession對象,並使用SqlSession對象中的方法。 11 * 12 */ 13 14 public class CustomerDaoImpl extends SqlSessionDaoSupport implements CustomerDao { 15 // 經過id查詢客戶 16 public Customer findCustomerById(Integer id) { 17 return this.getSqlSession().selectOne("com.itheima.po.CustomerMapper.findCustomerById", id); 18 } 19 }
③整合測試:src/com/itheima/test/DaoTest.java
1 package com.itheima.test; 2 import org.junit.Test; 3 import org.springframework.context.ApplicationContext; 4 import 5 org.springframework.context.support.ClassPathXmlApplicationContext; 6 import com.itheima.dao.CustomerDao; 7 import com.itheima.mapper.CustomerMapper; 8 import com.itheima.po.Customer; 9 /** 10 * DAO測試類 11 */ 12 public class DaoTest { 13 @Test 14 public void findCustomerByIdDaoTest(){ 15 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); 16 // 根據容器中Bean的id來獲取指定的Bean 17 // CustomerDao customerDao = (CustomerDao) act.getBean("customerDaoID"); 18 19 //Spring獲取Bean的另外一種方式,這種方式再也不須要進行強制類型轉換了 20 CustomerDao customerDao = act.getBean(CustomerDao.class); 21 Customer customer = customerDao.findCustomerById(1); 22 System.out.println(customer); 23 } 24 }
④測試結果:
1)、在MyBatis+Spring的項目中,雖然使用傳統的DAO開發方式能夠實現所需功能,可是採用這種方式在實現類中會出現大量的重複代碼,在方法中也須要指定映射文件中執行語句的id,而且不能保證編寫時id的正確性(運行時才能知道)。爲此,咱們可使用MyBatis提供的另一種編程方式,即使用Mapper接口編程。
2)、基於MapperFactoryBean的整合
a)、MapperFactoryBean是MyBatis-Spring團隊提供的一個用於根據Mapper接口生成Mapper對象的類,該類在Spring配置文件中使用時能夠配置如下參數:
mapperInterface:用於指定接口;
SqlSessionFactory:用於指定SqlSessionFactory;
SqlSessionTemplate:用於指定SqlSessionTemplate。若是與SqlSessionFactory同時設定,則只會啓用SqlSessionTemplate。
b)、實操MapperFactoryBean是如何來實現MyBatis與Spring的整合:
①建立CustomerMapper接口即對應的映射文件:(注意此處就與上面的操做不一樣了)src/com/itheima/mapper--->CustomerMapper.java
1 package com.itheima.mapper; 2 3 import java.lang.Integer; 4 import com.itheima.po.Customer; 5 public interface CustomerMapper { // 建立CustomerMapper接口 6 7 // 經過id查詢客戶 8 public Customer findCustomerById(Integer id); 9 10 // 添加客戶 11 public void addCustomer(Customer customer); 12 13 }
②src/com/itheima/mapper--->CustomerMapper.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 3 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 4 5 <mapper namespace="com.itheima.mapper.CustomerMapper"> 6 7 <!--一、根據id查詢客戶信息,返回類型是customer類型 8 Mapper接口中的方法名和Mapper.xml中定義的每一個執行語句的id相同!!! 9 --> 10 <select id="findCustomerById" parameterType="Integer" 11 resultType="customer"> 12 select * from t_customer where id = #{id} 13 </select> 14 15 <!--二、添加客戶信息,參數類型是 customer類型--> 16 <insert id="addCustomer" parameterType="customer"> 17 insert into t_customer(username,jobs,phone) 18 values(#{username},#{jobs},#{phone}) 19 </insert> 20 21 </mapper>
③在MyBatis的配置文件mybatis-config.xml中,配置新的映射文件src/com/itheima/mapper/CustomerMapper.xml
<mapper resource="com/itheima/mapper/CustomerMapper.xml" />
④在Spring的配置文件中,建立CustomerMapper的Bean實例id
<!-- 七、Mapper代理開發(基於MapperFactoryBean) --> <bean id="customerMapperID" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!-- 指定了接口mapperInterface和工廠sqlSessionFactory --> <property name="mapperInterface" value="com.itheima.mapper.CustomerMapper" /> <property name="sqlSessionFactory" ref="sqlSessionFactoryID" /> </bean>
⑤單元測試:
@Test public void findCustomerByIdMapperTest(){ ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); CustomerMapper customerMapper = act.getBean(CustomerMapper.class); Customer customer = customerMapper.findCustomerById(1); System.out.println(customer); }
⑥測試結果:
c)、Mapper接口編程方式只須要編寫Mapper接口(至關於DAO接口),而後由MyBatis框架根據接口的定義建立接口的動態代理對象,等同於DAO接口的實現類。
3)、雖然使用Mapper接口編程的方式很簡單,可是在具體使用時仍是須要遵循一些規範。
a)、Mapper接口的名稱和對應的Mapper.xml映射文件的名稱必須一致。
b)、Mapper.xml文件中的namespace與Mapper接口的類路徑相同。(即接口文件和映射文件須要放在同一個包中)
c)、注意:Mapper接口中的方法名和Mapper.xml中定義的每一個執行語句的id相同。
d)、Mapper接口中方法的輸入參數類型要和Mapper.xml中定義的每一個sql的parameterType的類型相同。
e)、Mapper接口方法的輸出參數類型要和Mapper.xml中定義的每一個sql的resultType的類型相同。
4)、基於MapperScannerConfigurer的整合
a)、在實際的項目中,DAO層會包含不少接口,若是每個接口都在Spring配置文件中配置,不但會增長工做量,還會使得Spring配置文件很是臃腫。爲此,能夠採用自動掃描的形式來配置MyBatis中的映射器——採用MapperScannerConfigurer類。
b)、MapperScannerConfigurer類在Spring配置文件中能夠配置如下屬性:
basePackage:指定映射接口文件所在的包路徑,當須要掃描多個包時可使用分號或逗號做爲分隔符。指定包路徑後,會掃描該包及其子包中的全部文件。
annotationClass:指定了要掃描的註解名稱,只有被註解標識的類纔會被配置爲映射器。
sqlSessionFactoryBeanName:指定在Spring中定義的SqlSessionFactory的Bean名稱。
sqlSessionTemplateBeanName:指定在Spring中定義的SqlSessionTemplate的Bean名稱。若是定義此屬性,則sqlSessionFactoryBeanName將不起做用。
markerInterface:指定建立映射器的接口。
c)、MapperScannerConfigurer的使用很是簡單,只須要在Spring的配置文件中編寫以下代碼:
<!-- Mapper代理開發(基於MapperScannerConfigurer) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.itheima.mapper" /> </bean>
d)、一般狀況下,MapperScannerConfigurer在使用時只需經過basePackage屬性指定須要掃描的包便可,Spring會自動的經過包中的接口來生成映射器。這使得開發人員能夠在編寫不多代碼的狀況下,完成對映射器的配置,從而提升開發效率。對MapperScannerConfigurer進行測試可得與上面相同的結果。
1)、在項目中,Service層既是處理業務的地方,又是管理數據庫事務的地方。對事務進行測試:
a)、建立Service層;
b)、在Service層編寫添加客戶操做的代碼;
c)、有意地添加一段異常代碼(如int i = 1/0;)來模擬現實中的意外狀況;
d)、編寫測試方法,調用業務層的添加方法。這樣,程序在執行到錯誤代碼時就會出現異常。
2)、在沒有事務管理的狀況下,即便出現了異常,數據也會被存儲到數據表中;若是添加了事務管理,而且事務管理的配置正確,那麼在執行上述操做時,所添加的數據將不可以插入到數據表中。
3)在CustomerMapper接口中,添加addCustomer()方法,而後在CustomerMapper映射文件中編寫執行插入操做的SQL配置,具體看上面的代碼。
①建立業務接口:src/com/itheima/service/CustomerService.java
package com.itheima.service; import com.itheima.po.Customer; public interface CustomerService { // 業務層:建立CustomerService接口 public void addCustomer(Customer customer); }
②建立業務接口的實現類:com/itheima/service/impl/CustomerServiceImpl.java
1 package com.itheima.service.impl; 2 import org.springframework.beans.factory.annotation.Autowired; 3 import org.springframework.stereotype.Service; 4 import org.springframework.transaction.annotation.Transactional; 5 import com.itheima.mapper.CustomerMapper; 6 import com.itheima.po.Customer; 7 import com.itheima.service.CustomerService; 8 9 // 使用Spring的註解@Service來標識業務層的類 10 @Service 11 12 // 使用@Transactional註解來標識事務處理的類 13 @Transactional 14 public class CustomerServiceImpl implements CustomerService { 15 16 //經過@Autowired註解注入CustomerMapper 17 @Autowired 18 private CustomerMapper customerMapper; 19 20 //添加客戶 21 public void addCustomer(Customer customer) { 22 // 調用接口中的addCustomer()方法 23 this.customerMapper.addCustomer(customer); 24 25 //模擬添加操做後系統忽然出現的異常問題 26 int i = 1 / 0; 27 } 28 }
③在Spring的配置文件中,編寫開啓註解掃描的配置代碼:
<!-- 九、使用註解,開啓掃描 Spring註解提供了另一種高效的註解配置方式,(對包路徑下的全部Bean文件進行掃描) 使用 context 命名空間 ,通知Spring掃描指定包下全部Bean類,進行註解解析 --> <context:component-scan base-package="com.itheima.service" />
④測試類:com/itheima/test/TransactionTest.java
1 package com.itheima.test; 2 import org.springframework.context.ApplicationContext; 3 import org.springframework.context.support.ClassPathXmlApplicationContext; 4 import com.itheima.po.Customer; 5 import com.itheima.service.CustomerService; 6 /** 7 * 測試事務 8 */ 9 public class TransactionTest { 10 public static void main(String[] args) { 11 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); 12 CustomerService customerService = act.getBean(CustomerService.class); 13 14 Customer customer = new Customer(); 15 customer.setUsername("zhangsan"); 16 customer.setJobs("manager"); 17 customer.setPhone("13233334444"); 18 customerService.addCustomer(customer); 19 } 20 }
⑤先將@Transactional註釋掉後運行測試類的結果以下:
4)、雖拋出異常,但查詢數據庫mybatis中的t_customer表可知,新添加的數據已經存儲在該表中,這就驗證了在沒有事務管理的狀況下,即便出現了異常,數據也會被存儲到數據表中。
5)、將註釋去掉,再次執行並查詢表如圖所示:
這就說明項目中配置的事務是正確的。
本章詳細介紹瞭如何實現SM的整合步驟。我的認爲基於Mapper的接口方式實現MyBatis與Spring的整合是相對比較方便和簡單的,至少在編碼方面能提升開發者的工做效率,但實現DAO層的整合也需充分理解,總之,實踐是檢驗真知的標準!