Spring5(23) —— 回顾事务


1.回顾事务

  • 事务特性:要么都成功,要么都失败
  • 事务在项目开发中十分重要,涉及到数据一致性问题,不能马虎
  • 它用于确保数据一致性

事务的ACID原则

  1. 原子性:事务不可分割
  2. 一致性:事务执行不管成不成功,所有人的数据要一致;比如转账,那么参与转账双方的钱的总和应该保持不变
  3. 隔离性:操作同一数据的不同事务之间相互独立,互不干扰
  4. 持久性:事务成功之后,其结果必须影响数据库中的数据;即使事务失败,也要求使用某种机制恢复数据

2.代码实现

1.项目搭建

    首先我们再来回顾一下spring整合mybatis

  • 创建新项目:Spring-11-Transaction

  • 子model依赖添加

    <?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">
       <parent>
           <artifactId>Spring-Study</artifactId>
           <groupId>com.thhh</groupId>
           <version>1.0-SNAPSHOT</version>
       </parent>
       <modelVersion>4.0.0</modelVersion>
    
       <artifactId>Spring-11-Transaction</artifactId>
       <dependencies>
           <!--junit依赖-->
           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>4.12</version>
           </dependency>
           <!--数据库依赖-->
           <dependency>
               <groupId>mysql</groupId>
               <artifactId>mysql-connector-java</artifactId>
               <version>5.1.47</version>
           </dependency>
           <!--mybatis依赖-->
           <dependency>
               <groupId>org.mybatis</groupId>
               <artifactId>mybatis</artifactId>
               <version>3.5.2</version>
           </dependency>
           <!--spring依赖-->
           <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-webmvc</artifactId>
               <version>5.2.8.RELEASE</version>
           </dependency>
           <!--spring操作数据库,需要再导入一个spring-jdbc这个依赖-->
           <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-jdbc</artifactId>
               <version>5.2.8.RELEASE</version>
           </dependency>
           <!--AOP织入包,简单理解,支持切入点表达式等等-->
           <dependency>
               <groupId>org.aspectj</groupId>
               <artifactId>aspectjweaver</artifactId>
               <version>1.9.4</version>
           </dependency>
           <!--mybatis-spring整合依赖-->
           <dependency>
               <groupId>org.mybatis</groupId>
               <artifactId>mybatis-spring</artifactId>
               <version>2.0.5</version>
           </dependency>
           <!--lombok依赖-->
           <dependency>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok</artifactId>
               <version>1.18.12</version>
           </dependency>
       </dependencies>
    
    </project>
    
  • 创建实体类

    package com.thhh.pojo;
    
    import lombok.Data;
    
    @Data
    public class User {
        private int id;
        private String name;
        private String pwd;
    }
    
  • 有了实体类就为它创建一个mapper接口

    package com.thhh.mapper;
    
    import com.thhh.pojo.User;
    
    import java.util.List;
    
    public interface UserMapper {
        public List<User> queryUserList();
    }
    
  • 有了mapper接口就为它创建一个mapper.xml

    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.thhh.mapper.UserMapper">
        <select id="queryUserList" resultType="user">
            select * from mybatis.user
        </select>
    </mapper>
    
  • 有了mapper.xml就去mybatis核心配置文件中注册,注意这一点,原来单独使用mybatis的时候,配置文件中的内容比较多,现在我们将spring和mybatis进行了整合,mybatis中一般只剩下了typealiases和setting节点的配置,其他配置都迁移到spring容器中

    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--类型别名节点-->
        <typeAliases>
            <package name="com.thhh.pojo"/><!--直接包扫描,我们可以使用类名,首字母大小写都可以-->
        </typeAliases>
    
    </configuration>
    
  • 整合mybatis,创建spring配置文件,这里我们为了规范,先创建一个整个mybatis的配置文件spring-dao.xml,再创建一个总的配置文件applicationContext.xml;spring-dao.xml负责整合mybatis(即只装配两个bean,dataSource和sqlSessionFactory),applicationContext.xml用于引入spring-dao.xml和装配bean(其他的bean都装配到这个spring容器中)

    • spring-dao.xml
    <?xml version="1.0" encoding="UTF8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop
            https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!--数据源datasources:是呀spring的数据源替换mybatis的配置-->
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=UTF-8&amp;useSSL=false"/>
            <property name="username" value="root"/>
            <property name="password" value="123"/>
        </bean>
        <!--sqlsessionFactory-->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <!--绑定mybatis配置文件-->
            <property name="configLocation" value="classpath:mybatis-config.xml"/><!--这样两个配置文件就联动起来了-->
            <property name="mapperLocations" value="classpath:com/thhh/mapper/*.xml"/><!--配置注册mapper.xml,对应mybatis中的注册mapper节点-->
        </bean>
    </beans>
    
    • applicationContext.xml
    <?xml version="1.0" encoding="UTF8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:aop="http://www.springframework.org/schema/aop"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
           https://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/aop
           https://www.springframework.org/schema/aop/spring-aop.xsd">
       <!--导入整合mybatis的子容器,最后所有的容器会整合成一个大容器-->
       <import resource="spring-dao.xml"/>
    
       <!--装配bean-->
       <!--方式2配置sqlsession-->
       <bean id="userMapperImpl" class="com.thhh.mapper.UserMapperImpl">
           <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
       </bean>
    
    </beans>
    
  • 整合spring和mybatis的时候我们需要新增一个mapper接口的实现类来封装mybatis的操作,即UserMapperImpl

    package com.thhh.mapper;
    
    import com.thhh.pojo.User;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    
    import java.util.List;
    
    public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
    
       @Override
       public List<User> queryUserList() {
           return getSqlSession().getMapper(UserMapper.class).queryUserList();
       }
    }
    
  • 测试

    import com.thhh.mapper.UserMapper;
    import com.thhh.pojo.User;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import java.util.List;
    
    public class MyTest {
        @Test
        public void test01(){
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper userMapper = context.getBean("userMapperImpl", UserMapper.class);
            List<User> userList = userMapper.queryUserList();
            for (User user : userList) {
                System.out.println(user);
            }
        }
    }
    

在这里插入图片描述

2.代码实现

需求:制造错误,用于认识spring操作中不使用事务的危险性

  • 添加一个新增和删除用户操作
    package com.thhh.mapper;
    
    import com.thhh.pojo.User;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    public interface UserMapper {
        //1、查询所有用户
        public List<User> queryUserList();
    
        //2、新增用户
        public int addUser(User user);//非基本数据类型不要写@Param注解,否则会报错
        
        //3、删除用户
        public int deleteUser(@Param("id") int id);
    }
    
  • 修改实现类
    package com.thhh.mapper;
    
    import com.thhh.pojo.User;
    import org.mybatis.spring.support.SqlSessionDaoSupport;
    
    import java.util.List;
    
    public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
    
        @Override
        public List<User> queryUserList() {
            return getSqlSession().getMapper(UserMapper.class).queryUserList();
        }
    
        @Override
        public int addUser(User user) {
            return getSqlSession().getMapper(UserMapper.class).addUser(user);
        }
    
        @Override
        public int deleteUser(int id) {
            return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
        }
    }
    
  • 去mapper.xml中编写SQL
    <?xml version="1.0" encoding="UTF8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.thhh.mapper.UserMapper">
        <!--1、查询用户-->
        <select id="queryUserList" resultType="user">
            select * from mybatis.user
        </select>
        <!--2、新增用户-->
        <insert id="addUser" parameterType="user">
            insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd});
        </insert>
        <!--3、删除用户-->
        <delete id="deleteUser">
            delete from mybatis.user where id=#{id}
        </delete>
    </mapper>
    
  • 制造一个错误,把delete关键字后面添加一个"S",那么delete操作显然使用报错的
    在这里插入图片描述
    在这里插入图片描述
  • 修改查询实现的mybatis对应的代码
        @Override
        public List<User> queryUserList() {
            User user = new User(10,"10号","123");
            UserMapper userMapper = getSqlSession().getMapper(UserMapper.class);
            userMapper.addUser(user);
            deleteUser(10);
            return userMapper.queryUserList();
        }
    

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值