Spring整合Mybatis(配置事务两种方式)
前言
spring为什么要整合mybatis
Mybatis开发中所存在的问题
Spring整合Mybatis步骤
前言
我们在学习Spring整合的,肯定会有疑问Mybatis已经是一个单独的持久层框架了为什么还要与Spring整合。
Spring为什么要整合Mybatis
Spring是一个优秀的框架,他的优秀支持就是能整合所有程序员想要让他整合的框架,这里所说的持久成也不例外。
Spring整合Mybatis其主要目的就是为了简化开发
我们在所有开发中都会与持久层关联,用来永久存储数据。
1.在 JavaEE开发需要持久层进行数据库的访问操作
于是就有了一下数据库交互方式
2. JDBC Hibernate Mybatis进行持久开发过程存在大量的代码冗余
在出现问题之后,在Spring框架中得到了相应的解决
3. Spring基于模板设计模式对于上述的持久层技术进行了封装
Mybatis开发中所存在的问题
配置繁琐,代码冗余
技术都是建立在需求的基础上,新的技术也为了解决一些旧的问题。
我们在使用Mybatis进行持久化操作的时候,需要进行大量且重复的配置,既然有问题,在Spring整合Mybaits中得到了解决。
举个例子
<mappers>
<mapper resource="con.dao.xxxMapper"></mapper>
<mapper resource="con.dao.xxxMapper"></mapper>
</mappers>
代码冗余
每个映射类都需要指定,在平时写程序可能没有体会,但是在实际开发中,代码冗余度是很大的,这个映射在Mybatis中也得到了改善,可以使用<package name=""/>
但是在我们常用的设置别名的时候也会有体现,而Spring中把这些问题都已经解决,而且在其他方法也有很大的完善。
Spring整合Mybatis步骤
1,导入依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<!--导入junit测试坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.14.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.3</version>
</dependency>
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.11.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.18</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.7</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
</dependencies>
这里导入的都是Spring基本jar包,还有就是aop切面jar包,本次演示的第一种就是在配置文件中配置事务属性,而配置事务底层就是采用的切面编程,其他就是连接数据库的jar包还有连接池,和整合事务的jar包。
2,实体类
package com.pojo;
public class Student {
private int sid;
private String sname;
private String sex;
private int age;
private int cit;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getCit() {
return cit;
}
public void setCit(int cit) {
this.cit = cit;
}
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", cit=" + cit +
'}';
}
}
Dao层接口 StudentMapper
package com.dao;
import com.pojo.Student;
import java.util.List;
public interface StudentMapper {
//插入一条记录
Student StudentInsert(Student student);
}
3,StudentMapper.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.dao.StudentMapper">
<!--返回值为int可以省略-->
<select id="StudentInsert">
insert into student(sname,sex,age,cit) value(#{sname},#{sex},#{age},#{cit});
</select>
</mapper>
4,ServiceStudent接口
package com.service;
import com.pojo.Student;
import java.util.List;
public interface ServiceStudent {
Student save(Student student);
}
Spring整合Mybatis的事务用业务层
5,ServiceStudent实现类
package com.service;
import com.dao.StudentMapper;
import com.pojo.Student;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public class ServiceStudentImpl implements ServiceStudent {
//获取dao层接口
private StudentMapper studentMapper;
public StudentMapper getStudentMapper() {
return studentMapper;
}
public void setStudentMapper(StudentMapper studentMapper) {
this.studentMapper = studentMapper;
}
@Override
public Student save() {
return studentMapper.StudentInsert();
}
}
6,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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="db.properties"/>
<!--连接数据库这里读取的是配置文件-->
<!--连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<!--创建工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--指定实体类的包-->
<property name="typeAliasesPackage" value="com.pojo"/>
<!--指定映射文件的包,-->
<property name="mapperLocations" value="com/dao/*Mapper.xml"/>
</bean>
<!--Dao层实体类,这里还是实现的dao层,只是service通过调用dao层进行操作-->
<bean id="Scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.dao"/>
</bean>
<!--如果不整合事务,以上操作可以直接对数据库进行操作-->
<!--事务整合-->
<!--原始对象-->
<bean id="serviceStudent" class="com.service.ServiceStudentImpl">
<property name="studentMapper" ref="studentMapper"/>
</bean>
<!--额外功能-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--事务属性-->
<tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
<tx:attributes>
<tx:method name="Query" isolation="DEFAULT"/>
</tx:attributes>
</tx:advice>
<!---->
<!--切入点-->
<aop:config>
<aop:pointcut id="pc" expression="execution(* com.service.ServiceStudentImpl.Query(..))"/>
<!--组装-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
</aop:config>
</beans>
7,测试类
package com.dao.test;
import com.dao.StudentMapper;
import com.pojo.Student;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class StudentTest {
@Test
public void QueryStudent(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/ApplicationContext.xml");
StudentMapper studentMapper = (StudentMapper) ctx.getBean("studentMapper");
//这里的studentMapper是由配置文件指定包自动创建的与之配置文件名对应且首字母小写其他不变
List<Student> query =studentMapper.Query();
for(Student student : query){
System.out.println(student);
}
}
}
以上是Spring整合Mybatis和事务的配置开发
整合事务使用注解只需要在ServiceStudent实现类中添加@Transactional注解,配置文件由下
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:advice="http://www.springframework.org/schema/aop" xmlns:aop="http://www.springframework.org/schema/aop"
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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<!--连接池-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</bean>
<!--创建实例工厂-->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.pojo"/>
<property name="mapperLocations" value="classpath:com/dao/*Mapper.xml"/>
</bean>
<!--Dao接口实体类-->
<bean id="Scanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="SqlSessionFactory"/>
<property name="basePackage" value="com.dao"/>
</bean>
<!--spring整合事务-->
<!--原始对象-->
<bean id="serviceStudent" class="com.service.ServiceStudentImpl">
<property name="studentMapper" ref="studentMapper"/>
</bean>
<!--额外功能-->
<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--切入点-->
<!--
@Transactional
public class ServiceStudentImpl implements ServiceStudent {
-->
<!--组装切面-->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
</beans>
两种方式除了业务层实现类多加了个注解还有配置文件不同其他都是一样的。
这就是Spring整合Mybatis并且整合事务的全部流程,可能初学者对配置事务属性的地方有疑问,是根据事务的五个属性进行配置的,分别是
1. 隔离属性(isolation)
2. 传播属性(Propagation)
3. 只读属性(readOnly)
4. 超时属性(timeout)
5. 异常属性
它们与之都有对应的属性值。
其他内容
学习不是即学即用,而是用的时候已经掌握。
Java学习之初疑问
Markdown基本语法
MySQL设置级联操作
Spring工厂实现