扩展mybatis plus支持for update

一、背景

  1. 在账户流水表等重要数据更新,每个账户都需要单线程执行,防止无效多线程执行。
  2. MybatisPlus官方并没有针此处场景进行支持

二、 实现方式

  1. 改造queryWrapper新增lock()方法
  2. 在BaseMapper新增通用方法
  3. 最简单使用queryWrapper.last(" for update") !!!

三、环境

<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.2.0</version>
</dependency>

四、注入自定义批量插入sql

因为只需要改造selectOne方法,那直接CV就好

  1. sql模板
public class SelectOneForUpdate extends AbstractMethod {

    private static final String MAPPER_METHOD = "selectOneForUpdate";
    private static final String SQL_TEMPLATE = "<script>%s SELECT %s FROM %s %s %s for update\n</script>";

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(SQL_TEMPLATE,
                sqlFirst(), sqlSelectColumns(tableInfo, true), tableInfo.getTableName(),
                sqlWhereEntityWrapper(true, tableInfo), sqlComment()), modelClass);
        return this.addSelectMappedStatementForTable(mapperClass, MAPPER_METHOD, sqlSource, tableInfo);
    }
}
public class SelectListForUpdate extends AbstractMethod {

    private static final String MAPPER_METHOD = "selectListForUpdate";
    private static final String SQL_TEMPLATE = "<script>%s SELECT %s FROM %s %s %s for update\n</script>";

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String sql = String.format(SQL_TEMPLATE, sqlFirst(), sqlSelectColumns(tableInfo, true), tableInfo.getTableName(),
                sqlWhereEntityWrapper(true, tableInfo), sqlComment());
        SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
        return this.addSelectMappedStatementForTable(mapperClass, MAPPER_METHOD, sqlSource, tableInfo);
    }
}
  1. 注入sql
public class CustomerSqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass);
	methodList.add(new SelectOneForUpdate());
	methodList.add(new SelectListForUpdate());
        return methodList;
    }
}
  1. 通用mapper
public interface CommonMapper<T> extends BaseMapper<T> {

    /**
     * 根据 entity 条件,查询一条记录,并锁定
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    T selectOneForUpdate(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

	
    /**
     * 根据 entity 条件,查询全部记录,并锁定
     *
     * @param queryWrapper 实体对象封装操作类(可以为 null)
     */
    List<T> selectListForUpdate(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}
  1. 通用Service
public class CommonServiceImpl<M extends CommonMapper<T>, T> extends ServiceImpl<M, T> {

    
    public T getOneForUpdate(Wrapper<T> queryWrapper) {
        return baseMapper.selectOneForUpdate(queryWrapper);
    }
	
	
    public List<T> listForUpdate(Wrapper<T> queryWrapper) {
        return baseMapper.selectListForUpdate(queryWrapper);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值