0
点赞
收藏
分享

微信扫一扫

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

搬砖的小木匠 2021-09-27 阅读 54

SpringBoot集成MyBatis

常见访问数据库方式

1、原始java访问数据库

  • 开发流程麻烦

    • 注册驱动/加载驱动

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扫描
  • 书写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 不会导致事务回滚的异常类名字数组
举报

相关推荐

0 条评论