Spring 学习小记(七)
Spring集成MyBatis
本小记中学习目标
1. MyBatis简介
2.MyBatis工作原理介绍
3.MyBaits的入门程序开发介绍
4.Spring框架整合MyBatis
一、MyBatis简介
历史由来:Apache的开源项目iBatis---->2010年,迁移至Google Code,更名为MyBatis
MyBatis是一个基于java的持久层框架,这个框架包含SQL Maps、Data Access Objects(DAO)。它基本上消除了几乎所有的JDBC代码和参数手工设置及结果集的检索。使用简单的xml或注解来做配置和原始映射,把接口和java的POJO(java对象)映射成数据库中的记录
常见的Java持久层框架有Hibernate、MyBatis,其中MyBatis是一个半自动的映射框架,需要手动匹配pojo、SQL和映射关系,然而Hibernate是一个全表映射的框架,只需要提供pojo和映射关系就可以了。它们两者各自己的优点如下,在使用时需要根据实际项目情况做选择
MyBatis:小巧、方便、高效、简单、直接、半自动化
Hibernate:强大、方便、高效、复杂、间接、全自动化
二、MyBatis工作原理介绍
MyBatis框架执行流程图
从上图中所示的框架执行流程图进行说明
(1)读取MyBatis配置文件,mybatis-config.xml
这个配置文件是MyBatis的全局配置文件,配置MyBatis的运行环境等相关信息,对于数据库的连接信息也需要配置在这里
(2)加载映射文件,这里的映射文件指的是Sql映射文件,这个文件中配置了操作数据库的Sql语句,需要在mybatis-config.xml中加载,在全局的配置文件中可以加载多个映射文件,每一个映射文件对应数据库中的一张数据表
(3)构造会话工厂,SqlSessionFactory,构造会话工厂时是根据前面提到的全局配置信息来进行构造
(4)创建会话对象,SqlSession,由会话工厂来创建,这个对象包含了执行SQL语句的所有方法
(5)Executor执行器,在MyBatis的底层定义了一个Executor接口来操作数据库,它把SqlSessionw传递的参数动态生成需要执行的Sql语句。同时它也会负责查询缓存的维护
(6)MappedStatement对象,在Executor接口的执行方法中有一个MappedStatement类型的参数,这个参数是对映射信息的封装,用于存储映射的Sql语句的id,参数等相关信息
(7)输入参数映射,这个过程相当于JDBC中对preparedStatement对象设置参数的过程
(8)输出映射结果,这个过程相当于JDBC对结果集的解析过程
三、MyBatis入门程序开发介绍
下面以一个最基础的实例来对MyBatis的入门程序开发进行说明
实例
1.创建一个Maven 的jar工程
2.导入相关的依赖,在pom.xml文件中添加如下内容
<
dependencies
>
<!--
mybatis
-->
<
dependency
>
<
groupId
>org.mybatis
</
groupId
>
<
artifactId
>
mybatis
</
artifactId
>
<
version
>3.4.5
</
version
>
</
dependency
>
<!--
mysql
-connector-java -->
<
dependency
>
<
groupId
>
mysql
</
groupId
>
<
artifactId
>
mysql-connector-java
</
artifactId
>
<
version
>5.1.45
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>log4j
</
groupId
>
<
artifactId
>log4j
</
artifactId
>
<
version
>1.2.17
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.apache.logging.log4j
</
groupId
>
<
artifactId
>log4j-core
</
artifactId
>
<
version
>2.3
</
version
>
</
dependency
>
</
dependencies
>
3.由于需要在控制台中打印MyBatis的执行SQL的目志,需要配置日志文件的配置文件(
注意:log4j2只支持xml或json的本配置,对于properties的配置文件不起作用)
在classpath的路径下新增一个log4j2的配置文件log4j2.xml
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
Configuration
status=
"WARN"
>
<
Appenders
>
<
Console
name=
"Console"
target=
"SYSTEM_OUT"
>
<
PatternLayout
pattern=
"[%t] %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"
/>
</
Console
>
</
Appenders
>
<
Loggers
>
<
Root
level=
"DEBUG"
>
<
AppenderRef
ref=
"Console"
/>
</
Root
>
<
logger
name=
"java.sql"
level=
"DEBUG"
></
logger
>
<
logger
name=
"org.apache.ibatis"
level=
"INFO"
></
logger
>
</
Loggers
>
</
Configuration
>
4.建立一个pojo的实体类它与数据库中表对应
package com.xiaoxie.pojo;
public
class Student {
private Integer
id;
private String
name;
private Integer
age;
//getter和setter方法
public Integer getId() {
return
id;
}
public
void setId(Integer
id) {
this.
id =
id;
}
public String getName() {
return
name;
}
public
void setName(String
name) {
this.
name =
name;
}
public Integer getAge() {
return
age;
}
public
void setAge(Integer
age) {
this.
age =
age;
}
public String toString() {
return
"Student[id="+
id+
",name="+
name+
",age="+
age+
"]";
}
}
5.建立MyBatis的映射文件,com.xiaoxie.dao.mybatis.StudentMapper.xml
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<!
DOCTYPE
mapper
<
mapper
namespace=
"com.xiaoxie.dao.mybatis.StudentMapper"
>
<!-- 根据ID查找一个student信息 -->
<
select
id=
"selectStudentById"
parameterType=
"Integer"
resultType=
"com.xiaoxie.pojo.Student"
>
select id,name,age from student where id = #{id}
</
select
>
<!-- 查询所有student信息 -->
<
select
id=
"selectAllStudent"
resultType=
"com.xiaoxie.pojo.Student"
>
select id,name,age from student
</
select
>
<!-- 获取ID最的一条记录 -->
<
select
id=
"selectMaxIdStudent"
resultType=
"com.xiaoxie.pojo.Student"
>
select id,name,age from student order by id
desc limit 1
</
select
>
<!-- 添加一个student信息 -->
<
insert
id=
"addStudent"
parameterType=
"com.xiaoxie.pojo.Student"
>
insert into student(name,age) values(#{name},#{age})
</
insert
>
<!-- 修改一个student信息 -->
<
update
id=
"updateStudent"
parameterType=
"com.xiaoxie.pojo.Student"
>
update student set name = #{name},age = #{age} where id = #{id}
</
update
>
<
delete
id=
"deleteStudent"
parameterType=
"com.xiaoxie.pojo.Student"
>
delete from student where id = #{id}
</
delete
>
</
mapper
>
映射文件中则指定了,要执行的sql语句,相关参数与实体类的对应,返回结果与实体类的对应
6.新增MyBatis的全局配置文件mybatis-config.xml(在classpath路行径下)
<?
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
>
<!-- 配置环境 -->
<
environments
default=
"development"
>
<
environment
id=
"development"
>
<!-- 使用JDBC的事务管理 -->
<
transactionManager
type=
"JDBC"
/>
<
dataSource
type=
"POOLED"
>
<!--
mysql
数据库驱动 -->
<
property
name=
"driver"
value=
"com.mysql.jdbc.Driver"
/>
<!-- 数据库连接信息 -->
<
property
name=
"url"
value=
"jdbc:
mysql://localhost:3306/test?characterEncoding=utf8
"
/>
<
property
name=
"username"
value=
"root"
/>
<
property
name=
"password"
value=
"root"
/>
</
dataSource
>
</
environment
>
</
environments
>
<!-- 映射文件 -->
<
mappers
>
<
mapper
resource=
"com/xiaoxie/dao/mybatis/StudentMapper.xml"
/>
</
mappers
>
</
configuration
>
主要完成两类事情:环境的配置(datasource配置)、加入对应的映射文件
7.新增测试类及测试方法
private
static
void testMyBaties1() {
try {
//读取MyBatis全局的配置文件
InputStream
config = Resources.
getResourceAsStream(
"mybatis-config.xml");
//构建SqlSessionFactory
SqlSessionFactory
ssf =
new SqlSessionFactoryBuilder().build(
config);
//通过SqlSessionFactory来创建SqlSession
SqlSession
ss =
ssf.openSession();
System.
out.println(
"--------根据id查找一条记录--------");
//查找一条记录
//com.xiaoxie.dao.mybatis.StudentMapper
String
base_str =
"com.xiaoxie.dao.mybatis.StudentMapper.";
Student
student =
ss.selectOne(
base_str +
"selectStudentById",12);
System.
out.println(
student);
System.
out.println(
"------------添加一条记录----------");
//添加一条记录
//创建一个Student对象
Student
s =
new Student();
s.setName(
"马超");
s.setAge(22);
ss.insert(
base_str +
"addStudent",
s);
System.
out.println(
"-----------修改一条记录----------");
//修改一条记录
student.setAge(39);
ss.update(
base_str +
"updateStudent",
student);
System.
out.println(
"-----------删除一条记录----------");
//删除一条记录,删除最大ID的记录
Student
maxIdStudent =
ss.selectOne(
base_str +
"selectMaxIdStudent");
ss.delete(
base_str +
"deleteStudent",
maxIdStudent);
System.
out.println(
"-----------查找所有记录----------");
//查找所有记录
List<Student>
students =
ss.selectList(
base_str +
"selectAllStudent");
for (Student
stu :
students) {
System.
out.println(
stu);
}
//提交事务
ss.commit();
//关闭SqlSession
ss.close();
}
catch (IOException
e) {
//
TODO
Auto-generated catch block
e.printStackTrace();
}
}
8.在测试类的main方法中调用上面的方法,在控制台打印结果如下
--------根据id查找一条记录--------
[main] 16:25:43.727 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectStudentById - ==> Preparing: select id,name,age from student where id = ?
[main] 16:25:43.783 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectStudentById - ==> Parameters: 12(Integer)
[main] 16:25:43.824 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectStudentById - <== Total: 1
Student[id=12,name=黄忠,age=33]
------------添加一条记录----------
[main] 16:25:43.826 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.addStudent - ==> Preparing: insert into student(name,age) values(?,?)
[main] 16:25:43.828 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.addStudent - ==> Parameters: 马超(String), 22(Integer)
[main] 16:25:43.829 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.addStudent - <== Updates: 1
-----------修改一条记录----------
[main] 16:25:43.830 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.updateStudent - ==> Preparing: update student set name = ?,age = ? where id = ?
[main] 16:25:43.831 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.updateStudent - ==> Parameters: 黄忠(String), 39(Integer), 12(Integer)
[main] 16:25:43.832 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.updateStudent - <== Updates: 1
-----------删除一条记录----------
[main] 16:25:43.832 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectMaxIdStudent - ==> Preparing: select id,name,age from student order by id desc limit 1
[main] 16:25:43.832 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectMaxIdStudent - ==> Parameters:
[main] 16:25:43.834 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectMaxIdStudent - <== Total: 1
[main] 16:25:43.834 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.deleteStudent - ==> Preparing: delete from student where id = ?
[main] 16:25:43.835 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.deleteStudent - ==> Parameters: 16(Integer)
[main] 16:25:43.835 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.deleteStudent - <== Updates: 1
-----------查找所有记录----------
[main] 16:25:43.835 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectAllStudent - ==> Preparing: select id,name,age from student
[main] 16:25:43.836 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectAllStudent - ==> Parameters:
[main] 16:25:43.839 DEBUG com.xiaoxie.dao.mybatis.StudentMapper.selectAllStudent - <== Total: 6
Student[id=1,name=刘备,age=30]
Student[id=2,name=关公,age=29]
Student[id=3,name=张飞,age=26]
Student[id=10,name=诸葛亮,age=25]
Student[id=11,name=赵云,age=23]
Student[id=12,name=黄忠,age=39]
四、Spring框架整合MyBatis
Spring框架整合MyBatis,我们使用一个简单的实例进行说明
实例:
1.新增一个Maven的jar工程,在pom.xml中导入相应的jar包
<
dependencies
>
<!-- 添加Spring核心依赖包 Context -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-context
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!--
mybatis
-->
<
dependency
>
<
groupId
>org.mybatis
</
groupId
>
<
artifactId
>
mybatis
</
artifactId
>
<
version
>3.4.5
</
version
>
</
dependency
>
<!--
mysql
-connector-java -->
<
dependency
>
<
groupId
>
mysql
</
groupId
>
<
artifactId
>
mysql-connector-java
</
artifactId
>
<
version
>5.1.45
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>log4j
</
groupId
>
<
artifactId
>log4j
</
artifactId
>
<
version
>1.2.17
</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.apache.logging.log4j
</
groupId
>
<
artifactId
>log4j-core
</
artifactId
>
<
version
>2.3
</
version
>
</
dependency
>
<!-- spring-
jdbc
-->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-
jdbc
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!--
aspectjweaver
-->
<
dependency
>
<
groupId
>org.aspectj
</
groupId
>
<
artifactId
>
aspectjweaver
</
artifactId
>
<
version
>1.8.13
</
version
>
</
dependency
>
<!-- spring-aspects -->
<
dependency
>
<
groupId
>org.springframework
</
groupId
>
<
artifactId
>spring-aspects
</
artifactId
>
<
version
>5.0.2.RELEASE
</
version
>
</
dependency
>
<!--
aopalliance
-->
<
dependency
>
<
groupId
>
aopalliance
</
groupId
>
<
artifactId
>
aopalliance
</
artifactId
>
<
version
>1.0
</
version
>
</
dependency
>
<!--
mybatis
-spring -->
<
dependency
>
<
groupId
>org.mybatis
</
groupId
>
<
artifactId
>
mybatis-spring
</
artifactId
>
<
version
>1.3.1
</
version
>
</
dependency
>
<!-- commons-dbcp2 -->
<
dependency
>
<
artifactId
>commons-dbcp2
</
artifactId
>
<
version
>2.2.0
</
version
>
</
dependency
>
<!-- commons-pool2 -->
<
dependency
>
<
artifactId
>commons-pool2
</
artifactId
>
<
version
>2.5.0
</
version
>
</
dependency
>
</
dependencies
>
从上面可以看到有几个注意事项:第一,整合时需要导入MyBatis与Spring的中间包mybatis-spring-x.x.x.jar;第二,整合时使用了DBCP数据源管理;第三,连接池使用了commons-pool
2.创建持久化的类POJO,这个实体类与数据库中相应的表对应com.xiaoxie.pojo.Student
package com.xiaoxie.pojo;
public
class Student {
private Integer
id;
private String
name;
private Integer
age;
public Student() {}
public Student(String
name,Integer
age) {
this.
name =
name;
this.
age =
age;
}
//getter和setter方法
public Integer getId() {
return
id;
}
public
void setId(Integer
id) {
this.
id =
id;
}
public String getName() {
return
name;
}
public
void setName(String
name) {
this.
name =
name;
}
public Integer getAge() {
return
age;
}
public
void setAge(Integer
age) {
this.
age =
age;
}
public String toString() {
return
"Student[id="+
id+
",name="+
name+
",age="+
age+
"]";
}
}
3.建立实体类与数据库表的映射文件com.xoaoxie.dao.mybatis.StudentMapper.xml
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<!
DOCTYPE
mapper
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
<
mapper
namespace=
"com.xiaoxie.dao.StudentDao"
>
<!-- 根据id查询一条记录 -->
<
select
id=
"selectStudentById"
parameterType=
"Integer"
resultType=
"com.xiaoxie.pojo.Student"
>
select id,name,age from student where 1=1 and id=#{id}
</
select
>
<!-- 查询所有记录 -->
<
select
id=
"selectAllStudent"
resultType=
"com.xiaoxie.pojo.Student"
>
select id,name,age from student
</
select
>
<!-- 添加一条记录 -->
<
insert
id=
"addStudent"
parameterType=
"com.xiaoxie.pojo.Student"
>
insert into student(name,age) values(#{name},#{age})
</
insert
>
<!-- 修改一条记录 -->
<
update
id=
"updateStudentById"
parameterType=
"com.xiaoxie.pojo.Student"
>
update student set name=#{name},age=#{age} where 1=1 and id=#{id}
</
update
>
<!-- 查找当前表中最大ID -->
<
select
id=
"selectMaxIdFromTable"
resultType=
"Integer"
>
select id from student order by id
desc limit 1
</
select
>
<!-- 删除一条记录 -->
<
delete
id=
"deleteStudentById"
parameterType=
"Integer"
>
delete from student where id=#{id}
</
delete
>
</
mapper
>
在这里定义需要执行的sql语句
4.在类路径下新增MyBatis的全局配置文件mybatis-config.xml
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<!
DOCTYPE
configuration
PUBLIC
"-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"
>
<
configuration
>
<!-- 查找映射文件 -->
<
mappers
>
<
mapper
resource=
"com/xiaoxie/dao/mybatis/StudentMapper.xml"
/>
</
mappers
>
</
configuration
>
注意:这里只需要把映射文件指定进去即可
5.创建一个Dao接口:com.xiaoxie.dao.StudentDao
package com.xiaoxie.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import com.xiaoxie.pojo.Student;
@Repository(
"studentDao")
@Mapper
public
interface StudentDao {
/*接口中的方法必须要保持与映射文件中一致*/
//根据id查找一条记录
Student selectStudentById(Integer
id);
//查询所有的记录
List<Student> selectAllStudent();
//添加一条记录
int addStudent(Student
student);
//更新一条记录
int updateStudentById(Student
student);
//查找表记录中最大Id
Integer selectMaxIdFromTable();
//删除一条记录
int deleteStudentById(Integer
id);
}
注意:这里要使用@Mapper注解,接口中的方法要与前面定义的Mapper配置文件中指定的sql执行的id一致
6.创建一个Controller的实现类com.xiaoxie.controller.StudentController
package com.xiaoxie.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import com.xiaoxie.dao.StudentDao;
import com.xiaoxie.pojo.Student;
@Transactional
@Controller(
"studentController")
public
class StudentController {
@Autowired
private StudentDao
studentDao;
public
void operation() {
//查找一条记录
System.
out.println(
"----------------根据ID查找一条记录---------------");
Student
stu =
studentDao.selectStudentById(10);
System.
out.println(
"查找信息Age:" +
stu.getAge());
System.
out.println(
"=====================查找记录完成================");
//添加一条记录
System.
out.println(
"-------------------添加一条记录------------------");
int
rows =
studentDao.addStudent(
new Student(
"刘备",30));
System.
out.println(
"===============添加"+
rows +
"条记录==============");
//添加一条记录
System.
out.println(
"-------------------添加一条记录------------------");
rows =
studentDao.addStudent(
new Student(
"马超",20));
System.
out.println(
"===============添加"+
rows +
"条记录==============");
//修改一条记录
System.
out.println(
"-------------------更新一条记录------------------");
stu.setAge(
stu.getAge() + 3);
rows =
studentDao.updateStudentById(
stu);
System.
out.println(
"===============修改"+
rows +
"条记录==============");
//删除一条记录
System.
out.println(
"-------------------删除一条记录------------------");
//查找当前表中最大id记录
Integer
maxId =
studentDao.selectMaxIdFromTable();
studentDao.deleteStudentById(
maxId);
//studentDao.deleteStudentById(stu.getId());
System.
out.println(
"===============删除"+
rows +
"条记录==============");
//查看所有记录
System.
out.println(
"-------------------查找所有记录------------------");
List<Student>
selectAllStudent =
studentDao.selectAllStudent();
for (Student
student :
selectAllStudent) {
System.
out.println(
student);
}
System.
out.println(
"=====================查找记录完成================");
}
}
注意:这里要指定事务,如果不指定则对于事务相关的操作(修改、删除)不会生效,执行时会提示:Closing non transactional SqlSession
7.在执行方法时为了可以看到执行的日志,需要添加日志打印的配置文件log4j2.xml
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
<
Configuration
status=
"WARN"
>
<
Appenders
>
<
Console
name=
"Console"
target=
"SYSTEM_OUT"
>
<
PatternLayout
pattern=
"[%t] %d{HH:mm:ss.SSS} %-5level - %msg%n"
/>
</
Console
>
</
Appenders
>
<
Loggers
>
<
Root
level=
"DEBUG"
>
<
AppenderRef
ref=
"Console"
/>
</
Root
>
<
logger
name=
"java.sql"
level=
"DEBUG"
></
logger
>
<
logger
name=
"org.apache.ibatis"
level=
"INFO"
></
logger
>
</
Loggers
>
</
Configuration
>
8.配置spring的xml配置文件
<?
xml
version=
"1.0"
encoding=
"UTF-8"
?>
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:context=
"http://www.springframework.org/schema/context"
xmlns:tx=
"http://www.springframework.org/schema/tx"
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/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"
>
<!-- 指定Spring需要扫描的包 -->
<
context:component-scan
base-package=
"com.xiaoxie.dao"
/>
<
context:component-scan
base-package=
"com.xiaoxie.controller"
/>
<!-- 配置数据源 -->
<
property
name=
"
driverClassName"
value=
"com.mysql.jdbc.Driver"
/>
<
property
name=
"
url"
value=
"jdbc:mysql://localhost:3306/test?characterEncoding=utf8"
/>
<
property
name=
"
username"
value=
"root"
/>
<
property
name=
"
password"
value=
"root"
/>
<!-- 最大连接数 -->
<
property
name=
"
maxTotal"
value=
"30"
/>
<!-- 最大空闲连接数 -->
<
property
name=
"
maxIdle"
value=
"10"
/>
<!-- 初始化连接数 -->
<
property
name=
"
initialSize"
value=
"5"
/>
</
bean
>
<!-- 添加事务支持 -->
<
bean
class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"
id=
"tranManager"
>
<
property
name=
"
dataSource"
ref=
"dataSource"
/>
</
bean
>
<!-- 开启事务注解 -->
<
tx:annotation-driven
transaction-manager=
"tranManager"
/>
<!-- 配置MyBatis -->
<
bean
class=
"org.mybatis.spring.SqlSessionFactoryBean"
id=
"sqlSessionFactory"
>
<!-- 指定数据源 -->
<
property
name=
"
dataSource"
ref=
"dataSource"
/>
<!-- MyBatis的全局配置文件 -->
<
property
name=
"
configLocation"
value=
"mybatis-config.xml"
/>
</
bean
>
<!-- Spring自动扫描MyBatis并进行装配 -->
<
bean
class=
"org.mybatis.spring.mapper.MapperScannerConfigurer"
>
<!-- 指定需要扫描的包,这里只需要到接口,接口中的方法与
mybatis
映射文件中指定的相同 -->
<
property
name=
"
basePackage"
value=
"com.xiaoxie.dao"
/>
<
property
name=
"
sqlSessionFactoryBeanName"
value=
"sqlSessionFactory"
/>
</
bean
>
</
beans
>
注意:这里有配置点:第一,使用注解需要指定spring扫描的包;第二,配置数据源;第三,开启对数据源的事务支持(不开启则会对于有事务的操作不生效);第四,配置MyBatis的SqlSessionFactoryBean;第五,配置Spring自动扫描MyBatis并进行装配
9.建立测试类com.xiaoxie.test.Application,并在其中main方法中调用controller中的方法
package com.xiaoxie.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xiaoxie.controller.StudentController;
public
class Application {
public
static
void main(String[]
args) {
ApplicationContext
context =
new ClassPathXmlApplicationContext(
"spring-config.xml");
StudentController
sc = (StudentController)
context.getBean(
"studentController");
sc.operation();
}
}
10.运行测试类,控制台打印的关键信息如下
----------------根据ID查找一条记录---------------
[main] 23:53:45.374 DEBUG - Creating a new SqlSession
[main] 23:53:45.380 DEBUG - Registering transaction synchronization for SqlSession [[email protected]]
[main] 23:53:45.390 DEBUG - JDBC Connection [2030458766, URL=jdbc:mysql://localhost:3306/test?characterEncoding=utf8, [email protected], MySQL Connector Java] will be managed by Spring
[main] 23:53:45.403 DEBUG - ==> Preparing: select id,name,age from student where 1=1 and id=?
[main] 23:53:45.444 DEBUG - ==> Parameters: 10(Integer)
[main] 23:53:45.475 DEBUG - <== Total: 1
[main] 23:53:45.479 DEBUG - Releasing transactional SqlSession [[email protected]]
查找信息Age:23
=====================查找记录完成================
-------------------添加一条记录------------------
[main] 23:53:45.479 DEBUG - Fetched SqlSession [[email protected]] from current transaction
[main] 23:53:45.479 DEBUG - ==> Preparing: insert into student(name,age) values(?,?)
[main] 23:53:45.481 DEBUG - ==> Parameters: 刘备(String), 30(Integer)
[main] 23:53:45.482 DEBUG - <== Updates: 1
[main] 23:53:45.483 DEBUG - Releasing transactional SqlSession [[email protected]]
===============添加1条记录==============
-------------------添加一条记录------------------
[main] 23:53:45.483 DEBUG - Fetched SqlSession [[email protected]] from current transaction
[main] 23:53:45.483 DEBUG - ==> Preparing: insert into student(name,age) values(?,?)
[main] 23:53:45.483 DEBUG - ==> Parameters: 马超(String), 20(Integer)
[main] 23:53:45.484 DEBUG - <== Updates: 1
[main] 23:53:45.484 DEBUG - Releasing transactional SqlSession [[email protected]]
===============添加1条记录==============
-------------------更新一条记录------------------
[main] 23:53:45.484 DEBUG - Fetched SqlSession [[email protected]] from current transaction
[main] 23:53:45.484 DEBUG - ==> Preparing: update student set name=?,age=? where 1=1 and id=?
[main] 23:53:45.485 DEBUG - ==> Parameters: 诸葛亮(String), 26(Integer), 10(Integer)
[main] 23:53:45.485 DEBUG - <== Updates: 1
[main] 23:53:45.485 DEBUG - Releasing transactional SqlSession [[email protected]]
===============修改1条记录==============
-------------------删除一条记录------------------
[main] 23:53:45.486 DEBUG - Fetched SqlSession [[email protected]] from current transaction
[main] 23:53:45.486 DEBUG - ==> Preparing: select id from student order by id desc limit 1
[main] 23:53:45.486 DEBUG - ==> Parameters:
[main] 23:53:45.490 DEBUG - <== Total: 1
[main] 23:53:45.491 DEBUG - Releasing transactional SqlSession [[email protected]]
[main] 23:53:45.491 DEBUG - Fetched SqlSession [[email protected]] from current transaction
[main] 23:53:45.492 DEBUG - ==> Preparing: delete from student where id=?
[main] 23:53:45.492 DEBUG - ==> Parameters: 25(Integer)
[main] 23:53:45.492 DEBUG - <== Updates: 1
[main] 23:53:45.493 DEBUG - Releasing transactional SqlSession [[email protected]]
===============删除1条记录==============
-------------------查找所有记录------------------
[main] 23:53:45.493 DEBUG - Fetched SqlSession [[email protected]] from current transaction
[main] 23:53:45.493 DEBUG - ==> Preparing: select id,name,age from student
[main] 23:53:45.494 DEBUG - ==> Parameters:
[main] 23:53:45.496 DEBUG - <== Total: 6
[main] 23:53:45.496 DEBUG - Releasing transactional SqlSession [[email protected]]
Student[id=2,name=关公,age=29]
Student[id=3,name=张飞,age=26]
Student[id=10,name=诸葛亮,age=26]
Student[id=11,name=赵云,age=23]
Student[id=12,name=黄忠,age=35]
Student[id=24,name=刘备,age=30]
=====================查找记录完成================
[main] 23:53:45.497 DEBUG - Transaction synchronization committing SqlSession [[email protected]]
[main] 23:53:45.497 DEBUG - Transaction synchronization deregistering SqlSession [[email protected]]
[main] 23:53:45.497 DEBUG - Transaction synchronization closing SqlSession [[email protected]]
[main] 23:53:45.497 DEBUG - Initiating transaction commit
[main] 23:53:45.498 DEBUG - Committing JDBC transaction on Connection [2030458766, URL=jdbc:mysql://localhost:3306/test?characterEncoding=utf8, [email protected], MySQL Connector Java]
[main] 23:53:45.503 DEBUG - Releasing JDBC Connection [2030458766, URL=jdbc:mysql://localhost:3306/test?characterEncoding=utf8, [email protected], MySQL Connector Java] after transaction
[main] 23:53:45.503 DEBUG - Returning JDBC Connection to DataSource
从上面的程序中我们可以看到当使用Spring整合MyBatis后,不需要再去做创建SqlSession的操作、事务的处理了,在方法中只需要处理业务逻辑即可。因为在spring的配置文件中对于指定dao包下的接口进行自动扫描MyBatis并进行装配,上面的整合比较麻烦的地方则在于我们配置了Mapper映射后同时还要再定义一个dao的接口与之对应