**如果想先学习整合框架可以参考我的另一篇文章
https://blog.csdn.net/weixin_52188717/article/details/115375060?spm=1001.2014.3001.5501
**
一。事务说明
模拟用户购买商品(模拟用户下订单,向订单表添加销售记录,从商品表减少库存)
二。代码实现
1)创建数据库中的表—goods表和sale表
create table sale(
id int primary key auto_increment,
gid int ,
nums int
);
create table goods(
id int primary key auto_increment,
name varchar(100),
amount int,
price float
);
insert into goods values(1001,'computer',10,5000.00);
insert into goods values(1002,'phone',30,3000.00);
2)加入依赖
1.spring依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
2.mybatis依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
3.mysql驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
4.spring事务的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
5.spring和mybatis的集成依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
6.连接池
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
3)创建实体类
Goods类
package zjc.javaweb.entity;
public class Goods {
private Integer id;
private String name;
private Integer amount;
private float price;
}
Sale类
package zjc.javaweb.entity;
public class Sale {
private Integer id;
private Integer gid;
private Integer nums;
}
4)定义dao接口(mybatis内容)
GoodsDao
package zjc.javaweb.dao;
public interface GoodsDao {
int updateGoods(Goods goods);
}
SaleDao
package zjc.javaweb.dao;
public interface SaleDao {
int insertSale();
}
5)定义dao接口的sql映射文件,也即是同名xml文件(mybatis内容)
GoodsDao.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="zjc.javaweb.dao.GoodsDao">
<!--这个位置namespace要改成接口名字相对路径-->
<!--id改成dao接口的方法名-->
<update id="updateGoods">
<!--sql语句-->
update goods set amount =amount-#{amount}
</update>
<select id="selectGoods" resultType="Integer">
select amount from goods where id=#{goodsId}
</select>
</mapper>
这段代码应用率和重复率较高,大家可以参考我的另一篇文章来设置模板https://editor.csdn.net/md/?articleId=115414716
SaleDao.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="zjc.javaweb.dao.SaleDao">
<!--这个位置namespace要改成接口名字相对路径-->
<!--id改成dao接口的方法名-->
<insert id="insertSale">
<!--sql语句-->
insert into sale (gid,nums) values(#{gid},#{nums})
</insert>
</mapper>
6)定义service接口(spring内容)
package zjc.javaweb.Service;
public interface BuyGoodsService {
public void Buy(Integer goodsId,Integer amount);
}
7)定义service接口的实现类(spring内容)
package zjc.javaweb.Service;
import zjc.javaweb.dao.GoodsDao;
import zjc.javaweb.dao.SaleDao;
import zjc.javaweb.entity.Goods;
import zjc.javaweb.entity.Sale;
import zjc.javaweb.excep.NotEnoughException;
public class BuyGoodsServiceImp implements BuyGoodsService{
//1.dao属性
private SaleDao saleDao;
private GoodsDao goodsDao;
public void setSaleDao(SaleDao saleDao) {
this.saleDao = saleDao;
}
public void setGoodsDao(GoodsDao goodsDao) {
this.goodsDao = goodsDao;
}
@Override
public void Buy(Integer goodsId, Integer nums) {
//记录销售信息,向Sale表添加记录
Sale sale=new Sale();
sale.setGid(goodsId);
sale.setNums(nums);
saleDao.insertSale(sale);
//输出剩余库存
Goods goods=goodsDao.selectGoods(goodsId);
if(goods.getAmount()<nums){
System.out.println("库存不足");
}else{
int i=goods.getAmount()-nums;
System.out.println("购买成功,还剩"+i);
}
//更新库存
Goods buyGoods=new Goods();
buyGoods.setId(goodsId);
buyGoods.setAmount(nums);
goodsDao.updateGoods(buyGoods);
}
}
8)声明主配置文件和mybatis.xml文件
Resources文件下创建
mybatis.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>
<settings>
<!--这里是设置输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<!--实体类的包名-->
<package name="zjc.javaweb.entity"/>
</typeAliases>
<mappers>
<!--是mapper配置文件的包名-->
<package name="zjc.javaweb.dao"/>
</mappers>
</configuration>
配置文件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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--配置druid连接池数据源-->
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="333"/>
</bean>
<!--注册sqlsessionactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="datasource"/>
<!--value改成classpath:mybatis主配置文件的名字-->
<property name="configLocation" value="classpath:mybatis.xml"/>
</bean>
<!--声明扫描器对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--dao接口所在路径-->
<property name="basePackage" value="zjc.javaweb.dao"/>
</bean>
<!--id:自己定义,class:是实现类的绝对路径-->
<bean id="buyService" class="zjc.javaweb.Service.BuyGoodsServiceImp">
<!--name是实现类中dao接口创建的属性,ref与前者同名-->
<property name="goodsDao" ref="goodsDao"/>
<property name="saleDao" ref="saleDao"/>
</bean>
<context:component-scan base-package="com.alibaba.druid">
</context:component-scan>
</beans>
9)定义测试类
package zjc.javaweb;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import zjc.javaweb.Service.BuyGoodsService;
public class AppTest
{
@Test
public void test01(){
String config="applicationContext.xml";
ApplicationContext ac=new ClassPathXmlApplicationContext(config);
BuyGoodsService service=(BuyGoodsService) ac.getBean("buyService"); //service层定义id
service.Buy(1001,2);
}
}
接下来开始添加事务
事务是什么:事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。
所以不添加事务程序也可以正常运行,添加事务后程序会更加严密。
添加事务的步骤:
1)声明事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--指定数据源-->
<property name="dataSource" ref="datasource"/>
</bean>
2)开启注解驱动
这里要注意tx:annotation-driven有很多种,要选以tx结尾的
<!--transaction-manager:事务管理器的id-->
<!--选tx结尾的-->
<tx:annotation-driven transaction-manager="transactionManager"/>
3)在servie接口的实现类中方法上方添加注解
@Transactional(propagation = Propagation.REQUIRED,
rollbackFor = {NotEnoughException.class,
NullPointerException.class})
propagation:用于设置事务传播属性,默认值为Propagation.REQUIRED。
rollbackfor:用于设置抛出异常的类,如:NullPointException