0
点赞
收藏
分享

微信扫一扫

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

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

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 条评论