• SpringBoot:事务的操作(动力)


     


     

     

     

     

    使用MyBatis生成器:

    MyBatis Generator(MBG)由XML配置文件驱动。配置文件会告知 MBG:

    如何连接数据库
    哪些对象需要被生成,以及如何生成它们
    哪些数据表需要被利用来生成对象
    MBG可生成三种文件:

    Java Model Objects(.java)--------POJO
    SQL Map Files(.xml)--------数据库查询映射
    Java Client Objects(.java)--------DAO


    使用MyBatis插件创建Dao、Mapper、实体类:

    首先在pom.xml中添加插件:

    <!--mybatis代码自动生成插件-->
    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.6</version>
        <configuration>
            <!--配置文件的位置:在项目的根目录下,和src平级的-->
            <configurationFile>GeneratorMapper.xml</configurationFile>
            <verbose>true</verbose>
            <overwrite>true</overwrite>
        </configuration>
    </plugin>

    pom.xml:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    4. <modelVersion>4.0.0</modelVersion>
    5. <parent>
    6. <groupId>org.springframework.boot</groupId>
    7. <artifactId>spring-boot-starter-parent</artifactId>
    8. <version>2.7.1</version>
    9. <relativePath/> <!-- lookup parent from repository -->
    10. </parent>
    11. <groupId>com.bjpowernode</groupId>
    12. <artifactId>019-springboot-transactional</artifactId>
    13. <version>0.0.1-SNAPSHOT</version>
    14. <properties>
    15. <java.version>1.8</java.version>
    16. </properties>
    17. <dependencies>
    18. <dependency>
    19. <groupId>org.springframework.boot</groupId>
    20. <artifactId>spring-boot-starter-web</artifactId>
    21. </dependency>
    22. <dependency>
    23. <groupId>org.mybatis.spring.boot</groupId>
    24. <artifactId>mybatis-spring-boot-starter</artifactId>
    25. <version>2.2.2</version>
    26. </dependency>
    27. <dependency>
    28. <groupId>mysql</groupId>
    29. <artifactId>mysql-connector-java</artifactId>
    30. <scope>runtime</scope>
    31. </dependency>
    32. <dependency>
    33. <groupId>org.springframework.boot</groupId>
    34. <artifactId>spring-boot-starter-test</artifactId>
    35. <scope>test</scope>
    36. </dependency>
    37. </dependencies>
    38. <build>
    39. <plugins>
    40. <!--mybatis代码自动生成插件-->
    41. <plugin>
    42. <groupId>org.mybatis.generator</groupId>
    43. <artifactId>mybatis-generator-maven-plugin</artifactId>
    44. <version>1.3.6</version>
    45. <configuration>
    46. <!--配置文件的位置:在项目的根目录下,和src平级的-->
    47. <configurationFile>GeneratorMapper.xml</configurationFile>
    48. <verbose>true</verbose>
    49. <overwrite>true</overwrite>
    50. </configuration>
    51. </plugin>
    52. <plugin>
    53. <groupId>org.springframework.boot</groupId>
    54. <artifactId>spring-boot-maven-plugin</artifactId>
    55. </plugin>
    56. </plugins>
    57. </build>
    58. </project>

     再把GeneratorMapper.xml复制到项目的根目录下,中来跟src同级:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE generatorConfiguration
    3. PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
    4. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    5. <generatorConfiguration>
    6. <!-- 指定连接数据库的JDBC驱动包所在位置,指定到你本机的完整路径 -->
    7. <classPathEntry location="D:\softwares\tools\mysql-connector-java-8.0.22.jar"/>
    8. <!-- 配置table表信息内容体,targetRuntime指定采用MyBatis3的版本 -->
    9. <context id="tables" targetRuntime="MyBatis3">
    10. <!-- 抑制生成注释,由于生成的注释都是英文的,可以不让它生成 -->
    11. <commentGenerator>
    12. <property name="suppressAllComments" value="true" />
    13. </commentGenerator>
    14. <!-- 配置数据库连接信息 -->
    15. <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
    16. connectionURL="jdbc:mysql://localhost:3306/springdb?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=GMT%2B8"
    17. userId="root"
    18. password="123456">
    19. <property name="nullCatalogMeansCurrent" value="true"/>
    20. </jdbcConnection>
    21. <!-- 生成model类,targetPackage指定model类的包名, targetProject指定生成的model放在eclipse的哪个工程下面-->
    22. <javaModelGenerator targetPackage="com.bjpowernode.model"
    23. targetProject="E:\course\SpringBoot\019-springboot-transactional\src\main\java">
    24. <property name="enableSubPackages" value="false" />
    25. <property name="trimStrings" value="false" />
    26. </javaModelGenerator>
    27. <!-- 生成MyBatis的Mapper.xml文件,targetPackage指定mapper.xml文件的包名, targetProject指定生成的mapper.xml放在eclipse的哪个工程下面 -->
    28. <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
    29. <property name="enableSubPackages" value="false" />
    30. </sqlMapGenerator>
    31. <!-- 生成MyBatis的Mapper接口类文件,targetPackage指定Mapper接口类的包名, targetProject指定生成的Mapper接口放在eclipse的哪个工程下面 -->
    32. <javaClientGenerator type="XMLMAPPER" targetPackage="com.bjpowernode.dao" targetProject="src/main/java">
    33. <property name="enableSubPackages" value="false" />
    34. </javaClientGenerator>
    35. <!-- 数据库表名及对应的Java模型类名 -->
    36. <table tableName="student" domainObjectName="Student"
    37. enableCountByExample="false"
    38. enableUpdateByExample="false"
    39. enableDeleteByExample="false"
    40. enableSelectByExample="false"
    41. selectByExampleQueryId="false"/>
    42. </context>
    43. </generatorConfiguration>

    进行修改插件所需的配置文件的内容GenetatorMapper.xml:

    MyBatis Generator : Table Configuration scheme.table matched more than one table

    [WARNING] Table Configuration student matched more than one table (springdb..student,studentinfo..student,user..student,mybatis..student)

    注意:如果生成有问题!!!
    在使用生成器生成代码的时候遇到了这个错误, 现象就是某个类中出来了数据库表里面没有的字段,非常奇怪.

    解决方法是在生成器的配置文件里的数据库连接地址(就是jdbcUrl)中添加这个参数:

    nullCatalogMeansCurrent=true
    大概就是这个样子:

    <!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
    <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/security"
                    userId="root"
                    password="root">
        <!--MySQL 8.x 需要指定服务器的时区-->
        <property name="serverTimezone" value="UTC"/>
        <!--MySQL 不支持 schema 或者 catalog 所以需要添加这个-->
        <!--参考 : http://www.mybatis.org/generator/usage/mysql.html-->
        <property name="nullCatalogMeansCurrent" value="true"/>
    </jdbcConnection>

     

     使用Maven中的:双击就自动生成了对应的内容:

    以下是自动生成的代码:

    StudentMapper接口:

    1. package com.bjpowernode.dao;
    2. import com.bjpowernode.model.Student;
    3. public interface StudentMapper {
    4. int deleteByPrimaryKey(Integer id);
    5. int insert(Student record);
    6. int insertSelective(Student record);
    7. Student selectByPrimaryKey(Integer id);
    8. int updateByPrimaryKeySelective(Student record);
    9. int updateByPrimaryKey(Student record);
    10. }

     Student类:

    1. package com.bjpowernode.model;
    2. public class Student {
    3. private Integer id;
    4. private String name;
    5. private Integer age;
    6. public Integer getId() {
    7. return id;
    8. }
    9. public void setId(Integer id) {
    10. this.id = id;
    11. }
    12. public String getName() {
    13. return name;
    14. }
    15. public void setName(String name) {
    16. this.name = name;
    17. }
    18. public Integer getAge() {
    19. return age;
    20. }
    21. public void setAge(Integer age) {
    22. this.age = age;
    23. }
    24. }

    StudentMapper.xml:

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3. <mapper namespace="com.bjpowernode.dao.StudentMapper">
    4. <resultMap id="BaseResultMap" type="com.bjpowernode.model.Student">
    5. <id column="id" jdbcType="INTEGER" property="id" />
    6. <result column="name" jdbcType="VARCHAR" property="name" />
    7. <result column="age" jdbcType="INTEGER" property="age" />
    8. </resultMap>
    9. <sql id="Base_Column_List">
    10. id, name, age
    11. </sql>
    12. <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    13. select
    14. <include refid="Base_Column_List" />
    15. from student
    16. where id = #{id,jdbcType=INTEGER}
    17. </select>
    18. <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    19. delete from student
    20. where id = #{id,jdbcType=INTEGER}
    21. </delete>
    22. <insert id="insert" parameterType="com.bjpowernode.model.Student">
    23. insert into student (id, name, age
    24. )
    25. values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR}, #{age,jdbcType=INTEGER}
    26. )
    27. </insert>
    28. <insert id="insertSelective" parameterType="com.bjpowernode.model.Student">
    29. insert into student
    30. <trim prefix="(" suffix=")" suffixOverrides=",">
    31. <if test="id != null">
    32. id,
    33. </if>
    34. <if test="name != null">
    35. name,
    36. </if>
    37. <if test="age != null">
    38. age,
    39. </if>
    40. </trim>
    41. <trim prefix="values (" suffix=")" suffixOverrides=",">
    42. <if test="id != null">
    43. #{id,jdbcType=INTEGER},
    44. </if>
    45. <if test="name != null">
    46. #{name,jdbcType=VARCHAR},
    47. </if>
    48. <if test="age != null">
    49. #{age,jdbcType=INTEGER},
    50. </if>
    51. </trim>
    52. </insert>
    53. <update id="updateByPrimaryKeySelective" parameterType="com.bjpowernode.model.Student">
    54. update student
    55. <set>
    56. <if test="name != null">
    57. name = #{name,jdbcType=VARCHAR},
    58. </if>
    59. <if test="age != null">
    60. age = #{age,jdbcType=INTEGER},
    61. </if>
    62. </set>
    63. where id = #{id,jdbcType=INTEGER}
    64. </update>
    65. <update id="updateByPrimaryKey" parameterType="com.bjpowernode.model.Student">
    66. update student
    67. set name = #{name,jdbcType=VARCHAR},
    68. age = #{age,jdbcType=INTEGER}
    69. where id = #{id,jdbcType=INTEGER}
    70. </update>
    71. </mapper>

     


     配置文件application.properties:

    1. #设置端口
    2. server.port=9002
    3. #上下文
    4. server.servlet.context-path=/mytrans
    5. #设置连接数据库 mysql驱动新版的驱动类
    6. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    7. #连接数据库的url ?后是连接数据库提供的参数 useUnicode:表示用的是useUnicode编码 characterEncoding:表示字符集 serverTimezone:表示时区 GMT:标准时区 8:表示加8小时,我们的时区跟标准时区差8小时
    8. spring.datasource.url=jdbc:mysql://localhost:3306/springdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
    9. #数据库连接名字
    10. spring.datasource.username=root
    11. #数据库连接密码
    12. spring.datasource.password=123456
    13. #指定mapper文件的位置
    14. mybatis.mapper-locations=classpath:mapper/*.xml
    15. #指定mybatis的日志 将这个日志输出到控制台上
    16. mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

     创建StudentService:

    1. package com.bjpowernode.service;
    2. import com.bjpowernode.model.Student;
    3. public interface StudentService {
    4. int addStudent(Student student);
    5. }

    创建实现类StudentServiceImpl:在这里抛出了一个异常,事务会回滚,不会插入数据库

    1. package com.bjpowernode.service.impl;
    2. import com.bjpowernode.dao.StudentMapper;
    3. import com.bjpowernode.model.Student;
    4. import com.bjpowernode.service.StudentService;
    5. import org.springframework.stereotype.Service;
    6. import org.springframework.transaction.annotation.Transactional;
    7. import javax.annotation.Resource;
    8. @Service
    9. public class StudentServiceImpl implements StudentService {
    10. @Resource
    11. private StudentMapper studentDao;
    12. /*@Transactional :表示方法有事务支持
    13. * 默认:使用库的隔离级别,REQUIRED-传播行为 超时时间- -1
    14. * */
    15. @Transactional
    16. @Override
    17. public int addStudent(Student student) {
    18. System.out.println("业务方法addStudent");
    19. int rows = studentDao.insert(student);
    20. System.out.println("执行sql语句");
    21. //抛出一个运行时异常,目的是回滚事务
    22. int m=10/0;
    23. return rows;
    24. }
    25. }

    创建控制类:StudentController:

     

    1. package com.bjpowernode.controller;
    2. import com.bjpowernode.model.Student;
    3. import com.bjpowernode.service.StudentService;
    4. import org.springframework.stereotype.Controller;
    5. import org.springframework.web.bind.annotation.RequestMapping;
    6. import org.springframework.web.bind.annotation.ResponseBody;
    7. import javax.annotation.Resource;
    8. @Controller
    9. public class StudentController {
    10. @Resource //注解进行注入
    11. private StudentService service;
    12. @RequestMapping("/addStudent")
    13. @ResponseBody
    14. public String addStudent(String name,Integer age){
    15. Student s1=new Student();
    16. s1.setName(name);
    17. s1.setAge(age);
    18. int rows = service.addStudent(s1);
    19. return "添加学生:"+rows;
    20. }
    21. }

    主启动类Application:加dao的扫描注解,启动项目

    1. package com.bjpowernode;
    2. import org.mybatis.spring.annotation.MapperScan;
    3. import org.springframework.boot.SpringApplication;
    4. import org.springframework.boot.autoconfigure.SpringBootApplication;
    5. import org.springframework.transaction.annotation.EnableTransactionManagement;
    6. /*@EnableTransactionManagement:启用事务管理器
    7. * 这个注解可以不加,但是最好加上
    8. * */
    9. @EnableTransactionManagement
    10. @SpringBootApplication
    11. @MapperScan(basePackages = "com.bjpowernode.dao") //注解让他扫描到Dao
    12. public class Application {
    13. public static void main(String[] args) {
    14. SpringApplication.run(Application.class, args);
    15. }
    16. }

    浏览器输入数据: 

     控制台抛出了异常

     把StudentServiceImpl:中的运行时异常注释掉,重新启动项目

    //抛出一个运行时异常,目的是回滚事务
    int m=10/0;

     

     

     

     正常添加进去,查看数据库:数据库也添加成功

     张强的id为5,中间少一个4,正是刚才出错的,刚才已经在数据库添加了数据,报异常了回滚,这条数据的操作撤销了,主键字段是逐条增长的,用过4了,就不能再用了,所以在添加我变为5

  • 相关阅读:
    【Python项目】过马路游戏
    Reactjs数据篇
    RL 实践(0)—— 及第平台辛丑年冬赛季【Rule-based policy】
    Java语言有多少优势(总结版)
    如何查看MySQL的安装位置
    VSCode 居然是个娱乐软件?让你 high 到爆的几款插件
    通达OA 2016网络智能办公系统 handle.php SQL注入漏洞
    【无标题】
    C++——编译和链接原理笔记
    Java CAS基本原理
  • 原文地址:https://blog.csdn.net/dengfengling999/article/details/125551594