美文网首页SpringBoot
SpringBoot(四、MyBatis,隔离级别,传播行为)

SpringBoot(四、MyBatis,隔离级别,传播行为)

作者: 强某某 | 来源:发表于2019-05-14 10:47 被阅读0次

    SpringBoot集成MyBatis

    常见访问数据库方式

    1、原始java访问数据库

    • 开发流程麻烦

      • 注册驱动/加载驱动

      Class.forName("com.mysql.jdbc.Driver")
      - 建立连接
      > Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbname","root","root");
      - 创建Statement
      - 执行SQL语句
      - 处理结果集
      - 关闭连接,释放资源

    2、apache dbutils框架

    3、jpa框架

    spring-data-jpa:jpa在复杂查询的时候性能不是很好

    4、Hiberante
    ORM:对象关系映射Object Relational Mapping
    企业大都喜欢使用hibernate

    5、Mybatis框架

    • 互联网行业通常使用mybatis
    • 不提供对象和关系模型的直接映射,半ORM

    集成步骤

    • 添加依赖
    <!-- 引入starter-->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
                        
    <!-- MySQL的JDBC驱动包  --> 
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency> 
    
    • 添加配置
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/tjsdemo?useUnicode=true&characterEncoding=utf-8
        username: root
        password: zengqiang789
    mybatis:
      configuration:
        # 开启mybatis的sql打印输出,可以不添加
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    
    • 启动类增加mapper扫描

    @MapperScan("com.techsel.mapper")

    • 书写mapper文件
    public interface User2Mapper {
    
        //$ 是字符串拼接:有注入风险,#可以防止注入
        @Insert("INSERT INTO user2(name,phone,create_time,age) VALUES(#{name},#{phone},#{createTime},#{age})")
        //技巧:保存对象,获取数据库自增id
        @Options(useGeneratedKeys=true, keyProperty="id", keyColumn="id")//keyProperty对应java对象的属性;keyColumn数据库字段
        int insert(User2 user2);
    
        @Select("SELECT * FROM user2")
        @Results({@Result(column = "create_time",property = "createTime")})//下划线转驼峰,column对应数据库字段,property对应java对象属性
        List<User2> getAll();
    
    
        @Select("SELECT * FROM user2 WHERE id = #{id}")
        @Results({@Result(column = "create_time",property = "createTime")})
        User2 findById(Long id);
    
    
        @Update("UPDATE user2 SET name=#{name} WHERE id =#{id}")
        void update(User2 user);
    
        @Delete("DELETE FROM user2 WHERE id =#{userId}") //userId对应参数中的Long userId
        void delete(Long userId);
    }
    
    • 实体类
    public class User2 {
        Integer id;
        String name;
        String phone;
        Integer age;
        Date createTime;
    
        public int getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public Date getCreateTime() {
            return createTime;
        }
    
        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }
    }
    
    • 在使用的地方注入mapper
    @Autowired
    private User2Mapper userMapper2;
    

    隔离级别和传播行为

    1. 讲解场景的隔离级别
    • Serializable: 最严格,串行处理,消耗资源大
    • Repeatable Read:保证了一个事务不会修改已经由另一个事务读取但未提交(回滚)的数据
    • Read Committed:大多数主流数据库的默认事务等级
    • Read Uncommitted:保证了读取过程中不会读取到非法数据。
    1. 讲解常见的传播行为
    • PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务,最常见的选择。
    • PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
    • PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
    • PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起, 两个事务之间没有关系,一个异常,一个提交,不会同时回滚
    • PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    • PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常

    简单案例

    1、service逻辑引入事务 @Transantional(propagation=Propagation.REQUIRED)

    2、service代码

    @Override
    @Transactional 
    public int addAccount() {
        User user = new User();
        user.setAge(9);
        user.setCreateTime(new Date());
        user.setName("事务测试");
        user.setPhone("000121212");
        userMapper.insert(user);
        int a = 1/0;
        return user.getId();
    }
    

    Transantional相关属性

    属性 类型 描述
    value String 可选的限定描述符,指定使用的事务管理器
    propagation enum: Propagation 可选的事务传播行为设置
    isolation enum: Isolation 可选的事务隔离级别设置
    readOnly boolean 读写或只读事务,默认读写
    timeout int (in seconds granularity) 事务超时时间设置
    rollbackFor Class对象数组,必须继承自Throwable 导致事务回滚的异常类数组
    rollbackForClassName 类名数组,必须继承自Throwable 导致事务回滚的异常类名字数组
    noRollbackFor Class对象数组,必须继承自Throwable 不会导致事务回滚的异常类数组
    noRollbackForClassName 类名数组,必须继承自Throwable 不会导致事务回滚的异常类名字数组

    相关文章

      网友评论

        本文标题:SpringBoot(四、MyBatis,隔离级别,传播行为)

        本文链接:https://www.haomeiwen.com/subject/jbgjaqtx.html