記錄一次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

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