mybatis_plus

mybatis_plus

(1)测试

自动拼接sql语句

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3b48e183] was not registered for synchronization because synchronization is not active
2021-04-19 16:18:05.070  INFO 3268 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-04-19 16:18:05.474  INFO 3268 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
JDBC Connection [HikariProxyConnection@526874139 wrapping com.mysql.jdbc.JDBC4Connection@5a034157] will not be managed by Spring
==>  Preparing: UPDATE user SET name=?, age=? WHERE id=?
==> Parameters: 小天(String), 18(Integer), 7(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3b48e183]

(2)自动填充

创建时间,修改时间 自动化完成,不需要手动更新

阿里巴巴开发手册:gmt_create,gmt_modified

几乎所有的表都要配置,自动化

数据库级别

1)在表中新增字段(需要设置timestamp类型)

create_time,create_user

private Date createTime;
private Date updateTime;

代码级别

(1)修改数据库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i5LNb4AY-1623747912237)(C:\Users\root\AppData\Roaming\Typora\typora-user-images\image-20210419164641845.png)]

(2)添加注解

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private int age;
    private String email;
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    //开始的时候两个字段都要有内容
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;


}

(3)编写处理器来处理这个注解

package com.example.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

//加到ioc容器中
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入时填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill...");
        // default MetaObjectHandler setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        this.setFieldValByName("createTime", new Date(), metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill...");
        this.setFieldValByName("updateTime", new Date(), metaObject);

    }
}

(4)结果

Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6a6f6c7e] was not registered for synchronization because synchronization is not active
2021-04-19 17:01:25.588  INFO 8220 --- [           main] com.example.handler.MyMetaObjectHandler  : start update fill...
2021-04-19 17:01:25.597  INFO 8220 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
2021-04-19 17:01:25.925  INFO 8220 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
JDBC Connection [HikariProxyConnection@1679401185 wrapping com.mysql.jdbc.JDBC4Connection@280d4882] will not be managed by Spring
==>  Preparing: UPDATE user SET name=?, age=?, update_time=? WHERE id=?
==> Parameters: 李继(String), 68(Integer), 2021-04-19 17:01:25.588(Timestamp), 7(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6a6f6c7e]
2021-04-1

(5)插入

==> Preparing: INSERT INTO user ( name, age, create_time, update_time ) VALUES ( ?, ?, ?, ? )
> Parameters: 曹钦(String), 23(Integer), 2021-04-19 17:04:19.321(Timestamp), null
<
Updates: 1

mysql 锁 CAS

乐观锁

他总认为不会出现问题,无论干什么都不会加锁,出了问题再次更新值测试

悲观锁

他总是认为会出现问题,无论干什么都会上锁再去操作

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败

测试MP乐观锁插件

(1)添加数据库字段

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ODLilEt-1623747912239)(C:\Users\root\AppData\Roaming\Typora\typora-user-images\image-20210419173035953.png)]

(2)增加数据库字段到pojo

@Version
private Integer version;

(3)注册组件

package com.example.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
//自动管理事务,默认管理了
//
@MapperScan("com.example.mapper")
@EnableTransactionManagement
public class MybatisPlusConfig {
    //注册
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

(4)测试

成功

//测试乐观锁
//成功
@Test
public void success() {
    //查询用户信息
    User user = userMapper.selectById(1);
    //单线程修改
    user.setName("zrm");
    user.setEmail("1677");
    int i = userMapper.updateById(user);
    System.out.println(i);
}JDBC Connection [HikariProxyConnection@805536380 wrapping com.mysql.jdbc.JDBC4Connection@38f77cd9] will not be managed by Spring
==>  Preparing: UPDATE user SET name=?, age=?, email=?, update_time=?, version=? WHERE id=? AND version=?
==> Parameters: zrm(String), 68(Integer), 1677(String), 2021-04-19 17:43:02.346(Timestamp), 2(Integer), 1(Long), 1(Integer)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6aa3bfc]

失败

//失败(多线程会失败)
@Test
public void fail() {
    User user1 = userMapper.selectById(1);
    //单线程修改
    user1.setName("于洪111");
    user1.setEmail("28999111");
    //模拟另外一个线程插队操作

    User user2 = userMapper.selectById(1);
    //单线程修改
    user2.setName("于洪222");
    user2.setEmail("28999222");
    //另一个线程抢先完成更新
    userMapper.updateById(user2);

    //如果没有乐观锁会覆盖抢完更新的值
    //可以尝试自旋锁来尝试多次提交
    userMapper.updateById(user1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值