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);,运行结果同上。
实在太乱了,应你们的要求,打算在另一篇文章中再继续写。