• spring复习05,spring整合mybatis,声明式事务


    spring整合mybatis

    新建一个maven项目,对用户的增删改查的业务操作。

    1. 在pom.xml中导入依赖

    	
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-contextartifactId>
                <version>5.3.1version>
            dependency>
            
            
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-ormartifactId>
                <version>5.3.1version>
            dependency>
            
            <dependency>
                <groupId>junitgroupId>
                <artifactId>junitartifactId>
                <version>4.13.2version>
                <scope>testscope>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>8.0.30version>
            dependency>
            
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatisartifactId>
                <version>3.5.11version>
            dependency>
            
            <dependency>
                <groupId>org.mybatisgroupId>
                <artifactId>mybatis-springartifactId>
                <version>3.0.0version>
            dependency>
            
            <dependency>
                <groupId>org.springframeworkgroupId>
                <artifactId>spring-aspectsartifactId>
                <version>5.3.1version>
            dependency>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    这里我的数据源选择的是mybatis-spring。链接: mybatis-spring介绍和快速入门

    2. 创建实体类

    package com.gothic.sunset.pojo;
    
    public class User {
    
        private Integer id;
        private String userName;
        private String password;
    
    
        public User() {
        }
    
        public User(Integer id, String userName, String password) {
            this.id = id;
            this.userName = userName;
            this.password = password;
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    3. 创建Mapper接口

    package com.gothic.sunset.mapper;
    
    import com.gothic.sunset.pojo.User;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    public interface UserMapper {
    
        public int addUser(User user);
    
        public int updateUser(@Param("id") int id);
    
        public int delete(@Param("id") int id);
    
        public List<User> selectAllUsers();
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    4. 配置mybatis核心配置文件

    mybatis-config.xml:

    
    DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        
        <settings>
            
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        settings>
    
        <typeAliases>
        	
            <package name="com.gothic.sunset"/>
        typeAliases>
    
    
    configuration>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    5. 编写映射文件Mapper.xml

    UserMapper.xml(在resources下的com/gothic/sunset/mapper目录下):

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    
    <mapper namespace="com.gothic.sunset.mapper.UserMapper">
    
        
        <insert id="addUser" >
            insert into user(id,user_name,password) values (#{id},#{userName},#{password})
        insert>
    
        
        <update id="updateUser" >
            update  user
            set user_name=#{userName},
                password = #{password}
            where id = #{id}
        update>
        
        
        <delete id="delete" >
            delete from user where id =#{id}
        delete>
    
        
        <select id="selectAllUsers" resultType="User">
            select id,user_name,password from user where id =#{id}
        select>
    
    
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    6. 编写数据源配置

    在这里我的数据库连接配置信息在另一个文件中jdbc.properties中,通过 引入。
    jdbc.properties:

    jdbc.driver=com.mysql.cj.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8
    jdbc.username=root
    jdbc.password=root
    
    • 1
    • 2
    • 3
    • 4

    在resources目录下新建spring-dao.xml:

    	
        <context:property-placeholder location="classpath:jdbc.properties"/>
        
        <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="url" value="${jdbc.url}"/>
            <property name="driverClassName" value="${jdbc.driver}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    7. sqlSessionFactory

    也在spring-dao.xml中编写:

    	
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            
            <property name="configLocation" value="classpath:mybatis-config.xml"/>
            
            <property name="mapperLocations" value="classpath:com/gothic/sunset/mapper/*.xml"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里可以通过sqlSessionFactory来绑定mapper映射文件,也可以像之前一样在mybatis-config.xmlmappers标签来绑定mapper映射文件。

    8. sqlSessionTemplate

    在spring-dao.xml中编写:
    使用 SqlSessionFactory 作为构造方法的参数来创建 SqlSessionTemplate 对象。

    	
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg index="0" ref="sqlSessionFactory"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4

    SqlSessionTemplate 是 MyBatis-Spring 的核心。作为 SqlSession 的一个实现,可以使用它无缝代替你代码中已经在使用的 SqlSession。 SqlSessionTemplate 是线程安全的,可以被多个 DAO 或映射器所共享使用。

    Spring 框架对 JDBC 进行封装,使用 JdbcTemplate 方便实现对数据库操作。(本着万物皆bean,交由容器处理)

    9. 需要给接口加实现类

    因为现在我们的sqlsession已经交由ioc容器来管理,所以我们可以通过接口实现类的方式,直接使用依赖注入去完成功能,这会使我们的代码更简单。

    package com.gothic.sunset.mapper;
    
    import com.gothic.sunset.pojo.User;
    import org.mybatis.spring.SqlSessionTemplate;
    
    import java.util.List;
    
    public class UserMapperImpl implements UserMapper{
    
        //set注入sqlSession对象
        private SqlSessionTemplate sqlSession;
    
        public void setSqlSession(SqlSessionTemplate sqlSession) {
            this.sqlSession = sqlSession;
        }
    
        @Override
        public int addUser(User user) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            int i = mapper.addUser(user);
            return i;
        }
    
        @Override
        public int updateUser(int id) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.updateUser(id);
        }
    
        @Override
        public int delete(int id) {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.delete(id);
        }
    
        @Override
        public List<User> selectAllUsers() {
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            return mapper.selectAllUsers();
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    这里的sqlSession也可以通过注解的方式注入,这样子就更简单了。

    10. 将实现类注入到spring中

    在applicationContext.xml中编写:

    	
    	<import resource="spring-dao.xml"/>
    
        <bean id="userMapper" class="com.gothic.sunset.mapper.UserMapperImpl">
            <property name="sqlSession" ref="sqlSession"/>
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    11. 添加声明式事务

    要开启 Spring 的事务处理功能,在 Spring 的配置文件中创建一个 DataSourceTransactionManager 对象。

    事务管理器:

    	 
        
    	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <constructor-arg ref="dataSource" />
        bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里如果使用@Transactional注解方式来配置的话,配置事务通知就需要使用

    配置事务通知:

    	
    	
    	
    	<tx:advice transaction-manager="transactionManager" id="txAdvice">
            <tx:attributes>
            	
    			
                <tx:method name="addUser" propagation="REQUIRED"/>
                <tx:method name="updateUser" propagation="REQUIRED"/>
                <tx:method name="delete" propagation="REQUIRED"/>
                <tx:method name="selectAllUsers" read-only="false"/>
            tx:attributes>
        tx:advice>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    read-only属性:设置只读属性
    rollback-for属性:设置回滚的异常
    no-rollback-for属性:设置不回滚的异常
    isolation属性:设置事务的隔离级别
    timeout属性:设置事务的超时属性
    propagation属性:设置事务的传播行为

    配置aop事务切入:

     	
        <aop:config>
            
            <aop:pointcut id="pointCut" expression="execution(* com.gothic.sunset.mapper.*.*(..))"/>
            <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
        aop:config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    12. 测试使用

     	@Test
        public void testJdbc(){
            ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
            UserMapper userMapper =  ioc.getBean("userMapper", UserMapper.class);
            User user1 = new User(1, "一叶知秋", "110244001");
            User user2 = new User(2, "大漠孤烟", "110244003");
            User user3 = new User(3, "夜雨声烦", "110244023");
            User user4 = new User(4, "树藤海岛", "110244026");
            userMapper.addUser(user1);
            userMapper.addUser(user2);
            userMapper.addUser(user3);
            userMapper.addUser(user4);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    观察我们的测试代码,越来越简单,相比于之前sqlSessionFactory的工具类也更简单了。

    插入成功:

    在这里插入图片描述

    声明式事务

    声明式事务(declarative transaction management)是Spring提供的对程序事务管理的方式之一。

    Spring使用AOP来完成声明式的事务管理,因而声明式事务是以方法为单位,在Spring中事务属性有以下四个参数:

    1. 传播行为

    当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。

    2. 隔离级别

    数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高数据一致性就越好但并发性越弱

    隔离级别一共有四种:

    • 读未提交:READ UNCOMMITTED
      允许Transaction01读取Transaction02未提交的修改。
    • 读已提交:READ COMMITTED、
      要求Transaction01只能读取Transaction02已提交的修改。
    • 可重复读:REPEATABLE READ
      确保Transaction01可以多次从一个字段中读取到相同的值,即Transaction01执行期间禁止其它事务对这个字段进行更新。
    • 串行化:SERIALIZABLE
      确保Transaction01可以多次从一个表中读取到相同的行,在Transaction01执行期间,禁止其它事务对这个表进行添加、更新、删除操作。可以避免任何并发问题,但性能十分低下。

    3. 只读提示 readOnly

    对一个查询操作来说,如果我们把它设置成只读,就能够明确告诉数据库,这个操作不涉及写操作。这样数据库就能够针对查询操作来进行优化。

    4. 事务超时期间

    事务在执行过程中,有可能因为遇到某些问题,导致程序卡住,从而长时间占用数据库资源。而长时间占用资源,大概率是因为程序运行出现了问题(可能是Java程序或MySQL数据库或网络连接等等)。此时这个很可能出问题的程序应该被回滚,撤销它已做的操作,事务结束,把资源让出来,让其他正常程序可以执行。
    超时回滚,释放资源


    以上的四个属性在xml和注解中都可以配置:
    xml中:

    <tx:method name="xxx" 
    propagation="REQUIRED|.." 
    read-only="true|false" 
    isolation="DEFAULT|READ_UNCOMMITTED|READ_COMMITTED|REPEATABLE_READ|SERIALIZABLE" 
    rollback-for="..." 
    timeout="..."/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    好多我就不一一列出,大家可以自行查看文档。
    注解:

    
    @Transactional(isolation = "",timeout = "",
    readOnly = true|flase,propagation = "",rollbackFor...)
    
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述
    声明式事务默认只针对运行时异常回滚,编译时异常不回滚。可以通过@Transactional中相关属性设置回滚策略。
    rollbackFor属性:需要设置一个Class类型的对象
    rollbackForClassName属性:需要设置一个字符串类型的全类名
    noRollbackFor属性:需要设置一个Class类型的对象
    rollbackFor属性:需要设置一个字符串类型的全类名


    spring大概的过了一遍,过几天要开始springMvc的复习了,果然“配置地狱”!!!

  • 相关阅读:
    【解决方案】多租户技术架构设计入门(一)
    计算机组成原理-----定点数原码和补码的乘法与除法
    使用Nginx和内网穿透实现多个本地Web站点的公网访问
    代码随想录算法训练营第四十一天 | 01背包问题 二维
    flutter sliver 多种滚动组合开发指南
    C现代方法(第12章)笔记——指针和数组
    【Rust—LeetCode题解】1656. 设计有序流
    如何实现MySQL的增删改查
    建模助手(Revit)插件如何生成基坑开挖和地下连续墙?
    C/C++语言100题练习计划 77——区间问题(差分实现)
  • 原文地址:https://blog.csdn.net/m0_63622279/article/details/128098912