自学spring的回顾(3/3)

spring事务

处理事务怎么做
1、事务内部提交:告诉spring使用哪种数据库访问事务类型
2、什么样的事务:
(1)事务的隔离级别:有4个隔离级别:
READ_UNCOMMITTED:读未提交
READ_COMMITTED:读已提交
REPEATABLE_READ:可重复读。默认
SERIALIZABLE:串行化
(2)事务的超时时间:默认-1
(3)事务的传播行为:常用的有3个
PROPAGATION_REQUIRED:指定的方法必须在事务内执行
若没有事务,则创建一个新事务。默认
PROPAGATION_REQUIRES_NEW:总是新建一个事务,若存在当前事务,
就将当前事务挂起,直到新事务执行完毕。
PROPAGATION_SUPPORTS:支持当前事务,若没有事务,也可以以非事务进行处理
3、spring提交事务或回滚的时机:
当你业务方法,执行成功,没有异常抛出,当方法执行完毕,提交
当你业务方法抛出异常,spring回滚
当你业务方法抛出非运行时异常,提交事务

spring整合mybatis(ioc和aop处理事务的运用)

实现商品购买和商品成交记录(遇到商品号不对或者商品数量不足会自动回滚)
2个数据库的表:

CREATE TABLE `goods` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `amount` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) 
CREATE TABLE `sale` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `goodid` int(11) NOT NULL,
  `num` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) 

1、创建maven项目
2、加入依赖

<dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
    <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>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.9</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.12</version>
    </dependency>

3、创建实体类
根据数据库表自行创建。
4、创建Dao和Mapper

public interface GoodDao {
    int update(Goods goods);
    goods select(Integer num);
}
<?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.my.dao.GoodDao">
    <update id="update" >
        update goods set amount=amount-#{amount} where id=#{id}
    </update>
    <select id="select" resultType="com.my.shiticlass.goods">
        select * from goods where id=#{num}
    </select>
</mapper>
public interface SaleDao {
    int insert(Sale sale);
}
<?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.my.dao.SaleDao">
    <insert id="insert">
        insert into sale(goodid,num) values (#{goodid},#{num})
    </insert>
</mapper>

5、创建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>
    <settings>
        <setting value="STDOUT_LOGGING" name="logImpl"/><!--输出日志信息-->
    </settings>
    <typeAliases>
        <package name="com.my.shiticlass"/><!--实体类所在的包-->
    </typeAliases>
    <mappers>
        <package name="com.my.dao"/><!--Dao和mapper所在的包-->
    </mappers>
</configuration>

6、创建异常类继承RuntimeException

public class NotEnough extends RuntimeException {//由于spring中事务回滚通常是处理运行时异常
    public NotEnough() {
        super();
    }
    public NotEnough(String message) {
        super(message);
    }
}

7、创建service业务逻辑代码

public interface Ser {
    void my(Integer goodsnum, Integer salenum);
}
public class Service implements Ser{
    private SaleDao saleDao;
    private GoodDao goodDao;
    public SaleDao getSaleDao() {
        return saleDao;
    }
    public void setSaleDao(SaleDao saleDao) {
        this.saleDao = saleDao;
    }
    public GoodDao getGoodDao() {
        return goodDao;
    }
    public void setGoodDao(GoodDao goodDao) {
        this.goodDao = goodDao;
    }
    public Service(SaleDao saleDao, GoodDao goodDao) {
        this.saleDao = saleDao;
        this.goodDao = goodDao;
    }
    @Override
    @Transactional//事务注解的添加,可以根据业务要求的不同,对属性进行修改,这里使用默认的属性值
    //这里没有aop动态代理的切面方法,是因为spring已经在事务中写好了切面。
    public void my(Integer goodid, Integer num) {
        Sale sale=new sale();
        sale.setGoodid(goodid);
        sale.setNum(num);
        saleDao.insert(sale);
        Goods select = goodDao.select(goodid);
        if(select==null||num>select.getAmount()){
            throw new Notenough("输入的商品编号不正确或者商品数量不足");
        }
        Goods goods1=new goods();
        goods1.setId(goodid);
        goods1.setAmount(num);
        goodDao.update(goods1);
    }
}

8、创建spring配置文件

<?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:util="http://www.springframework.org/schema/util"
       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/util 
       https://www.springframework.org/schema/util/spring-util.xsd 
       http://www.springframework.org/schema/context 
       https://www.springframework.org/schema/context/spring-context.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
    <bean id="DataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init"
          destroy-method="close"><!--这里使用druid连接数据库,作为数据源-->
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="maxActive" value="20"></property>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--创建sqlSession工厂对象,它需要数据源和mybatis配置文件的地址-->
        <property name="dataSource" ref="DataSource"></property>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!--多个动态代理对象的创建,这里不使用id是因为获取动态代理对象不方便,首字母小写-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
        <property name="basePackage" value="com.my.dao"></property>
    </bean>
    <bean id="service" class="com.my.service.Service"><!--业务逻辑类的对象-->
        <property name="GoodDao" ref="goodDao"></property>
        <property name="saleDao" ref="saleDao"></property>
    </bean>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--事务管理器,只需要数据源-->
        <property name="dataSource" ref="DataSource"></property>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/><!--事务驱动,驱动事务管理器-->
</beans>

9、写测试方法

public class MyTest {
    @Test
    public void test01(){
        String config="ApplicationContext.xml";
        ApplicationContext applicationContext=new ClassPathXmlApplicationContext(config);
        Ser service1 = (Ser) applicationContext.getBean("service");
        service1.my(1,100);
    }
}

注:如果配置多个方法的事务属性,可以采用、

    <tx:advice transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="method1" isolation="" propagation="" read-only="" rollback-for="" timeout=""/>
            <tx:method name="method2" isolation="" propagation="" read-only="" rollback-for="" timeout=""/>
        </tx:attributes>
    </tx:advice>

spring中web的容器创建

由于web中每次刷新请求或者提交数据都需要创建一次容器,效率会非常低,可以将容器放入到全局作用域中(ServletContext),多次请求都会使用这一个容器。(使用监听器处理这些)
1、首先加入依赖

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

2、在web.xml配置文件中写入listener标签

<listener>
	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

3、由于监听器要创建全局作用域对象,就要加载WEB-INF下面的applicationContext.xml文件,是默认路径,所以要求修改默认路径

<context-param>
	<para-name>contextConfigLocation</para-name>
	<para-value>classpath:</para-value>
</context-param>

4、然后就可以在Servlet类中去使用监听器创建的容器:

WebApplicationContext ctx=null;//这里的容器是在web中使用的容器
ctx=WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值