目录
- 1.Spring的事务
- 1.1 什么是事务?
- 1.2 事务的特性(ACID)
- 1.3 Spring 事务实现方式有哪些?
- 1.4 Spring事务管理接口介绍
- 1.4.1 PlatformTransactionManager:事务管理接口
- 1.4.2 TransactionDefinition:事务属性事务管理器接口
- 1.4.3 TransactionStatus:事务状态
- 2.事务入门案例
- 3.动态代理控制事务
- 4.Spring AOP控制事务
- 5. 基于注解的AOP控制事务
- 5.1 @Transactional 注解使用详解
- 5.2 使用注解控制事务
- 6.Spring整合MyBatis
- 6.1 创建工程
- 6.2 配置数据源
- 6.3 整合MyBatis
- 6.4 测试
1.Spring的事务
1.1 什么是事务?
需要一次执行多条SQL语句时,可以使用事务。通俗一点说,如果这几条SQL语句全部执行成功,则才对数据库进行一次更新,如果有一条SQL语句执行失败,则这几条SQL语句全部不进行执行,即要么都执行,要么都不执行。这个时候需要用到事务。
1.2 事务的特性(ACID)
- 原子性(Atomicity):事务是最小的执行单位,不允许分割。事务的原子性确保动作要么全部完成,要么完全不起作用;
- 一致性(Consistency):执行事务前后,数据保持一致,例如转账业务中,无论事务是否成功,转账者和收款人的总额应该是不变的;
- 隔离性(Isolation):并发访问数据库时,一个用户的事务不被其他事务所干扰,各并发事务之间数据库是独立的;
- 持久性(Durability):一个事务被提交之后。它对数据库中数据的改变是持久的,即使数据库发生故障也不应该对其有任何影响。
1.3 Spring 事务实现方式有哪些?
Spring事务机制主要包括声明式事务和编程式事务。
- 编程式事务:通过编程的方式管理事务,这种方式带来了很大的灵活性,但很难维护。
- 声明式事务:将事务管理代码从业务方法中分离出来,通过aop进行封装。Spring声明式事务使得我们无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。使用 @Transactional 注解开启声明式事务。
1.4 Spring事务管理接口介绍
Spring 框架中,事务管理相关最重要的 3 个接口如下:
PlatformTransactionManager
:(平台)事务管理器,Spring 事务策略的核心。TransactionDefinition
:事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)。TransactionStatus
:事务运行状态。
1.4.1 PlatformTransactionManager:事务管理接口
Spring 并不直接管理事务,而是提供了多种事务管理器 。
Spring 事务管理器的接口是:PlatformTransactionManager 。
通过这个接口,Spring 为各个平台如:JDBC(DataSourceTransactionManager)、Hibernate(HibernateTransactionManager)、JPA(JpaTransactionManager)等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。
PlatformTransactionManager接口中定义了三个方法:
public interface PlatformTransactionManager {
//开启事务
TransactionStatus getTransaction(TransactionDefinition definition)
throws TransactionException;
//提交事务
void commit(TransactionStatus status) throws TransactionException;
//回滚事务
void rollback(TransactionStatus status) throws TransactionException;
}
1.4.2 TransactionDefinition:事务属性事务管理器接口
PlatformTransactionManager 通过 getTransaction(TransactionDefinition definition) 方法来得到一个事务,这个方法里面的参数是 TransactionDefinition 类 ,这个类就定义了一些基本的事务属性。什么是事务属性呢?
事务属性可以理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了 5 个方面:
- 隔离级别
- 传播行为
- 回滚规则
- 是否只读
- 事务超时
TransactionDefinition 接口中定义了 5 个方法以及一些表示事务属性的常量比如隔离级别、传播行为等等。
package org.springframework.transaction;
import org.springframework.lang.Nullable;
public interface TransactionDefinition {
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = 1;
int ISOLATION_READ_COMMITTED = 2;
int ISOLATION_REPEATABLE_READ = 4;
int ISOLATION_SERIALIZABLE = 8;
int TIMEOUT_DEFAULT = -1;
// 返回事务的传播行为,默认值为 REQUIRED。
int getPropagationBehavior();
//返回事务的隔离级别,默认值是 DEFAULT
int getIsolationLevel();
// 返回事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
int getTimeout();
// 返回是否为只读事务,默认值为 false
boolean isReadOnly();
@Nullable
String getName();
}
- 事务隔离级别
-
事务并发时的安全问题
问题 描述 隔离级别 脏读 一个事务读取到另一个事务还未提交的数据 read-commited 不可重复读 一个事务内多次读取一行数据的内容,其结果不一致 repeatable-read 幻读 一个事务内多次读取一张表中的内容,其结果不一致 serialized-read -
Spring事务隔离级别(比数据库事务隔离级别多一个default)由低到高为:
隔离级别 ISOLATION_DEFAULT 这是一个platfromtransactionmanager默认的隔离级别,使用数据库默认的事务隔离级别。 ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,会产生脏读,不可重复读和幻像读。 ISOLATION_READ_COMMITTED 这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。 Oracle数据库默认的隔离级别。 ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。MySQL数据库默认的隔离级别。 ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻像读。
- 事务的传播行为
-
什么是事务传播行为?
事务传播行为(propagation behavior)指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行。
例如:methodA事务方法调用methodB事务方法时,methodB是继续在调用者methodA的事务中运行呢,还是为自己开启一个新事务运行,这就是由methodB的事务传播行为决定的。
-
Spring定义了七种传播行为:
事务传播行为类型 说明 PROPAGATION_REQUIRED 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。 PROPAGATION_MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常。 PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。 PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。 PROPAGATION_NESTED 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与REQUIRED类似的操作。
- 事务超时
timeout
事务超时时间: 当前事务所需操作的数据被其他事务占用,则等待。- 100:自定义等待时间100(秒)。
- -1:由数据库指定等待时间,默认值。(建议)
- 读写性
readonly
读写性-
true:只读,可提高查询效率,适合查询
-
false:可读可写,适合增删改
-
- 事务回滚规则
这些规则定义了哪些异常会导致事务回滚而哪些不会。
默认情况下,事务只有遇到运行期异常(RuntimeException
的子类)时才会回滚,Error
也会导致事务回滚,但是,在遇到检查型(Checked)异常时不会回滚。
1.4.3 TransactionStatus:事务状态
TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息。
PlatformTransactionManager.getTransaction(…)
方法返回一个 TransactionStatus 对象。
TransactionStatus 接口内容如下:
public interface TransactionStatus{
boolean isNewTransaction(); // 是否是新的事务
boolean hasSavepoint(); // 是否有恢复点
void setRollbackOnly(); // 设置为只回滚
boolean isRollbackOnly(); // 是否为只回滚
boolean isCompleted; // 是否已完成
}
2.事务入门案例
通过实现银行转账功能初步认识事务
- applicationContext.xml
创建事物管理器和事物属性bean对象,使用默认id
<!--配置事物管理器-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置事物属性-->
<bean class="org.springframework.transaction.support.DefaultTransactionDefinition">
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
<property name="readOnly" value="false"></property>
</bean>
- service
业务层实现事务,手动触发一个异常,进行测试
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private TransactionDefinition txDefinition;
@Autowired
private PlatformTransactionManager txManager;
/**
* 转账
* @param source
* @param target
* @param money
*/
@Override
public void updateUser(String source, String target, Float money) {
// 获取一个事务
TransactionStatus txStatus = txManager.getTransaction(txDefinition);
try {
//扣钱
userMapper.updateUserOfSub(source, money);
//触发异常,测试事务
int a = 6/0;
//加钱
userMapper.updateUserOfAdd(target, money);
//提交事务
txManager.commit(txStatus);
}catch (Exception e){
//回滚事务
txManager.rollback(txStatus);
e.printStackTrace();
}
}
}
- 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {
@Autowired
private UserService userService;
/**
* 转账业务
*/
@Test
public void testUpdate(){
userService.updateUser("张三丰","宋远桥",1F);
}
}
-
事务回滚:
-
满足执行
我们现在虽然实现了事务控制,但是代码非常的臃肿,我们可以使用动态代理简化代码
3.动态代理控制事务
- factory
创建一个工厂,专门用来给 Service 创建代理对象,如下:
package com.by.factory;
import com.by.service.UserService;
import com.by.service.UserServiceImpl;
import org.hamcrest.Factory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* bean工厂
*/
@Component
public class BeanFactory {
@Autowired
private UserService userService;
@Autowired
private TransactionDefinition txDefinition;
@Autowired
private PlatformTransactionManager txManager;
/**
* 获得UserServiceImpl对象
*
* @return
*/
public UserService getUserService() {
return (UserService) Proxy.newProxyInstance(
userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//开启事务
TransactionStatus txStatus =
txManager.getTransaction(txDefinition);
try {
method.invoke(userService, args);
//提交事务
txManager.commit(txStatus);
} catch (Exception e) {
//回滚事务
txManager.rollback(txStatus);
e.printStackTrace();
}
return null;
}
});
}
}
- applicationContext.xml
<!--配置service代理对象-->
<bean id="proxyService" factory-bean="beanFactory" factory-method="getUserService"></bean>
- service
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 转账
* @param source
* @param target
* @param money
*/
@Override
public void updateUser(String source, String target, Float money) {
userMapper.updateUserOfSub(source, money);
int a = 6/0;
userMapper.updateUserOfAdd(target, money);
}
}
- 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class ServiceTest {
@Autowired
@Qualifier("proxyService")//注入代理对象
private UserService userService;
@Test
public void testUpdate(){
userService.updateUser("张三丰","宋远桥",1F);
}
}
- 事务回滚:
动态代理需要手动编写被代理类来指定增强代码,AOP可自动创建代理类从而进一步简化代码
4.Spring AOP控制事务
- 导入schema约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
https://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>
- 配置增强
<!-- 1、增强 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--事务属性-->
<tx:attributes>
<!-- 指定方法名称:是业务核心方法
read-only:是否是只读事务。默认false,不只读。
isolation:指定事务的隔离级别。默认值是使用数据库的默认隔离级别。
propagation:指定事务的传播行为。
timeout:指定超时时间。默认值为:-1。永不超时。
rollback-for:用于指定一个异常,当执行产生该异常时,事务回滚。产生其他异常,事务不回滚。
省略时任何异常都回滚。
-->
<tx:method name="*" read-only="false" propagation="REQUIRED"/>
<tx:method name="select*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
- 配置切点
<aop:config>
<!--2、切点-->
<aop:pointcut expression="execution(* com.by.service.*.*(..))" id="pointcut"/>
</aop:config>
- 配置切面
<aop:config>
<!--3、切面-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
- 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {
@Autowired
private UserService userService;
/**
* 转账业务
*/
@Test
public void testUpdate(){
userService.updateUser("张三丰","宋远桥",1F);
}
}
-
事务回滚:
5. 基于注解的AOP控制事务
5.1 @Transactional 注解使用详解
- @Transactional 的作用范围
方法:推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。
类:如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。
接口:不推荐在接口上使用。
- @Transactional 的常用配置参数
@Transactional注解源码如下,里面包含了基本事务属性的配置:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
- @Transactional 的常用配置参数总结(只列出了 5 比较常用的):
属性名 | 说明 |
---|---|
propagation | 事务的传播行为,默认值为 REQUIRED,可选的值在上面介绍过 |
isolation | 事务的隔离级别,默认值采用 DEFAULT,可选的值在上面介绍过 |
timeout | 事务的超时时间,默认值为-1(不会超时)。如果超过该时间限制但事务还没有完成,则自动回滚事务。 |
readOnly | 指定事务是否为只读事务,默认值为 false。 |
rollbackFor | 用于指定能够触发事务回滚的异常类型,并且可以指定多个异常类型。 |
- @Transactional 事务注解原理
@Transactional 的工作机制是基于 AOP 实现的,AOP 又是使用动态代理实现的。如果目标对象实现了接口,默认情况下会采用 JDK 的动态代理,如果目标对象没有实现了接口,会使用 CGLIB 动态代理。
5.2 使用注解控制事务
- applicationContext.xml
<!-- 开启spring对注解事务的支持 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
- service
@Service
@Transactional(readOnly=true,propagation= Propagation.SUPPORTS)
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* 转账
* @param source
* @param target
* @param money
*/
@Override
@Transactional(readOnly=false,propagation=Propagation.REQUIRED)
public void updateUser(String source, String target, Float money) {
userMapper.updateUserOfSub(source, money);
int a = 6/0;
userMapper.updateUserOfAdd(target, money);
}
}
- 测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {
@Autowired
private UserService userService;
/**
* 转账业务
*/
@Test
public void testUpdate(){
userService.updateUser("张三丰","宋远桥",1F);
}
}
- 事务回滚:
6.Spring整合MyBatis
6.1 创建工程
- pom.xml:添加工程依赖
<?xml version="1.0" encoding="UTF-8"?>
<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.by</groupId>
<artifactId>Spring_MyBatis</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!-- 项目源码及编译输出的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 项目编译JDK版本 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring常用依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.0</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!--日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.26</version>
</dependency>
<!--junit-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.32</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
</project>
- log4j.properties:配置日志输出文件
log4j.rootLogger=DEBUG,A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n
- applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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">
<context:component-scan base-package="com.by"></context:component-scan>
</beans>
6.2 配置数据源
- db.properties:配置数据库连接信息
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=1111
- applicationContext.xml:配置数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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
">
<!--加载配置文件-->
<context:property-placeholder location="classpath:db.properties" />
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
6.3 整合MyBatis
- applicationContext.xml
<!--会话工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.by.pojo"></property>
</bean>
<!--扫描basePackage所指定的包下的所有接口,生成代理类并交给spring管理-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--mapper所在的包-->
<property name="basePackage" value="com.by.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
6.4 测试
- 创建表
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`money` float DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
- pojo
package com.by.pojo;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class User {
private Integer id;
private String name;
private Float money;
}
- mapper
public interface UserMapper {
public void addUser(User user);
}
<?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.by.mapper.UserMapper">
<insert id="addUser" parameterType="User">
insert into t_user(name,money) values(#{name},#{money})
</insert>
</mapper>
- service
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void addUser(User user) {
userMapper.addUser(user);
}
}
- junit
package com.by.test;
import com.by.pojo.User;
import com.by.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")//加载配置文件
public class ServiceTest {
@Autowired
private UserService userService;
@Test
public void testAdd(){
userService.addUser(new User("张三丰",4000F));
userService.addUser(new User("宋远桥",2000F));
}
}