简单介绍
环境搭建
![https://i-blog.csdnimg.cn/blog_migrate/4bf2adac339347d202329db2a70fbf2b.png](https://i-blog.csdnimg.cn/blog_migrate/4bf2adac339347d202329db2a70fbf2b.png)
![https://i-blog.csdnimg.cn/blog_migrate/3a91aae30933a898cc165d5ffb6efc6b.png](https://i-blog.csdnimg.cn/blog_migrate/3a91aae30933a898cc165d5ffb6efc6b.png)
![https://i-blog.csdnimg.cn/blog_migrate/a2c95346ba341d7c4f5aadb576c0ec2f.png](https://i-blog.csdnimg.cn/blog_migrate/a2c95346ba341d7c4f5aadb576c0ec2f.png)
![https://i-blog.csdnimg.cn/blog_migrate/22d01a358720ac79281f930f57927d03.png](https://i-blog.csdnimg.cn/blog_migrate/22d01a358720ac79281f930f57927d03.png)
![https://i-blog.csdnimg.cn/blog_migrate/e8ecec915836688a64c6fcdf91de33bc.png](https://i-blog.csdnimg.cn/blog_migrate/e8ecec915836688a64c6fcdf91de33bc.png)
![https://i-blog.csdnimg.cn/blog_migrate/71b3f7829f372434e380c766bd12a0c1.png](https://i-blog.csdnimg.cn/blog_migrate/71b3f7829f372434e380c766bd12a0c1.png)
![https://i-blog.csdnimg.cn/blog_migrate/f6a07977b546c20d310b5165f8380537.png](https://i-blog.csdnimg.cn/blog_migrate/f6a07977b546c20d310b5165f8380537.png)
![https://i-blog.csdnimg.cn/blog_migrate/a1d7fc1d267a68e6c5b3e6f153174187.png](https://i-blog.csdnimg.cn/blog_migrate/a1d7fc1d267a68e6c5b3e6f153174187.png)
![https://i-blog.csdnimg.cn/blog_migrate/ed6562ef6d17b5fa51ac58e3a59211c5.png](https://i-blog.csdnimg.cn/blog_migrate/ed6562ef6d17b5fa51ac58e3a59211c5.png)
![https://i-blog.csdnimg.cn/blog_migrate/4cb5bc1c7799fa64b23ba1cc0847149c.png](https://i-blog.csdnimg.cn/blog_migrate/4cb5bc1c7799fa64b23ba1cc0847149c.png)
![https://i-blog.csdnimg.cn/blog_migrate/8c2c313f8ebe6763485e12a0e8c61a2d.png](https://i-blog.csdnimg.cn/blog_migrate/8c2c313f8ebe6763485e12a0e8c61a2d.png)
![https://i-blog.csdnimg.cn/blog_migrate/ec2f4251c493bb660bd77f48351375dd.png](https://i-blog.csdnimg.cn/blog_migrate/ec2f4251c493bb660bd77f48351375dd.png)
![](https://i-blog.csdnimg.cn/blog_migrate/65fe313d261d6124e8c2281fe7a9da20.png)
复制代码
<%@ 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>
复制代码
在项目上右键选择“Run as”-> “Run on Server”运行项目,运行结果如下。
![](https://i-blog.csdnimg.cn/blog_migrate/9e5df85901f27f53028fb3122f5ef1f7.png)
二、使用MyBatis完成MySQL数据库访问
![](https://i-blog.csdnimg.cn/blog_migrate/b045d06a0d606b0cf81d7732f57b0de4.png)
<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>
引用结果:
![](https://i-blog.csdnimg.cn/blog_migrate/ef722da92cf83577f89458252f097f9c.png)
准备数据
打开MySQL数据库,创建一个表,这里以booktypes表为例。
![](https://i-blog.csdnimg.cn/blog_migrate/c42c8b3b95374298f6e754d46aeadea7.png)
/*
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', '船舶制造');
创建java Bean
在包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文件
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
2.6、实现数据访问功能
为了更加方便的复用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测试用例,如下所示:
![](https://i-blog.csdnimg.cn/blog_migrate/b8eff307d8f5162c09e534a38909ea86.png)
测试用例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);
}
}
整合log4j2
上面的测试虽然通过,但是有一个错误提示“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请求,及数据库向程序响应的结果就清楚了。
测试结果:
使用Spring4.X整合MyBatis3.X初级版
什么是:MyBatis-Spring?
MyBatis-Spring会帮助你将MyBatis代码无缝地整合到Spring中。使用这个类库中的类,Spring将会加载必要的MyBatis工厂类和session类。这个类库也提供一个简单的方式来注入MyBatis数据映射器和SqlSession到业务层的bean中。而且它也会处理事务,翻译MyBatis的异常到Spring的DataAccessException异常(数据访问异常,译者注)中。最终,它并不会依赖于MyBatis,Spring或MyBatis-Spring来构建应用程序代码。
修改pom.xml添加依赖
为了将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>
创建Spring上下文初始化配置文件
该文件取名为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);
}
}
运行结果:
![](https://i-blog.csdnimg.cn/blog_migrate/d43d27477bda5c3a26cb9ccddb691bd9.png)
Spring集成MyBatis升级版
去掉MyBatisCfg.xml配置文件
<!--创建一个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>
映射接口类自动扫描配置
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>
修改后的 applicationContext.xml文件内容如下
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);
}
}
数据源与连接池
通过连接池可以增加数据访问的性能,因为访问数据库时建立连接与释放连接是耗时操作,JDBC默认不带连接池技术,但MyBatis是内置连接池功能的,还有一些第三方知名的连接池技术如:DBCP、C3P0、Druid(德鲁伊)。Druid(德鲁伊)
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>
使用SqlSession
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 作为构造方法的参数来创建。
可以通过自动装配实现,使配置更加简单,在配置文件中可以删除“创建一个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");
}
}