MyBatis-Spring 會幫助你將 MyBatis 代碼無縫地整合到 Spring 中。 使用這個類庫中的類, Spring 將會加載必要的MyBatis工廠類和 session 類。 這個類庫也提供一個簡單的方式來注入MyBatis數據映射器和SqlSession到業務層的bean中。 並且它也會處理事務, 翻譯MyBatis的異常到Spring的 DataAccessException異常(數據訪問異常,譯者注)中。最終它並不會依賴於MyBatis,Spring或MyBatis-Spring來構建應用程序代碼。更多內容請查看官網幫助。html
爲了完成Spring4.x與MyBatis3.X的整合更加順利,先回顧在Maven環境下建立Web項目並使用MyBatis3.X,第1、二點內容多數是回顧過去的內容 。完成第一階段與第二階段的項目結構以下所示:java
下載階段一與階段二示例mysql
1.二、點擊「File」->「New」->"Other"->輸入「Maven」,新建一個「Maven Project」,以下圖所示:git
1.二、請勾選「Create a simple project」,建立一個簡單的項目,不使用模板。也可使用模板,選擇WebApp,不過這裏就不該該勾選。以下圖所示:github
1.三、填寫好包名、項目名,選擇打包類型爲:war,以下圖所示:web
1.四、項目建立好後可能會發現有錯誤,選擇項目,右鍵「屬性properties」->"層面Project Facets"->"Java"修改版本號爲1.7,默認爲1.5;點擊「Ok」保存後關閉。以下圖所示:spring
1.五、重複上一個步驟,反勾Dynamic Web Module,將項目暫時變成非Web項目。點擊「Ok」保存後關閉。sql
1.六、重複上一步驟,再進層面屬性,勾選「Dynamic Web Module」選擇Version爲3.0。點擊左下角的超連接「Further Configuration available...「。數據庫
1.七、勾選「Generate web.xml deployment descriptor」生成web.xml部署描述文件。點擊「Ok」保存後關閉。apache
1.八、將生成的WebContent目錄下的兩個文件夾「META-INF」與「WEB-INF」複製到src/main/webapp目錄下。
1.九、刪除WebContent目錄。
1.十、刪除後會發現項目的pom.xml文件報錯,是由於找不到指定位置的web.xml文件引發的。再進入項目的屬性,選擇「Deployment Assembly」項目部署項,刪除「src/test/java」、「src/test/resources」與「WebContent」目錄,由於這三項不須要部署出去。
1.十一、點擊「Add添加」後選擇「Folder文件夾」爲項目的最終部署結果指定Web內容根文件夾。
1.十二、選擇src\main\webapp目錄爲目標目錄,點擊「Finish完成」保存並關閉。
1.1三、若是此時項目還報錯,隨便修改pom.xml文件後保存後應該錯誤會消失。
1.1四、在src\main\webapp目錄下新建一個index.jsp文件,做爲測試使用。
1.1五、新建完成後發現有錯誤,是由於沒有JavaEE Server Runtime引發的,在項目上右鍵屬性選擇「Java Build Path」項,點擊「Add Library...」添加引用。
1.1六、選擇Server Runtime項,點擊「Next下一步」,再選擇「Apache Tomcat v7.0」,這裏可能要根據本身的運行環境選擇了,若是還沒Server,則應該先整合Tomcat。
1.1七、在index.jsp文件中寫上測試內容。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Hello World!</title> </head> <body> Hello World! <p> <%=new java.util.Date().toLocaleString() %> </p> </body> </html>
1.1八、在項目上右鍵選擇「Run as」-> 「Run on Server」運行項目,運行結果以下。
要完成使用MyBatis訪問MySQL數據庫,須要添加一些依賴包,包含MyBatis3,鏈接驅動,JUnit,Log4j2等。能夠去共享資源庫中搜索,第一個網站地址是:http://mvnrepository.com/, 這裏以搜索鏈接驅動爲示例,搜索後的結果有5.xx版許多,也有6.xx版,但不建議使用6.xx版,由於MyBatis3不支持。
咱們選擇5.0版中的5.1.38,將Maven的依賴信息複製到項目中的pom.xml的dependencies結點下
固然也可去另一個網站:http://search.maven.org/,這裏以log4j爲例子搜索以下:
有一些依賴也能夠直接去官網查找,如MyBatis3:
項目的pom.xml文件以下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zhangguo</groupId> <artifactId>Spring061</artifactId> <version>0.0.1</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
引用結果:
若是在網速不穩定的狀況下,下載包頗有可能失敗,能夠試試強制項目從新下載;可使用下載工具將jar包下載後手複製到本地資源庫中。
打開MySQL數據庫,建立一個表,這裏以booktypes表爲例。
sql腳本以下:
/* Navicat MySQL Data Transfer Source Server : localhost Source Server Version : 50536 Source Host : localhost:3306 Source Database : db2 Target Server Type : MYSQL Target Server Version : 50536 File Encoding : 65001 Date: 2016-07-04 10:49:56 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `booktypes` -- ---------------------------- DROP TABLE IF EXISTS `booktypes`; CREATE TABLE `booktypes` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '類型編號', `typeName` varchar(100) NOT NULL COMMENT '類型名稱', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=94 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of booktypes -- ---------------------------- INSERT INTO `booktypes` VALUES ('1', '計算機軟件開發'); INSERT INTO `booktypes` VALUES ('2', '計算機網絡工程'); INSERT INTO `booktypes` VALUES ('3', '神話小說'); INSERT INTO `booktypes` VALUES ('4', '科幻小說'); INSERT INTO `booktypes` VALUES ('5', '外語'); INSERT INTO `booktypes` VALUES ('6', '測試類型'); INSERT INTO `booktypes` VALUES ('7', '91'); INSERT INTO `booktypes` VALUES ('8', '92'); INSERT INTO `booktypes` VALUES ('9', '93'); INSERT INTO `booktypes` VALUES ('91', '建築設計'); INSERT INTO `booktypes` VALUES ('92', '工業設計'); INSERT INTO `booktypes` VALUES ('93', '船舶製造');
在包com.zhangguo.Spring61.entities下添加類BookType類型。
package com.zhangguo.Spring61.entities; /** * 圖書類型 * */ public class BookType { /** * 編號 */ private int id; /** * 類型名 */ private String typeName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getTypeName() { return typeName; } public void setTypeName(String typeName) { this.typeName = typeName; } @Override public String toString() { return this.getId()+"\t"+this.getTypeName(); } }
這裏用接口+XML的形式完成,BookType數據訪問接口以下:
package com.zhangguo.Spring61.mapping; import java.util.List; import com.zhangguo.Spring61.entities.BookType; /** * 圖書類型數據訪問接口 * */ public interface BookTypeDAO { /* * 得到全部圖書類型 */ public List<BookType> getAllBookTypes(); }
BookTypeMapper.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.zhangguo.Spring61.mapping.BookTypeDAO"> <!--id應該是接口中的方法,結果類型如沒有配置別名則應該使用全名稱 --> <select id="getAllBookTypes" resultType="BookType"> select id,typeName from booktypes </select> </mapper>
MyBatisCfg.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> <!-- 指定數據庫鏈接信息的位置 --> <properties resource="db.properties"></properties> <!--類型別名,默認引入com.zhangguo.Spring61.entities下的全部類 --> <typeAliases> <package name="com.zhangguo.Spring61.entities"/> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <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> <mappers> <!--引入映射文件 --> <mapper resource="com/zhangguo/Spring61/mapping/BookTypeMapper.xml" /> </mappers> </configuration>
由於配置中依賴了db.properties文件,該文件用於指定數據庫的鏈接信息,內容以下:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/db2 username=root password=root
爲了更加方便的複用MyBatis實現數據訪問不須要頻繁的建立SQLSessionFactory和SQLSession對象,封裝一個MyBatisUtil工具類以下:
package com.zhangguo.Spring61.dao; import java.io.InputStream; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public abstract class MyBatisUtil { //GC不理static private static SqlSessionFactory factory=null; public static SqlSessionFactory getSqlSessionFactory(){ if(factory==null){ // 得到環境配置文件流 InputStream config = MyBatisUtil.class.getClassLoader().getResourceAsStream("MyBatisCfg.xml"); // 建立sql會話工廠 factory = new SqlSessionFactoryBuilder().build(config); } return factory; } //得到會話 public static SqlSession getSession(){ return getSqlSessionFactory().openSession(true); } /** * 得到得sql會話 * @param isAutoCommit 是否自動提交,若是爲false則須要sqlSession.commit();rollback(); * @return sql會話 */ public static SqlSession getSession(boolean isAutoCommit){ return getSqlSessionFactory().openSession(isAutoCommit); } }
建立類BookTypeDAOImpl實現接口BookTypeDAO,這裏要經過MyBatis實現數據訪問功能,內容以下:
package com.zhangguo.Spring61.dao; import java.util.List; import org.apache.ibatis.session.SqlSession; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; /** * 實現圖書類型數據訪問 * */ public class BookTypeDAOImpl implements BookTypeDAO { @Override public List<BookType> getAllBookTypes() { //得到會話對象 SqlSession session=MyBatisUtil.getSession(); try { //經過MyBatis實現接口BookTypeDAO,返回實例 BookTypeDAO bookTypeDAO=session.getMapper(BookTypeDAO.class); return bookTypeDAO.getAllBookTypes(); } finally { session.close(); } } }
新建一個JUnit Test Case測試用例,以下所示:
測試用例TestBookTypeDAOImpl.java文件以下:
package com.zhangguo.Spring61.test; import static org.junit.Assert.*; import java.util.List; import org.junit.BeforeClass; import org.junit.Test; import com.zhangguo.Spring61.dao.BookTypeDAOImpl; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; public class TestBookTypeDAOImpl { static BookTypeDAO bookTypeDao; @BeforeClass public static void beforeClass() { bookTypeDao=new BookTypeDAOImpl(); } @Test public void testGetAllBookTypes() { List<BookType> booktypes=bookTypeDao.getAllBookTypes(); for (BookType bookType : booktypes) { System.out.println(bookType); } assertNotNull(booktypes); } }
測試結果:
上面的測試雖然經過,可是有一個錯誤提示「ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.」,大意是:日誌記錄器沒有找到log4j2的配置文件。在源碼的根目錄下建立一個log4j2.xml配置文件,文件內容以下所示:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="off" monitorInterval="1800"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" /> </Console> </Appenders> <Loggers> <Root level="debug"> <AppenderRef ref="Console" /> </Root> </Loggers> </Configuration>
再運行就會發現log4j2已經在運行了,從控制檯能夠看到MyBatis的運行狀態信息:
程序向數據庫發送的SQL請求,及數據庫向程序響應的結果就清楚了。
在MyBatis的github官網(https://github.com/mybatis/spring)中有一個叫MyBatis Spring Adapter(MyBatis-Spring)的庫,暫且翻譯成:MyBatis Spring適配器,它的做用是:原話:「MyBatis-Spring adapter is an easy-to-use Spring3 bridge for MyBatis sql mapping framework.」,就是了爲更容易的將MyBatis與Spring整合,充分發揮二兩結合的優點,它至關於一個橋。
什麼是:MyBatis-Spring?
MyBatis-Spring會幫助你將MyBatis代碼無縫地整合到Spring中。使用這個類庫中的類,Spring將會加載必要的MyBatis工廠類和session類。這個類庫也提供一個簡單的方式來注入MyBatis數據映射器和SqlSession到業務層的bean中。並且它也會處理事務,翻譯MyBatis的異常到Spring的DataAccessException異常(數據訪問異常,譯者注)中。最終,它並不會依賴於MyBatis,Spring或MyBatis-Spring來構建應用程序代碼。
爲了將Spring與MyBatis整合完成,須要依賴MyBatis,由於在上面的示例中已依賴完成,這裏就再也不須要,主要需依賴的是Spring核心,AOP,JDBC,MyBatis-Spring等jar包。具體的依賴結果pom.xml文件以下所示:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zhangguo</groupId> <artifactId>Spring061</artifactId> <version>0.0.1</version> <packaging>war</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.3.0.RELEASE</spring.version> </properties> <dependencies> <!--mysql數據庫驅動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--log4j日誌包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.6.1</version> </dependency> <!-- mybatis ORM框架 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!-- JUnit單元測試工具 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> <!--mybatis-spring適配器 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!--Spring框架核心庫 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectJ AOP 織入器 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <!--Spring java數據庫訪問包,在本例中主要用於提供數據源 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> </dependencies> </project>
該文件取名爲ApplicationContext.xml主要緣由是「約束優於配置」的理由,使用Web監聽器加載Spring時會默認找該名稱的文件。在文件中咱們可像之前學習Spring同樣配置IOC與AOP,只不過這裏整合了一些MyBatis內容。文件內容以下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!--1定義一個jdbc數據源,建立一個驅動管理數據源的bean --> <bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/db2" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean> <!--2建立一個sql會話工廠bean,指定數據源--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="jdbcDataSource" /><!-- 指定數據源 --> <property name="configLocation" value="classpath:MyBatisCfg.xml"></property> <!-- 指定配置文件 --> </bean> <!--3建立一個booTypeDAO--> <bean id="bookTypeDao" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!--指定映射文件 --> <property name="mapperInterface" value="com.zhangguo.Spring61.mapping.BookTypeDAO"></property> <!-- 指定sql會話工廠--> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> <!--下面的配置暫時未使用 --> <context:component-scan base-package="com.zhangguo"> </context:component-scan> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> </beans>
從上面的代碼能夠看到分別建立了一個驅動管理數據源的對象,會話工廠與實現數據訪問的對象經過Spring IOC完成,而再也不是硬編碼。第2段配置與下面的代碼功能基本相似:
private static SqlSessionFactory factory=null; public static SqlSessionFactory getSqlSessionFactory(){ if(factory==null){ // 得到環境配置文件流 InputStream config = MyBatisUtil.class.getClassLoader().getResourceAsStream("MyBatisCfg.xml"); // 建立sql會話工廠 factory = new SqlSessionFactoryBuilder().build(config); } return factory; }
第3段配置與下面的java代碼基本相似:
SqlSession session = MyBatisUtil.getSession(); try { BookTypeDAO bookTypeDAO = session.getMapper(BookTypeDAO.class); return bookTypeDAO.getAllBookTypes(); } finally { session.close(); }
package com.zhangguo.Spring61.test; import static org.junit.Assert.assertNotNull; import java.util.List; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; public class TestMyBatisSpring01 { @Test public void test01() { //初始化容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("ApplicationContext.xml"); //得到bean BookTypeDAO bookTypeDao=ctx.getBean("bookTypeDao",BookTypeDAO.class); //訪問數據庫 List<BookType> booktypes=bookTypeDao.getAllBookTypes(); for (BookType bookType : booktypes) { System.out.println(bookType); } assertNotNull(booktypes); } }
運行結果:
小結:此處的整合仍是相對基礎,更完善的整合內容將在後面的章節實現。另外在MyBatisCfg.xml文件中能夠刪除運行環境中數據源配置部分的內容,以下圖所示。咱們當前的示例使用的是Spring提供的數據源,其實也可使用一第三方的數據源管理,如C3P0,Druid(德魯伊,阿里巴巴開發)等。
在沒有Spring的環境下咱們單純使用MyBatis ORM框架時,咱們是經過MyBatisCfg.xml完成sqlSessionFactory的構建工做,若是使用Spring則這部分配置的內容能夠徹底由Spring容器替代,具體實現以下:
<!--建立一個sql會話工廠bean,指定數據源 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 1指定數據源 --> <property name="dataSource" ref="jdbcDataSource" /> <!-- 2類型別名包,默認引入com.zhangguo.Spring61.entities下的全部類 --> <property name="typeAliasesPackage" value="com.zhangguo.Spring61.entities"></property> <!-- 3指定sql映射xml文件的路徑 --> <property name="mapperLocations" value="classpath:com/zhangguo/Spring61/mapping/*Mapper.xml"></property> </bean>
mapperLocations:它表示咱們的Mapper文件存放的位置,當咱們的Mapper文件跟對應的Mapper接口處於同一位置的時候能夠不用指定該屬性的值。
configLocation:用於指定Mybatis的配置文件位置。若是指定了該屬性,那麼會以該配置文件的內容做爲配置信息構建對應的SqlSessionFactoryBuilder,可是後續屬性指定的內容會覆蓋該配置文件裏面指定的對應內容。
typeAliasesPackage:它通常對應咱們的實體類所在的包,這個時候會自動取對應包中不包括包名的簡單類名做爲包括包名的別名。多個package之間能夠用逗號或者分號等來進行分隔。
typeAliases:數組類型,用來指定別名的。指定了這個屬性後,Mybatis會把這個類型的短名稱做爲這個類型的別名,前提是該類上沒有標註@Alias註解,不然將使用該註解對應的值做爲此種類型的別名。
<property name="typeAliases"> <array> <value>com.tiantian.mybatis.model.Blog</value> <value>com.tiantian.mybatis.model.Comment</value> </array> </property>
咱們修改了applicationContext.xml中的配置,經過容器完成了一個sqlSessionFactory Bean的建立, 1指定了數據源,2指定類型別名包這樣在sql映射文件中使用類型時能夠省去全名稱,3指定了全部要加載的sql映射xml文件,若是有多個目錄,則可使用以下的形式:
<property name="mapperLocations"> <list> <value>classpath:com/...目錄.../*_mapper.xml</value> <value>classpath:com/...目錄.../*_resultmap.xml</value> </list> </property>
若是須要設置更多的屬性則能夠參考類型org.mybatis.spring.SqlSessionFactoryBean,若是不使用Spring,也不使用MyBatis配置文件咱們照樣能夠得到一個sqlSessionFactory對象完成對MyBatis ORM框架的使用,由於能夠直接實例化一個SqlSessionFactoryBean對象,只是此時該工做被Spring容器替代,按這個思路能夠在SqlSessionFactoryBean類中找到更多的屬性設置在applicationContext.xml配置中,部分源代碼以下所示:
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> { private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class); private Resource configLocation; private Configuration configuration; private Resource[] mapperLocations; private DataSource dataSource; private TransactionFactory transactionFactory; private Properties configurationProperties; private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); private SqlSessionFactory sqlSessionFactory; //EnvironmentAware requires spring 3.1 private String environment = SqlSessionFactoryBean.class.getSimpleName(); private boolean failFast; private Interceptor[] plugins; private TypeHandler<?>[] typeHandlers; private String typeHandlersPackage; private Class<?>[] typeAliases; private String typeAliasesPackage; private Class<?> typeAliasesSuperType; //issue #19. No default provider. private DatabaseIdProvider databaseIdProvider; private Class<? extends VFS> vfs; private Cache cache; private ObjectFactory objectFactory; private ObjectWrapperFactory objectWrapperFactory; }
若是習慣二者結合使用,固然仍是能夠指定MyBatis配置文件的,增長屬性:<property name="configLocation" value="classpath:MyBatisCfg.xml"></property>
在示例3的applicationContext.xml配置文件中有一段實現BookTypeDAO接口實例的建立工廠,配置以下:
<!-- 建立一個booTypeDAO --> <bean id="bookTypeDao" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!--指定映射文件 --> <property name="mapperInterface" value="com.zhangguo.Spring61.mapping.BookTypeDAO"></property> <!-- 指定sql會話工廠 --> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>
若是有多個表,則須要配置多段信息,麻煩。咱們能夠經過自動掃描一次完成,配置以下:
<!--自動掃描映射接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定sql會話工廠,在上面配置過的 --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> <!-- 指定基礎包,即自動掃描com.zhangguo.Spring61.mapping這個包以及它的子包下的全部映射接口類 --> <property name="basePackage" value="com.zhangguo.Spring61.mapping"></property> </bean>
須要注意的是這裏的sql會話工廠的指定可使用sqlSessionFactoryBeanName屬性指定,也可使用sqlSessionFactory屬性指定,但建議你們使用sqlSessionFactoryBeanName,不然會由於加載的前後順序問題引發讀不到properties文件的內容。其它屬性的設置能夠查看源碼後再定義。
這樣MapperScannerConfigurer就會掃描指定basePackage下面的全部接口,並把它們註冊爲一個個MapperFactoryBean對象。basePackage下面的並不全是咱們定義的Mapper接口,爲此MapperScannerConfigurer還爲咱們提供了另外兩個能夠縮小搜索和註冊範圍的屬性。一個是annotationClass,另外一個是markerInterface。
annotationClass:當指定了annotationClass的時候,MapperScannerConfigurer將只註冊使用了annotationClass註解標記的接口。
markerInterface:markerInterface是用於指定一個接口的,當指定了markerInterface以後,MapperScannerConfigurer將只註冊繼承自markerInterface的接口。
sqlSessionFactory: 已廢棄 。當使用多個數據源時就須要經過sqlSessionFactory來指定註冊MapperFactoryBean的時候須要使用的SqlSessionFactory,由於在沒有指定sqlSessionFactory的時候,會以Autowired的方式自動注入一個。換言之當咱們只使用一個數據源的時候,即只定義了一個SqlSessionFactory的時候咱們就能夠不給MapperScannerConfigurer指定SqlSessionFactory。
sqlSessionFactoryBeanName:它的功能跟sqlSessionFactory是同樣的,只是它指定的是定義好的SqlSessionFactory對應的bean名稱。
sqlSessionTemplate: 已廢棄 。它的功能也是至關於sqlSessionFactory的,MapperFactoryBean最終仍是使用的SqlSession的getMapper方法取的對應的Mapper對象。當定義有多個SqlSessionTemplate的時候才須要指定它。對於一個MapperFactoryBean來講SqlSessionFactory和SqlSessionTemplate只須要其中一個就能夠了,當二者都指定了的時候,SqlSessionFactory會被忽略。
sqlSessionTemplateBeanName:指定須要使用的sqlSessionTemplate對應的bean名稱。
從示例3的配置代碼中能夠發現數據庫鏈接字符信息同時出如今兩個位置,分別是applicationContext.xml與db.properties文件中,以下所示:
<!--定義一個jdbc數據源,建立一個驅動管理數據源的bean --> <bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/db2" /> <property name="username" value="root" /> <property name="password" value="root" /> </bean>
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/db2 username=root password=root
根據咱們寫代碼的原則「Write once only once」,鏈接字符信息應該只存在一個位置,咱們能夠採用下面的方法整合:
修改後的db.properties文件內容以下:
#jdbc jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=UTF-8 jdbc.uid=root jdbc.pwd=root #other .. other.msg=hello
修改後的 applicationContext.xml文件內容以下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"> <!--屬性佔位文件引入,能夠經過${屬性名}得到屬性文件中的內容--> <context:property-placeholder location="classpath:db.properties"/> <!--定義一個jdbc數據源,建立一個驅動管理數據源的bean --> <bean id="jdbcDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.uid}" /> <property name="password" value="${jdbc.pwd}" /> </bean> <!--建立一個sql會話工廠bean,指定數據源 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定數據源 --> <property name="dataSource" ref="jdbcDataSource" /> <!--類型別名包,默認引入com.zhangguo.Spring61.entities下的全部類 --> <property name="typeAliasesPackage" value="com.zhangguo.Spring61.entities"></property> <!--指定sql映射xml文件的路徑 --> <property name="mapperLocations" value="classpath:com/zhangguo/Spring61/mapping/*Mapper.xml"></property> </bean> <!--自動掃描映射接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定sql會話工廠,在上面配置過的 --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> <!-- 指定基礎包,即自動掃描com.zhangguo.Spring61.mapping這個包以及它的子包下的全部映射接口類 --> <property name="basePackage" value="com.zhangguo.Spring61.mapping"></property> </bean> <!--下面的配置暫時未使用 --> <context:component-scan base-package="com.zhangguo.Spring61"> </context:component-scan> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> </beans>
測試運行代碼以下:
package com.zhangguo.Spring61.test; import static org.junit.Assert.assertNotNull; import java.util.List; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; public class TestMyBatisSpring01 { @Test public void test01() { //初始化容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("ApplicationContext.xml"); //得到bean BookTypeDAO bookTypeDao=ctx.getBean(BookTypeDAO.class); //訪問數據庫 List<BookType> booktypes=bookTypeDao.getAllBookTypes(); for (BookType bookType : booktypes) { System.out.println(bookType); } assertNotNull(booktypes); } }
測試結果同第3階段,成功!
經過鏈接池能夠增長數據訪問的性能,由於訪問數據庫時創建鏈接與釋放鏈接是耗時操做,JDBC默認不帶鏈接池技術,但MyBatis是內置鏈接池功能的,還有一些第三方知名的鏈接池技術如:DBCP、C3P0、Druid(德魯伊)。
DBCP 是 Apache 軟件基金組織下的開源鏈接池實現,要使用DBCP數據源,須要應用程序應在系統中增長以下兩個 jar 文件:Commons-dbcp.jar:鏈接池的實現、Commons-pool.jar:鏈接池實現的依賴庫,經常使用屬性以下:
#鏈接設置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/jdbcstudy username=root password=XDP #<!-- 初始化鏈接 --> initialSize=10 #最大鏈接數量 maxActive=50 #<!-- 最大空閒鏈接 --> maxIdle=20 #<!-- 最小空閒鏈接 --> minIdle=5 #<!-- 超時等待時間以毫秒爲單位 6000毫秒/1000等於60秒 --> maxWait=60000 #JDBC驅動創建鏈接時附帶的鏈接屬性屬性的格式必須爲這樣:[屬性名=property;] #注意:"user" 與 "password" 兩個屬性會被明確地傳遞,所以這裏不須要包含他們。 connectionProperties=useUnicode=true;characterEncoding=UTF8 #指定由鏈接池所建立的鏈接的自動提交(auto-commit)狀態。 defaultAutoCommit=true #driver default 指定由鏈接池所建立的鏈接的只讀(read-only)狀態。 #若是沒有設置該值,則「setReadOnly」方法將不被調用。(某些驅動並不支持只讀模式,如:Informix) defaultReadOnly= #driver default 指定由鏈接池所建立的鏈接的事務級別(TransactionIsolation)。 #可用值爲下列之一:(詳情可見javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=READ_UNCOMMITTED
在與Spring整合時設置:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/hlp?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"></property> <property name="username" value="root"></property> <property name="password" value="1234"></property> <property name="maxActive" value="100"></property> <property name="maxIdle" value="30"></property> <property name="maxWait" value="500"></property> <property name="defaultAutoCommit" value="true"></property> </bean>
使用上面的代碼替換原數據源的建立。
C3P0是一個開源的JDBC鏈接池,它實現了數據源和JNDI綁定,支持JDBC3規範和JDBC2的標準擴展。目前使用它的開源項目有Hibernate,Spring等。C3P0數據源在項目開發中使用得比較多。dbcp沒有自動回收空閒鏈接的功能,而c3p0有自動回收空閒鏈接功能。
在pom.xml中添加依賴:
<!--c3p0 鏈接池 --> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency>
在與Spring整合時修改applicationContext.xml,設置以下:
<!--定義一個jdbc數據源,建立一個驅動管理數據源的bean --> <bean id="jdbcDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.uid}" /> <property name="password" value="${jdbc.pwd}" /> <property name="acquireIncrement" value="5"></property> <property name="initialPoolSize" value="10"></property> <property name="minPoolSize" value="5"></property> <property name="maxPoolSize" value="20"></property> </bean>
在測試的代碼中設置斷點,查看鏈接數,顯示結果以下:
關於c3p0屬性的細節與查看鏈接數據的方法請查看個人另外一篇文章:Hibernate整合C3P0實現鏈接池。 經常使用屬性以下:
<!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 --> <property name="acquireIncrement">3</property> <!--定義在從數據庫獲取新鏈接失敗後重復嘗試的次數。Default: 30 --> <property name="acquireRetryAttempts">30</property> <!--兩次鏈接中間隔時間,單位毫秒。Default: 1000 --> <property name="acquireRetryDelay">1000</property> <!--鏈接關閉時默認將全部未提交的操做回滾。Default: false --> <property name="autoCommitOnClose">false</property> <!--c3p0將建一張名爲Test的空表,並使用其自帶的查詢語句進行測試。若是定義了這個參數那麼 屬性preferredTestQuery將被忽略。你不能在這張Test表上進行任何操做,它將只供c3p0測試 使用。Default: null--> <property name="automaticTestTable">Test</property> <!--獲取鏈接失敗將會引發全部等待鏈接池來獲取鏈接的線程拋出異常。可是數據源仍有效 保留,並在下次調用getConnection()的時候繼續嘗試獲取鏈接。若是設爲true,那麼在嘗試 獲取鏈接失敗後該數據源將申明已斷開並永久關閉。Default: false--> <property name="breakAfterAcquireFailure">false</property> <!--當鏈接池用完時客戶端調用getConnection()後等待獲取新鏈接的時間,超時後將拋出 SQLException,如設爲0則無限期等待。單位毫秒。Default: 0 --> <property name="checkoutTimeout">100</property> <!--經過實現ConnectionTester或QueryConnectionTester的類來測試鏈接。類名需制定全路徑。 Default: com.mchange.v2.c3p0.impl.DefaultConnectionTester--> <property name="connectionTesterClassName"></property> <!--指定c3p0 libraries的路徑,若是(一般都是這樣)在本地便可得到那麼無需設置,默認null便可 Default: null--> <property name="factoryClassLocation">null</property> <!--Strongly disrecommended. Setting this to true may lead to subtle and bizarre bugs. (文檔原文)做者強烈建議不使用的一個屬性--> <property name="forceIgnoreUnresolvedTransactions">false</property> <!--每60秒檢查全部鏈接池中的空閒鏈接。Default: 0 --> <property name="idleConnectionTestPeriod">60</property> <!--初始化時獲取三個鏈接,取值應在minPoolSize與maxPoolSize之間。Default: 3 --> <property name="initialPoolSize">3</property> <!--最大空閒時間,60秒內未使用則鏈接被丟棄。若爲0則永不丟棄。Default: 0 --> <property name="maxIdleTime">60</property> <!--鏈接池中保留的最大鏈接數。Default: 15 --> <property name="maxPoolSize">15</property> <!--JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但因爲預緩存的statements 屬於單個connection而不是整個鏈接池。因此設置這個參數須要考慮到多方面的因素。 若是maxStatements與maxStatementsPerConnection均爲0,則緩存被關閉。Default: 0--> <property name="maxStatements">100</property> <!--maxStatementsPerConnection定義了鏈接池內單個鏈接所擁有的最大緩存statements數。Default: 0 --> <property name="maxStatementsPerConnection"></property> <!--c3p0是異步操做的,緩慢的JDBC操做經過幫助進程完成。擴展這些操做能夠有效的提高性能 經過多線程實現多個操做同時被執行。Default: 3--> <property name="numHelperThreads">3</property> <!--當用戶調用getConnection()時使root用戶成爲去獲取鏈接的用戶。主要用於鏈接池鏈接非c3p0 的數據源時。Default: null--> <property name="overrideDefaultUser">root</property> <!--與overrideDefaultUser參數對應使用的一個參數。Default: null--> <property name="overrideDefaultPassword">password</property> <!--密碼。Default: null--> <property name="password"></property> <!--定義全部鏈接測試都執行的測試語句。在使用鏈接測試的狀況下這個一顯著提升測試速度。注意: 測試的表必須在初始數據源的時候就存在。Default: null--> <property name="preferredTestQuery">select id from test where id=1</property> <!--用戶修改系統配置參數執行前最多等待300秒。Default: 300 --> <property name="propertyCycle">300</property> <!--因性能消耗大請只在須要的時候使用它。若是設爲true那麼在每一個connection提交的 時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable 等方法來提高鏈接測試的性能。Default: false --> <property name="testConnectionOnCheckout">false</property> <!--若是設爲true那麼在取得鏈接的同時將校驗鏈接的有效性。Default: false --> <property name="testConnectionOnCheckin">true</property> <!--用戶名。Default: null--> <property name="user">root</property> 在Hibernate(spring管理)中的配置: <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass"><value>oracle.jdbc.driver.OracleDriver</value></property> <property name="jdbcUrl"><value>jdbc:oracle:thin:@localhost:1521:Test</value></property> <property name="user"><value>Kay</value></property> <property name="password"><value>root</value></property> <!--鏈接池中保留的最小鏈接數。--> <property name="minPoolSize" value="10" /> <!--鏈接池中保留的最大鏈接數。Default: 15 --> <property name="maxPoolSize" value="100" /> <!--最大空閒時間,1800秒內未使用則鏈接被丟棄。若爲0則永不丟棄。Default: 0 --> <property name="maxIdleTime" value="1800" /> <!--當鏈接池中的鏈接耗盡的時候c3p0一次同時獲取的鏈接數。Default: 3 --> <property name="acquireIncrement" value="3" /> <property name="maxStatements" value="1000" /> <property name="initialPoolSize" value="10" /> <!--每60秒檢查全部鏈接池中的空閒鏈接。Default: 0 --> <property name="idleConnectionTestPeriod" value="60" /> <!--定義在從數據庫獲取新鏈接失敗後重復嘗試的次數。Default: 30 --> <property name="acquireRetryAttempts" value="30" /> <property name="breakAfterAcquireFailure" value="true" /> <property name="testConnectionOnCheckout" value="false" /> </bean> 編輯本段相關信息鏈接池配置(以Hibernate爲例) ########################### ### C3P0 Connection Pool### ########################### #hibernate.c3p0.max_size 2 #hibernate.c3p0.min_size 2 #hibernate.c3p0.timeout 5000 #hibernate.c3p0.max_statements 100 #hibernate.c3p0.idle_test_period 3000 #hibernate.c3p0.acquire_increment 2 #hibernate.c3p0.validate false 在hibernate.cfg.xml文件裏面加入以下的配置: <!-- 最大鏈接數 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 最小鏈接數 --> <property name="hibernate.c3p0.min_size">5</property> <!-- 得到鏈接的超時時間,若是超過這個時間,會拋出異常,單位毫秒 --> <property name="hibernate.c3p0.timeout">120</property> <!-- 最大的PreparedStatement的數量 --> <property name="hibernate.c3p0.max_statements">100</property> <!-- 每隔120秒檢查鏈接池裏的空閒鏈接 ,單位是秒--> <property name="hibernate.c3p0.idle_test_period">120</property> <!-- 當鏈接池裏面的鏈接用完的時候,C3P0一下獲取的新的鏈接數 --> <property name="hibernate.c3p0.acquire_increment">2</property> <!-- 每次都驗證鏈接是否可用 --> <property name="hibernate.c3p0.validate">true</property>
Druid首先是一個數據庫鏈接池,但它不只僅是一個數據庫鏈接池,它還包含一個ProxyDriver,一系列內置的JDBC組件庫,一個SQL Parser。阿里巴巴是一個重度使用關係數據庫的公司,咱們在生產環境中大量的使用Druid,經過長期在極高負載的生產環境中實際使用、修改和完善,讓Druid逐步發展成最好的數據庫鏈接池。Druid在監控、可擴展性、穩定性和性能方面都有明顯的優點。
在與Spring整合時設置:
<!-- 配置數據源,使用的是alibaba的Druid(德魯伊)數據源 --> <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${jdbc_url}" /> <property name="username" value="${jdbc_username}" /> <property name="password" value="${jdbc_password}" /> <!-- 初始化鏈接大小 --> <property name="initialSize" value="0" /> <!-- 鏈接池最大使用鏈接數量 --> <property name="maxActive" value="20" /> <!-- 鏈接池最大空閒 --> <property name="maxIdle" value="20" /> <!-- 鏈接池最小空閒 --> <property name="minIdle" value="0" /> <!-- 獲取鏈接最大等待時間 --> <property name="maxWait" value="60000" /> <!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> --> <property name="validationQuery" value="${validationQuery}" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="testWhileIdle" value="true" /> <!-- 配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一個鏈接在池中最小生存的時間,單位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="25200000" /> <!-- 打開removeAbandoned功能 --> <property name="removeAbandoned" value="true" /> <!-- 1800秒,也就是30分鐘 --> <property name="removeAbandonedTimeout" value="1800" /> <!-- 關閉abanded鏈接時輸出錯誤日誌 --> <property name="logAbandoned" value="true" /> <!-- 監控數據庫 --> <!-- <property name="filters" value="stat" /> --> <property name="filters" value="mergeStat" /> </bean>
使用上面的代碼替換原數據源的建立。
maven依賴方式:
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.20</version> </dependency>
github:https://github.com/alibaba/druid,阿里的其它開源框架:https://github.com/alibaba
Mybatis-Spring爲咱們提供了一個實現了SqlSession接口的SqlSessionTemplate類,它是線程安全的,能夠被多個Dao同時使用。同時它還跟Spring的事務進行了關聯,確保當前被使用的SqlSession是一個已經和Spring的事務進行綁定了的。並且它還能夠本身管理Session的提交和關閉。當使用了Spring的事務管理機制後,SqlSession還能夠跟着Spring的事務一塊兒提交和回滾。修改applicationContext.xml文件,增長一個bean。
SqlSessionTemplate 是 MyBatis-Spring 的核心。 這個類負責管理 MyBatis 的 SqlSession, 調用 MyBatis 的 SQL 方法, 翻譯異常。 SqlSessionTemplate 是線程安全的, 能夠被多個 DAO 所共享使用。
當調用 SQL 方法時, 包含從映射器 getMapper()方法返回的方法, SqlSessionTemplate 將會保證使用的 SqlSession 是和當前 Spring 的事務相關的。此外,它管理 session 的生命 週期,包含必要的關閉,提交或回滾操做。
SqlSessionTemplate 實現了 SqlSession 接口,這就是說,在代碼中無需對 MyBatis 的 SqlSession 進行替換。 SqlSessionTemplate 一般是被用來替代默認的 MyBatis 實現的 DefaultSqlSession , 由於模板能夠參與到 Spring 的事務中而且被多個注入的映射器類所使 用時也是線程安全的。相同應用程序中兩個類之間的轉換可能會引發數據一致性的問題。
SqlSessionTemplate 對象可使用 SqlSessionFactory 做爲構造方法的參數來建立。
<!-- 建立一個sqlSession對象 --> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <!--建立一個BTDImpl對象 --> <bean id="bTDImpl" class="com.zhangguo.Spring61.dao.BTDImpl"> <property name="sqlSession" ref="sqlSession"></property> </bean>
新增一個BTDImpl類,實現接口BookTypeDAO,具體以下:
package com.zhangguo.Spring61.dao; import java.util.List; import org.apache.ibatis.session.SqlSession; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; public class BTDImpl implements BookTypeDAO { private SqlSession sqlSession; public void setSqlSession(SqlSession sqlSession) { this.sqlSession = sqlSession; } @Override public List<BookType> getAllBookTypes() { return sqlSession.selectList("com.zhangguo.Spring61.mapping.BookTypeDAO.getAllBookTypes"); } }
使用Spring的依賴注入在DAO中直接使用SqlSessionTemplate來訪問數據庫了。
測試代碼:
package com.zhangguo.Spring61.test; import static org.junit.Assert.assertNotNull; import java.util.List; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.zhangguo.Spring61.dao.BTDImpl; import com.zhangguo.Spring61.entities.BookType; public class TestMyBatisSpring02 { @Test public void test01() { //初始化容器 ApplicationContext ctx=new ClassPathXmlApplicationContext("ApplicationContext.xml"); //得到bean BTDImpl bTDImpl=ctx.getBean("bTDImpl",BTDImpl.class); //訪問數據庫 List<BookType> booktypes=bTDImpl.getAllBookTypes(); for (BookType bookType : booktypes) { System.out.println(bookType); } assertNotNull(booktypes); } }
運行結果:
也能夠經過自動裝配實現,使配置更加簡單,在配置文件中能夠刪除「建立一個BTDImpl對象」這一段,在類BTDImpl中增長註解,代碼以下:
package com.zhangguo.Spring61.dao; import java.util.List; import javax.annotation.Resource; import org.apache.ibatis.session.SqlSession; import org.springframework.stereotype.Repository; import com.zhangguo.Spring61.entities.BookType; import com.zhangguo.Spring61.mapping.BookTypeDAO; @Repository public class BTDImpl implements BookTypeDAO { @Resource private SqlSession sqlSession; public void setSqlSession(SqlSession sqlSession) { this.sqlSession = sqlSession; } @Override public List<BookType> getAllBookTypes() { return sqlSession.selectList("com.zhangguo.Spring61.mapping.BookTypeDAO.getAllBookTypes"); } }
測試方法得到bean要修改爲:BTDImpl bTDImpl=ctx.getBean(BTDImpl.class);,運行結果同上。
實在太亂了,應你們的要求,打算在另一篇文章中再繼續寫。