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

news2024/11/24 8:34:29

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

  • spring整合mybatis
    • 1. 在pom.xml中导入依赖
    • 2. 创建实体类
    • 3. 创建Mapper接口
    • 4. 配置mybatis核心配置文件
    • 5. 编写映射文件Mapper.xml
    • 6. 编写数据源配置
    • 7. sqlSessionFactory
    • 8. sqlSessionTemplate
    • 9. 需要给接口加实现类
    • 10. 将实现类注入到spring中
    • 11. 添加声明式事务
    • 12. 测试使用
  • 声明式事务
    • 1. 传播行为
    • 2. 隔离级别
    • 3. 只读提示 readOnly
    • 4. 事务超时期间

spring整合mybatis

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

1. 在pom.xml中导入依赖

	<!-- 基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.1</version>
        </dependency>
        <!-- Spring 持久化层支持jar包 -->
        <!-- Spring 在执行持久化层操作、与持久化层技术进行整合过程中,需要使用orm、jdbc、tx三个
        jar包 -->
        <!-- 导入 orm 包就可以通过 Maven 的依赖传递性把其他两个也导入 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>5.3.1</version>
        </dependency>
        <!-- junit测试 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!-- MySQL驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>
        <!--mybatis核心-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.11</version>
        </dependency>
        <!-- 数据源 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- spring-aspects会帮我们传递过来aspectjweaver -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.1</version>
        </dependency>

这里我的数据源选择的是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;
    }
}

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();


}

4. 配置mybatis核心配置文件

mybatis-config.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>
    <!--MyBatis核心配置文件的标签必须按照指定的顺序去配置
        properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,
        objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?
    -->
    <settings>
        <!--将下划线映射为驼峰-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
    	<!--包的别名-->
        <package name="com.gothic.sunset"/>
    </typeAliases>


</configuration>

5. 编写映射文件Mapper.xml

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

<?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">

<!--namespace需要填写对应的mapper接口来绑定-->
<mapper namespace="com.gothic.sunset.mapper.UserMapper">

    <!--public int addUser(User user);-->
    <insert id="addUser" >
        insert into user(id,user_name,password) values (#{id},#{userName},#{password})
    </insert>

    <!-- public int updateUser(@Param("id") int id); -->
    <update id="updateUser" >
        update  user
        set user_name=#{userName},
            password = #{password}
        where id = #{id}
    </update>
    
    <!-- public int delete(@Param("id") int id);-->
    <delete id="delete" >
        delete from user where id =#{id}
    </delete>

    <!--public List<User> selectAllUsers();-->
    <select id="selectAllUsers" resultType="User">
        select id,user_name,password from user where id =#{id}
    </select>



</mapper>

6. 编写数据源配置

在这里我的数据库连接配置信息在另一个文件中jdbc.properties中,通过 <context:property-placeholder location="classpath: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

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

	<!--引入jdbc.properties-->
    <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>

7. sqlSessionFactory

也在spring-dao.xml中编写:

	<!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--绑定mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--绑定mapper映射文件-->
        <property name="mapperLocations" value="classpath:com/gothic/sunset/mapper/*.xml"/>
    </bean>

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

8. sqlSessionTemplate

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

	<!--配置sqlSession-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
    </bean>

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();
    }


}

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

10. 将实现类注入到spring中

在applicationContext.xml中编写:

	<!--导入spring-dao.xml-->
	<import resource="spring-dao.xml"/>

    <bean id="userMapper" class="com.gothic.sunset.mapper.UserMapperImpl">
        <property name="sqlSession" ref="sqlSession"/>
    </bean>

11. 添加声明式事务

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

事务管理器:

	 <!--
    开启事务的注解驱动
    通过注解@Transactional所标识的方法或标识的类中所有的方法,都会被事务管理器管理事务
    -->
    <!-- transaction-manager属性的默认值是transactionManager,如果事务管理器bean的id正好就
    是这个默认值,则可以省略这个属性 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="dataSource" />
    </bean>

这里如果使用@Transactional注解方式来配置的话,配置事务通知就需要使用<tx:annotation-driven transaction-manager="transactionManager" />

配置事务通知:

	<!-- tx:advice标签:配置事务通知 -->
	<!-- id属性:给事务通知标签设置唯一标识,便于引用 -->
	<!-- transaction-manager属性:关联事务管理器 -->
	<tx:advice transaction-manager="transactionManager" id="txAdvice">
        <tx:attributes>
        	<!-- tx:method标签:配置具体的事务方法 -->
			<!-- name属性:指定方法名,也可以使用星号代表多个字符 -->
            <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>

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>

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);

    }

观察我们的测试代码,越来越简单,相比于之前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="..."/>

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


@Transactional(isolation = "",timeout = "",
readOnly = true|flase,propagation = "",rollbackFor...)

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


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/47441.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript获取DOM元素相关信息和属性

getBoundingClientRect 获取到元素盒模型的一些信息,得到的结果是没有单位的,不包含滚动条的距离,不包含margin&#xff0c;包含border和padding width 宽度&#xff08;包含边框&#xff09; height 高度&#xff08;包含边框&#xff09; left 从元素最左边到可视区最左边距…

Ansible 企业级自动化运维实战

一、Ansible 简介 如果Ansible不采用0mq(ZeroMQ),在操作1000个以下的节点性能还可以,如果操作1000个以上的节点,性能就很差。 目前来说Ansible支持local,ssh,0mq,Ansible用ssh来管理被管理主机是最常见的方法。 saltstack简称salt,默认采用0mq(ZeroMQ),支持数万…

[附源码]Python计算机毕业设计Django大学生心理健康测评系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

【Java】并发模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pt4IAyjj-1669730661631)(https://gitee.com/github-25970295/blogpictureV2/raw/master/java-concurrent-overview-1.png)] 1. 并发问题的根源 可见性&#xff1a;一个线程对共享变量的修改&#xf…

GIT error: Committing is not possible because you have unmerged files.

翻译&#xff1a;错误:无法提交&#xff0c;因为您有未合并的文件。 git 上传文件报错原因&#xff1a; 远程仓库的文件与在本地被删除了&#xff0c;本地删除文件后重新创建一个相同文件名的文件 远程仓库&#xff1a; 解决方法&#xff1a; 代码重新提交&#xff0c;重新合…

xv6---Lab2: system calls

目录 参考资料&#xff1a; 2.1 抽象物理资源 2.2 特权模式与系统调用 2.3 内核的组织 2.5 进程概览 2.6 Code: 启动xv6&#xff0c;第一个进程和系统调用 4.2 Trap from user space System call tracing 关于syscall函数的代码 每个syscall是由usys.pl自动生成为us…

SAP 异常现象之同一个IDoc可以被POST两次触发2张不同的物料凭证

SAP 异常现象之同一个IDoc可以被POST两次触发2张不同的物料凭证 玩过SAP IDoc的童鞋都知道&#xff0c;一个IDoc正常情况下是只能被POST一次的&#xff0c;不可以POST两次的。 比如如下的IDoc 0000000205423126已经被POST了&#xff0c;其状态为53&#xff0c; Material Docume…

2-FreeRTOS编码标准、风格指南

1- 编码标准 FreeRTOS源文件(对所有端口通用&#xff0c;但对端口层不通用)符合MISRA编码标准指南。使用pc-lint和链接lint配置文件检查遵从性。由于标准有很多页长&#xff0c;并且可以从MISRA处以非常低的费用购买&#xff0c;所以我们在这里没有复制所有的规则。 就是下面这…

时间序列:时间序列模型---白噪声

本文是Quantitative Methods and Analysis: Pairs Trading此书的读书笔记。 白噪声&#xff08;white noise)是最简单的随机时间序列&#xff08;stochastic time series)。 在每一时刻&#xff0c;从一个正态分布中抽取一个值从而形成白噪声时间序列。并且&#xff0c;这个正…

1. 关于pytorch中的数据操作的广播机制

在某些情况下&#xff0c;即使形状不同&#xff0c;我们仍然可以通过调用 广播机制&#xff08;broadcasting mechanism&#xff09;来执行按元素操作。 这种机制的工作方式如下&#xff1a;首先&#xff0c;通过适当复制元素来扩展一个或两个数组&#xff0c; 以便在转换之后&…

第七章 贝叶斯分类器(下)

7.5 贝叶斯网 贝叶斯网亦称“信念网”&#xff0c;它借助有向无环图&#xff08;DAG&#xff09;来刻画属性之间的依赖关系&#xff0c;并使用条件概率表&#xff08;CPT&#xff09;来描述属性的联合概率分布。 具体来说&#xff0c;一个贝叶斯网B由结果G和参数Θ两部分构成&…

安全漏洞分类之CNNVD漏洞分类指南

适用范围说明 凡是被国家信息安全漏洞库&#xff08;CNNVD&#xff09;收录的漏洞&#xff0c;均适用此分类规范&#xff0c;包括采集的公开漏洞以及收录的未公开漏洞&#xff0c;通用型漏洞及事件型漏洞。 漏洞类型 CNNVD将信息安全漏洞划分为26种类型&#xff0c;分别是&…

基于Tree-LSTM网络语义表示模型

TC&#xff1b;DR 目前的LSTM仅能对序列信息进行建模&#xff0c; 但是自然语言中通常由词组成的短语形成了句法依存的语义树。为了学习到树结构的语义信息。论文中提出了两种Tree-LSTM模型。Child-Sum、Tree-LSTM、和N-ary Tree LSTMs。实验部分的Tree-LSTM、对比多种LSTMs的…

09【MyBatis多表关联查询】

文章目录三、MyBatis多表关联查询3.1 表的关系3.2 一对一查询3.2.1 搭建环境3.2.2 需求分析3.2.3 dao接口3.2.3 mapper.xml3.2.4 测试3.2.5 配置MyBatis一对一关系1&#xff09;传统映射&#xff1a;2&#xff09;使用association标签映射3.3 一对多查询3.3.1 需求分析3.3.2 da…

Codeforces Round #799 (Div. 4) H. Gambling

翻译&#xff1a; 玛丽安在赌场。赌场里的游戏是这样的。 在每一轮之前&#xff0c;玩家在1到109之间选择一个数字。在那之后&#xff0c;一个有109个面的骰子被滚动&#xff0c;这样就会出现1到109之间的随机数。如果玩家猜对了数字&#xff0c;他们的钱就会翻倍&#xff0c…

C++原子操作和互斥锁性能(速度)对比

先说结论&#xff1a;原子操作性能&#xff08;速度&#xff09;强于互斥锁&#xff0c;下面用例子进行说明。 编写测试demo&#xff0c;开启两个线程&#xff0c;对全局变量n分别进行自增、自减操作&#xff0c;计算执行时间。 首先看没有用任何手段进行互斥的情况&#xff0c…

Springboot生成Word/EXECL/PPTX文档

目录 一、概述 二、使用介绍 第一种Poi-tl&#xff1a; 1、介绍 2、功能 第二种Poi: 什么是POI 二进制分布 源码分发 一、概述 Word模板引擎&#xff1a;使用Word模板和数据生成对应的Word文档。 方案移植性功能性易用性 Poi-tl Java跨平台 Word模板引擎&#…

【uniapp小程序】路由跳转navigator传参封装

文章目录&#x1f34d;前言&#x1f34b;正文1、看官网1.1 navigator API 介绍1.2、路由跳转参数传递1.3、五种常见的跳转方式1.3.1 uni.navigateTo(OBJECT)1.3.2 uni.redirectTo(OBJECT)1.3.3 uni.reLaunch(OBJECT)1.3.4 uni.switchTab(OBJECT)1.3.5 uni.navigateBack(OBJECT)…

Ensp用windows回环口连接cloud配置

Ensp模拟通过本机&#xff08;windows&#xff09;用python脚本批量配置华为数通设备时&#xff0c;为了避免对内网资源的浪费最好用回环口&#xff08;loopback&#xff09;。 一、windows开启loopback虚拟接口 概要&#xff1a; right click on window start menu icon an…

【C++】类型转换

目录 一、C语言风格类型转换 二、C风格类型转换 1.static_case 2.reinterpret_case 3、const_case 4、dynamic_case 三、RTTI 总结 一、C语言风格类型转换 在C语言中&#xff0c;如果赋值运算符左右两侧类型不同&#xff0c;或者形参与实参类型不匹配&#xff0c;或者返…