记录一次tk mybatis 增加批量更新接口

记录一次tk mybatis 增加批量更新接口

tk mybatis 个人理解就是对mybatis做的一层包装,实现可以对单个对象直接调用,如增删改查的过程,省略了原来mybatis一个个写这种重复sql的过程。其效果类似mybatis-plus。

所需依赖

maven 的pom.xml 增加依赖如下:


    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>2.1.5</version>
    </dependency>

这种其中已经包含mybatis相关依赖包了。

相关mapper文件以及提供实现类


import org.apache.ibatis.annotations.UpdateProvider;

import java.util.List;

/**
 * 批量update
 *
 * @param <T> 不能为空
 */
@tk.mybatis.mapper.annotation.RegisterMapper
public interface UpdateBatchByPrimaryKeySelectiveMapper<T> {

    /**
     * 根据Example条件批量更新实体`record`包含的不是null的属性值
     *
     * @return
     */
    @UpdateProvider(type = BatchExampleProvider.class, method = "dynamicSQL")
    int updateBatchByPrimaryKeySelective(List<? extends T> recordList);

}




import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
import tk.mybatis.mapper.provider.ExampleProvider;

import java.util.Set;


public class BatchExampleProvider extends ExampleProvider {

    public BatchExampleProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }


    /**
     * 拼update sql, 使用case when方式,id为主键
     *
     * @param ms
     * @return
     */
    public String updateBatchByPrimaryKeySelective(MappedStatement ms) {
        final Class<?> entityClass = getEntityClass(ms);
        //开始拼sql
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
        sql.append("<trim prefix=\"set\" suffixOverrides=\",\">");

        //获取全部列
        Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
        for (EntityColumn column : columnList) {
            if (!column.isId() && column.isUpdatable()) {
                sql.append("  <trim prefix=\""+column.getColumn()+" =case\" suffix=\"end,\">");
                sql.append("    <foreach collection=\"list\" item=\"i\" index=\"index\">");
                sql.append("      <if test=\"i."+column.getProperty()+"!=null\">");
                sql.append("         when id=#{i.id} then #{i."+column.getProperty()+"}");
                sql.append("      </if>");
                sql.append("    </foreach>");
                sql.append("  </trim>");
            }
        }

        sql.append("</trim>");
        sql.append("WHERE");
        sql.append(" id IN ");
        sql.append("<trim prefix=\"(\" suffix=\")\">");
        sql.append("<foreach collection=\"list\" separator=\", \" item=\"i\" index=\"index\" >");
        sql.append("#{i.id}");
        sql.append("</foreach>");
        sql.append("</trim>");

        return sql.toString();
    }
}



/**
 * 批量操作接口
 *
 * @param <T>
 * @author
 */
@tk.mybatis.mapper.annotation.RegisterMapper
public interface BatchMapper<T>
        extends UpdateBatchByPrimaryKeySelectiveMapper<T> {
}

其中@tk.mybatis.mapper.annotation.RegisterMapper该注解为了注册对应mapper类,要不然无法被tk使用。

使用方式

编写对应mapper接口时,如果想使用批量更新,直接继承对应类就可以了。

// Mapper是你使用的基类,而BatchMapper是你需要批量更新功能可以增加的。
public interface UserMapper extends Mapper<User>, BatchMapper<User> {
}


// 伪代码 , list为 ArrayList<User>();
userMapper.updateBatchByPrimaryKeySelective(list);

原理简述

其实从上面可以看出,本质就是原来mybatis中的xml文件内容变成根据每个对象的实际内容动态拼接,最终通过动态代理的方式将sql传递给数据库执行并返回结果。

参考

文章代码大部分内容参考:

https://codeleading.com/article/8997929925/

但是根据本人实际遇到的问题做了更改,以及更详细的阐述。

本文额外给出一篇mybatis实现批量更新文章地址,有兴趣的读者可以自行对比。

https://www.cnblogs.com/eternityz/p/12284760.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章