MyBatis事务管理-附案例代码

一、MyBatis事务管理

SqlSession对象

  • getMapper(DAO.class):获取Mapper(DAO接口的实体类)
  • 事务管理

1.1 手动提交事务

  • 手动事务管理

    • 当我们获取sqlSession对象时,就默认开启了事务;

    • 当一系列业务操作完成之后,我们需要手动提交事务 :sqlSession.commit()

    • 当操作出现异常,调用事务回滚方法:sqlSession.rollback()

@Test
    public void deleteStudent() {
        SqlSession sqlSession = null;
        try{
            //1.当我们获取sqlSession对象时,就默认开启了事务
            sqlSession = MyBatisUtil.getSqlSession();
            StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
            int i = studentDao.deleteStudent(9);
            //2.当一系列业务操作完成之后,我们需要手动提交事务
            sqlSession.commit();
        }catch (Exception e){
            //3.当操作出现异常,调用事务回滚方法
            sqlSession.rollback();
        }finally {
            sqlSession.close();
        }
    }

1.2 自动提交事务

通过SqlSessionFactory调用openSession方法获取sqlSession对象时,可以通过参数设置事务是否自动提交

如果参数设置为true,表示自动提交事务:sqlSessionFactory.openSession(true);

如果参数为空,则默认是fales,表示手动提交:sqlSessionFactory.openSession(true);

1.3 案例

数据准备

CREATE TABLE `students` (
  `stu_num` char(8) NOT NULL,
  `stu_name` varchar(20) NOT NULL,
  `stu_denger` char(2) NOT NULL,
  `stu_age` int NOT NULL,
  `stu_tel` char(11) NOT NULL,
  `stu_qq` varchar(11) DEFAULT NULL,
  `cid` int DEFAULT NULL,
  PRIMARY KEY (`stu_num`),
  KEY `FK_STUDENT_CLASS` (`cid`),
  CONSTRAINT `FK_STUDENT_CLASS` FOREIGN KEY (`cid`) REFERENCES `class` (`class_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;


INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('1', '蔡文姬', '女', '18', '123312312', '877877', '2');
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('2', '刘禅', '男', '26', '15688887878', '332212', '1');
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('3', '大乔', '女', '19', '13232322232', '4443322', '1');
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('4', '小明', '男', '30', '13567899876', '8879778', '2');
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('5', '鲁班大师', '男', '58', '13566656556', '9999899', '2');
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('6', '墨子', '男', '38', '13788787878', '878888', NULL);
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('7', '瑶', '女', '17', '136667673', '111221', NULL);
INSERT INTO `db_test`.`students` (`stu_num`, `stu_name`, `stu_denger`, `stu_age`, `stu_tel`, `stu_qq`, `cid`) VALUES ('8', '张飞', '男', '88', '13667565656', NULL, '2');

MyBatisUtil工具类

package com.feng.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * @program: mybatis_project
 * @description: MyBatis工具类,提供getSqlSession和getMapper方法
 * @author: FF
 * @create: 2024-11-27 20:08
 **/
public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;
    //为SqlSession加锁
    private static final ThreadLocal<SqlSession> sqlSessionlock = new ThreadLocal<>();
    static {
        InputStream inputStream = null;
        try {
            //构建sqlSession工厂
            inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            sqlSessionFactory = builder.build(inputStream);
            inputStream.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    
    /** 
    * @Description: 通过sqlSessionFactory,获取sqlSession对象(private不对外)
    * @Param: [isAutoCommit]
    * @return: org.apache.ibatis.session.SqlSession
    * @Author: FF
    * @Date: 2024/11/27
    */
    
    private static SqlSession getSqlSession(boolean isAutoCommit){
        SqlSession sqlSession = sqlSessionlock.get();
        if (sqlSession == null) {
            sqlSession = sqlSessionFactory.openSession(isAutoCommit);
            sqlSessionlock.set(sqlSession);
        }
        return sqlSession;
    }
    /**
    * @Description: 获取sqlSession对象,默认手动提交事务(public对外)
    * @Param: []
    * @return: org.apache.ibatis.session.SqlSession
    * @Author: FF
    * @Date: 2024/11/27
    */

    public static SqlSession getSqlSession(){
        return getSqlSession(false);
    }
    /** 
    * @Description: 提供getMapper方法,获取mapper代理对象,默认自动提交事务
    * @Param: [c]
    * @return: T
    * @Author: FF
    * @Date: 2024/11/27
    */
    
    public static <T extends Object> T getMapper(Class<T> c){
        return getSqlSession(true).getMapper(c);
    }
}

Student.java

package com.feng.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
    private String stu_num;
    private String stu_name;
    private int stu_age;
    private String stu_denger;
    private String stu_tel;
    private String stu_qq;
    private int cid;

}

StudentDao.java

package com.feng.dao;

import com.feng.pojo.Student;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface StudentDao {
    public int addStudent(Student student);
    public int deleteStudent(int id);
    public int updateStudent(Student student);
    public List<Student> selectAllStudent();
    public Student selectStudentById(String id);
    public int countStudent();
    public List<Student> selectStudentByPage(@Param("start") int start, @Param("pageSize") int pageSize);
}

StudentMapper.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相当与DAO接口的实现类,namespace属性要指定实现DAO接口的全限定名-->
<mapper namespace="com.feng.dao.StudentDao">
    <resultMap id="studentMap" type="com.feng.pojo.Student">
        <id column="stu_num" property="stu_num"></id>
        <result column="stu_name" property="stu_name"></result>
        <result column="stu_age" property="stu_age"></result>
        <result column="stu_denger" property="stu_denger"></result>
        <result column="stu_tel" property="stu_tel"></result>
        <result column="stu_qq" property="stu_qq"></result>
        <result column="cid" property="cid"></result>
    </resultMap>
    <insert id="addStudent" parameterType="com.feng.pojo.Student" useGeneratedKeys="true" keyProperty="stu_num">
        insert into students(stu_num,stu_name,stu_age,stu_denger,stu_tel,stu_qq,cid)
        values (#{stu_num},#{stu_name},#{stu_age},#{stu_denger},#{stu_tel},#{stu_qq},#{cid})
    </insert>
    <delete id="deleteStudent">
        delete from students where stu_num = #{stu_num}
    </delete>
    <update id="updateStudent">
        update students set
            stu_num = #{stu_num},stu_name=#{stu_name},stu_age=#{stu_age},stu_denger=#{stu_denger},
            stu_tel=#{stu_tel},stu_qq=#{stu_qq},cid=#{cid}
        where
            stu_num = #{stu_num}
    </update>
    <select id="selectAllStudent" resultType="com.feng.pojo.Student" resultMap="studentMap">
        select * from students
    </select>
    <select id="selectStudentById" resultMap="studentMap">
        select * from students where stu_num = #{stu_num}
    </select>
    <select id="countStudent" resultType="int">
        select count(1) from students;
    </select>
    <select id="selectStudentByPage" resultMap="studentMap">
        select * from students limit #{start},#{pageSize}
    </select>
</mapper>

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>
    <!--配置数据库连接信息-->
    <environments default="mysql">
        <environment id="mysql">
            <!--用于配置数据库管理方式-->
            <transactionManager type="JDBC">

            </transactionManager>
            <!--配置数据库连接方式-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/db_test?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--需要将映射文件添加到主文件中-->
    <mappers>
        <mapper resource="mappers/StudentMapper.xml"></mapper>
    </mappers>
</configuration>

测试类

package com.feng.dao;

import com.feng.pojo.Student;
import com.feng.utils.MyBatisUtil;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import static org.junit.Assert.*;

public class StudentDaoTest {

    /**
    * @Description: 添加方法测试,未使用MyBatisUtils工具类,全部手写
    * @Param: []
    * @return: void
    * @Author: FF
    * @Date: 2024/11/27
    */

    @org.junit.Test
    public void addStudent() throws IOException {
        //加载mybatis配置文件
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        //构建session工厂
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //会话工厂
        SqlSessionFactory factory = sqlSessionFactoryBuilder.build(inputStream);
        //会话(连接)
        SqlSession sqlSession = factory.openSession();
        //通过会话,获取dao对象
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        //测试dao方法
        Student student = new Student();
        student.setStu_num("9");
        student.setStu_name("太乙真人");
        student.setStu_age(88);
        student.setStu_denger("男");
        student.setStu_tel("123312312");
        student.setStu_qq("877877");
        student.setCid(2);

        int i = studentDao.addStudent(student);
        //手动提交事务
        sqlSession.commit();
        //关闭会话
        sqlSession.close();
        //关闭流
        inputStream.close();
        System.out.println(i);

    }
/** 
* @Description: 删除方法测试,调用MyBatisUtil.getSqlSession()方法,默认手动提交事务
* @Param: []
* @return: void
* @Author: FF
* @Date: 2024/11/27
*/

    @Test
    public void deleteStudent() {
        SqlSession sqlSession = null;
        try{
            //1.当我们获取sqlSession对象时,就默认开启了事务(getSqlSession()方法,默认的事务提交方式是手动提交)
            sqlSession = MyBatisUtil.getSqlSession();
            StudentDao studentDao = MyBatisUtil.getMapper(StudentDao.class);
            int i = studentDao.deleteStudent(9);
            //2.当一系列业务操作完成之后,我们需要手动提交事务
            sqlSession.commit();
            System.out.println(i);
        }catch (Exception e){
            //3.当操作出现异常,调用事务回滚方法
            sqlSession.rollback();
        }
    }
/** 
* @Description: 修改方法测试,调用MyBatisUtil.getMapper()方法,默认自动提交事务
* @Param: []
* @return: void
* @Author: FF
* @Date: 2024/11/27
*/

    @Test
    public void updateStudent() throws IOException {
        //MyBatisUtil.getMapper(StudentDao.class)方法默认的是自动提交事务
        StudentDao studentDao = MyBatisUtil.getMapper(StudentDao.class);
        Student student = new Student();
        student.setStu_num("1");
        student.setStu_name("蔡文姬");
        student.setStu_age(18);
        student.setStu_denger("女");
        student.setStu_tel("123312312");
        student.setStu_qq("877877");
        student.setCid(2);
        int i = studentDao.updateStudent(student);

        assertEquals(1, 1);

    }

    @Test
    public void selectAllStudent() {
        StudentDao studentDao = MyBatisUtil.getMapper(StudentDao.class);
        List<Student> students = studentDao.selectAllStudent();
        assertNotNull(students);
        System.out.println(students.size());
        for (Student student : students) {
            System.out.println(student);
        }
    }

    @Test
    public void selectStudentById() throws IOException {

        StudentDao studentDao = MyBatisUtil.getMapper(StudentDao.class);
        Student student = studentDao.selectStudentById("3");
        System.out.println(student);
    }

    @Test
    public void countStudent() throws IOException {
        StudentDao studentDao = MyBatisUtil.getMapper(StudentDao.class);
        int count = studentDao.countStudent();
        System.out.println(count);
    }

    @Test
    public void selectStudentByPage() {
        StudentDao mapperer = MyBatisUtil.getMapper(StudentDao.class);
        List<Student> students = mapperer.selectStudentByPage(0,5);
        assertNotNull(students);
        System.out.println(students.size());
        for (Student student : students) {
            System.out.println(student);
        }
    }
}

pom.xml

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.feng</groupId>
  <artifactId>mybatis_project</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>mybatis_project Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
    <!-- mysql-connector-j -->
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>8.2.0</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.6</version>
    </dependency>
    <!-- lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.30</version>
      <scope>provided</scope>
    </dependency>

  </dependencies>
  <build>
    <finalName>mybatis_project</finalName>
  </build>
</project>

工程目录结构
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QChart数据可视化

目录 一、QChart基本介绍 1.1 QChart基本概念与用途 1.2 主要类的介绍 1.2.1 QChartView类 1.2.2 QChart类 1.2.3QAbstractSeries类 1.2.4 QAbstractAxis类 1.2.5 QLegendMarker 二、与图表交互 1. 动态绘制数据 2. 深入数据 3. 缩放和滚动 4. 鼠标悬停 三、主题 …

互联网视频推拉流EasyDSS视频直播点播平台视频转码有哪些技术特点和应用?

视频转码本质上是一个先解码再编码的过程。在转码过程中&#xff0c;原始视频码流首先被解码成原始图像数据&#xff0c;然后再根据目标编码标准、分辨率、帧率、码率等参数重新进行编码。这样&#xff0c;转换前后的码流可能遵循相同的视频编码标准&#xff0c;也可能不遵循。…

黑马程序员Java项目实战《苍穹外卖》Day01

苍穹外卖-day01 课程内容 软件开发整体介绍苍穹外卖项目介绍开发环境搭建导入接口文档Swagger 项目整体效果展示&#xff1a; ​ 管理端-外卖商家使用 ​ 用户端-点餐用户使用 当我们完成该项目的学习&#xff0c;可以培养以下能力&#xff1a; 1. 软件开发整体介绍 作为一…

使用phpStudy小皮面板模拟后端服务器,搭建H5网站运行生产环境

一.下载安装小皮 小皮面板官网下载网址&#xff1a;小皮面板(phpstudy) - 让天下没有难配的服务器环境&#xff01; 安装说明&#xff08;特别注意&#xff09; 1. 安装路径不能包含“中文”或者“空格”&#xff0c;否则会报错&#xff08;例如错误提示&#xff1a;Cant cha…

No.1 杀戮尖塔Godot复刻|项目概述|场景设置

项目概述 含有47个脚本文件&#xff0c;包括1185行代码&#xff0c;最长的脚本有111行 Battle Node——战斗节点 start_battle()——开始战斗turn management——管理回合win/lose conditions——识别输赢条件 EnemyHandler——敌人处理程序 enemy turn management——管理…

化工专业如何转软工

在当今数字化时代&#xff0c;跨考软件工程已经成为许多理工科学子的一个重要选择。化工专业的同学有着扎实的理工科基础&#xff0c;尤其是数学功底&#xff0c;这对于转向计算机领域是一个天然的优势。让我们详细探讨如何规划这段跨考之路。 编程语言的选择是入门的第一步。…

《Opencv》基础操作<1>

目录 一、Opencv简介 主要特点&#xff1a; 应用领域&#xff1a; 二、基础操作 1、模块导入 2、图片的读取和显示 &#xff08;1&#xff09;、读取 &#xff08;2&#xff09;、显示 3、 图片的保存 4、获取图像的基本属性 5、图像转灰度图 6、图像的截取 7、图…

论文阅读:A Software Platform for Manipulating theCamera Imaging Pipeline

论文代码开源链接&#xff1a; A Software Platform for Manipulating the Camera Imaging Pipelinehttps://karaimer.github.io/camera-pipeline/摘要&#xff1a;论文提出了一个Pipline软件平台&#xff0c;可以方便地访问相机成像Pipline的每个阶段。该软件允许修改单个模块…

ChatGPT的应用场景:开启无限可能的大门

ChatGPT的应用场景:开启无限可能的大门 随着人工智能技术的快速发展,自然语言处理领域迎来了前所未有的突破。其中,ChatGPT作为一款基于Transformer架构的语言模型,凭借其强大的语言理解和生成能力,在多个行业和场景中展现出了广泛的应用潜力。以下是ChatGPT八个最具代表…

音视频-什么是帧,视频为什么要编码

帧就是动画中的一张图片&#xff0c;这相当于电影胶片上的一个镜头&#xff0c;一帧就是一幅静止的画面&#xff0c;连续的帧就形成了我们看到的动画和视频。 但是直接采集后没经过处理的视频&#xff0c;其实是没有办法真正在互联网上进行传输的。以一张1920乘1080的图片为例&…

“蜀道山”高校联合公益赛 Web (部分)

文章目录 奶龙牌WAF海关警察训练平台恶意代码检测器 奶龙牌WAF <?php if ($_SERVER[REQUEST_METHOD] POST && isset($_FILES[upload_file])) {$file $_FILES[upload_file];if ($file[error] UPLOAD_ERR_OK) {$name isset($_GET[name]) ? $_GET[name] : basen…

【JavaEE初阶 — 网络原理】初识网络原理

目录 1. 网络发展史 1.1 独立模式 1.2 网络互连 1.2.1 网络互联的背景 1.2.2 网络互联的定义 1.3 局域网LAN 1.4 广域网WAN 2. 网络通信基础 2.1 IP地址 2.2 端口号 2.3 认识协议 2.4 五元组 2.5 协议分层 2.5.1 分…

Linux的介绍及虚拟机centOS系统的下载与应用

1、什么是Linux Linux 是一种类 Unix 操作系统&#xff0c;它的内核&#xff08;Kernel&#xff09;由 Linus Torvalds 于 1991 年首次发布。作为一个开源、免费的操作系统&#xff0c;Linux 被广泛用于服务器、桌面计算机、嵌入式设备、移动设备等各种场景。 1、操作系统 操…

Leetcode打卡:交替组II

执行结果&#xff1a;通过 题目&#xff1a;3208 交替组II 给你一个整数数组 colors 和一个整数 k &#xff0c;colors表示一个由红色和蓝色瓷砖组成的环&#xff0c;第 i 块瓷砖的颜色为 colors[i] &#xff1a; colors[i] 0 表示第 i 块瓷砖的颜色是 红色 。colors[i] 1 …

【ONE·基础算法 || 动态规划(二)】

总言 主要内容&#xff1a;编程题举例&#xff0c;熟悉理解动态规划类题型&#xff08;子数组、子序列问题&#xff09;。                文章目录 总言5、子数组问题&#xff08;数组中连续的一段&#xff09;5.1、最大子数组和&#xff08;medium&#xff09;5.1.…

Qt程序发布及打包成exe安装包

参考:Qt之程序发布以及打包成exe安装包 目录 一、简述 Qt 项目开发完成之后,需要打包发布程序,而因为用户电脑上没有 Qt 配置环境,所以需要将 release 生成的 exe 文件和所依赖的 dll 文件复制到一个文件夹中,然后再用 Inno Setup 打包工具打包成一个 exe 安装包,就可以…

通过抓包,使用frida定位加密位置

首先我们抓取一下我们要测试的app的某一个目标api&#xff0c;通过抓api的包&#xff0c;得到关键字。 例如&#xff1a;关键字&#xff1a;x-sap-ri 我们得到想要的关键字后&#xff0c;通过拦截 类&#xff0c;寻找我们的关键字&#xff0c;及找到发包收包的位置&#xff0c…

MFC图形函数学习12——位图操作函数

位图即后缀为bmp的图形文件&#xff0c;MFC中有专门的函数处理这种格式的图形文件。这些函数只能处理作为MFC资源的bmp图&#xff0c;没有操作文件的功能&#xff0c;受限较多&#xff0c;一般常作为程序窗口界面图片、显示背景图片等用途。有关位图操作的步骤、相关函数等介绍…

钟睒睒的“傲慢与偏见”

文章内容根据网络内容整理形成 最近&#xff0c;钟睒睒关于绿瓶水不适合长期饮用的言论&#xff0c;在网上引起了一番新的热议&#xff0c;让刚平静不久的包装饮用水竞争&#xff0c;再次掀起一阵波澜&#xff0c;同时&#xff0c;其对于企业家直播带货的等系列看法&#xff0c…

比亚迪降价令背后的反思,创新还是压榨?

科技新知 原创作者丨依蔓 编辑丨蕨影 比亚迪要求供应商明年起降价10%&#xff1f; 近日&#xff0c;网传一封有关比亚迪乘用车要求供应商降价的邮件&#xff0c;署名为比亚迪集团执行副总裁、乘用车首席运营官何志奇。 邮件称&#xff0c;2025年市场竞争将更加激烈&#xff0…