最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

自己手寫Mybatis通用batchInsert問題

 更新時間:2022年11月17日 11:24:25   作者:OK_boom  
這篇文章主要介紹了自己手寫Mybatis通用batchInsert問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

自己手寫Mybatis通用batchInsert

寫完才在群里有人告知本來tk mybatis就提供了批量insert的功能,那就放上來做個紀念吧.

先寫個數(shù)據(jù)字典(其實tk mybatis自身也有相應的功能)。

/**
?* Mybatis 帶緩沖功能的數(shù)據(jù)字典
?* Created by rocklee on 2019/8/10 23:27
?*/
public class MybatisDictionary {
? private static ConcurrentHashMap<Class<?>, String> entityClass2TableName=new ConcurrentHashMap<>();
? private static ConcurrentHashMap<Class<?>, String> entityClass2Columns=new ConcurrentHashMap<>();
? private static ConcurrentHashMap<Class<?>, List<String>> entityClass2FieldsList=new ConcurrentHashMap<>();
? private static ConcurrentHashMap<Class<?>, Hashtable<Field,String>> entityClass2Fields=new ConcurrentHashMap<>();
?
? public static String getTableName(Class<?> pvEntityClass){
? ? String lvsRet=entityClass2TableName.get(pvEntityClass);
? ? if (lvsRet!=null)return lvsRet;
? ? Table lvTable= pvEntityClass.getAnnotation(Table.class);
? ? if (lvTable==null){
? ? ? throw new RuntimeException(pvEntityClass.getName()+"不是有效的Entity類,缺少@Table標識");
? ? }
? ? lvsRet=lvTable.name();
? ? entityClass2TableName.put(pvEntityClass,lvsRet);
? ? return lvsRet;
? }
? public static String getColumns(Class<?> pvEntityClass){
? ? String lvsRet=entityClass2Columns.get(pvEntityClass);
? ? if (lvsRet!=null)return lvsRet;
? ? List<String> lvItems=new ArrayList<>();
? ? for (Field field:pvEntityClass.getDeclaredFields()){
? ? ? Column lvColumn=field.getAnnotation(Column.class);
? ? ? if (lvColumn==null)continue;
? ? ? lvItems.add(lvColumn.name());
? ? }
? ? lvsRet= Util.toString(lvItems,",");
? ? entityClass2Columns.put(pvEntityClass,lvsRet);
? ? return lvsRet;
? }
? public static List<String> getFieldsList(Class<?> pvEntityClass){
? ? List<String> lvRet=entityClass2FieldsList.get(pvEntityClass);
? ? if (lvRet!=null)return lvRet;
? ? lvRet=new ArrayList<>();
? ? for (Field field:pvEntityClass.getDeclaredFields()){
? ? ? Column lvColumn=field.getAnnotation(Column.class);
? ? ? if (lvColumn==null)continue;
? ? ? lvRet.add(field.getName());
? ? }
? ? entityClass2FieldsList.put(pvEntityClass,lvRet);
? ? return lvRet;
? }
? public static Hashtable<Field,String>getFields(Class<?> pvEntityClass){
? ? Hashtable<Field,String> lvRet=entityClass2Fields.get(pvEntityClass);
? ? if (lvRet!=null)return lvRet;
? ? lvRet=new Hashtable<Field,String>();
? ? for (Field field:pvEntityClass.getDeclaredFields()){
? ? ? Column lvColumn=field.getAnnotation(Column.class);
? ? ? if (lvColumn==null)continue;
? ? ? lvRet.put(field,lvColumn.name());
? ? }
? ? entityClass2Fields.put(pvEntityClass,lvRet);
? ? return lvRet;
? }
}

再寫SqlProvider:

/** 批處理SQL處理器
?* Created by rocklee on 2019/8/10 23:11
?*/
public class BatchSqlProvider ?extends MapperTemplate {
? public BatchSqlProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
? ? super(mapperClass, mapperHelper);
? }
?
? public String batchInsert(MappedStatement ms) {
? ? final Class<?> entityClass = getEntityClass(ms);
? ? StringBuilder sb=new StringBuilder();
? ? sb.append("INSERT INTO "+MybatisDictionary.getTableName(entityClass));
? ? sb.append("\n<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
? ? sb.append(MybatisDictionary.getColumns(entityClass));
? ? sb.append("</trim> \n");
? ? sb.append("\nVALUES\n");
? ? sb.append("<foreach collection=\"list\" item=\"record\" separator=\",\">");
? ? sb.append("\n");
? ? sb.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
? ? String lvsValFields="#{record."+ Util.toString(MybatisDictionary.getFieldsList(entityClass),"},#{record.")
? ? ? ? ? ? +"}";
? ? sb.append(lvsValFields);
? ? sb.append("\n</trim>\n</foreach>");
? ? return sb.toString() ;
? }
?
}

Mapper: 

/**
?* Created by rocklee on 2019/8/11 0:24
?*/
@RegisterMapper
public interface BatchMapper<T> {
? /***
? ?* 批量插入
? ?* @param pvToInsertList
? ?* @return
? ?*/
? @InsertProvider(type = BatchSqlProvider.class, ?method = "dynamicSQL")
? int batchInsert(List<? extends T> pvToInsertList);
}

這是基于tk的MapperTemplate 寫的sqlprovider,傳入的是MappedStatement,這時候返回的SQL不是raw SQL,還能支持<if>,<foreach>這些mybatis表達式, 而如果用與mapper接口相同的參數(shù)方式返回sql,那這些表達式則不會被mybatis解釋,而直接傳到database服務器那邊, 導致異常。

最后要提一下, tkmybatis帶自了一個insertListMapper,我們extends它就可以實現(xiàn)批量insert了:

使用Mapper通用insert方法遇到的問題

環(huán)境

  • spingboot
  • sqlserver
  • mybatis
  • Mapper

insert拋出不能為標識列插入顯式值的異常

原因:表的自增主鍵,通常情況下不需要直接在insert語句中指定設值。查看控制臺打印語句,發(fā)現(xiàn)是對該字段做了插入。

解決方法:該表對應實體中,在不需要做插入的字段上增加@Column(insertable = false)。

延伸:@Column還有一些值可供設值,

  • name 被標注字段在數(shù)據(jù)庫表中所對應字段的名稱;
  • unique 表示該字段是否為唯一標識,默認為false;
  • nullable表示該字段是否可以為null值,默認為true;
  • insertable表示在使用“INSERT”腳本插入數(shù)據(jù)時,是否需要插入該字段的值。
  • updatable表示在使用“UPDATE”腳本插入數(shù)據(jù)時,是否需要更新該字段的值。
  • columnDefinition表示創(chuàng)建表時,該字段創(chuàng)建的SQL語句,一般用于通過Entity生成表定義時使用。
  • table 定義了包含當前字段的表名。
  • length表示字段的長度,當字段的類型為varchar時,該屬性才有效,默認為255個字符。
  • precision屬性和scale屬性表示精度,當字段類型為double時,precision表示數(shù)值的總長度,scale表示小數(shù)點所占的位數(shù)。
  • insert不能返回自增id的問題

這個問題,用過給自增id加 @GeneratedValue(generator =’“JDBC”)等,無效;

只能先不用Mapper通用的方法,自己定義一個insert接口,在xml中設置usergeneratedkeys=true ,keyProperty=“id” 這樣會把自增得到的id值注入到實體id參數(shù)中。

(該問題待解決,有知道的朋友指點下,注意數(shù)據(jù)庫是SqlServer)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • mybatis引用其他文件中的sql片段的實現(xiàn)

    mybatis引用其他文件中的sql片段的實現(xiàn)

    Mybatis中也是支持引用其他Mapper文件中的SQL片段的,本文就來介紹一下如何使用,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-03-03
  • Java正則表達式Pattern和Matcher原理詳解

    Java正則表達式Pattern和Matcher原理詳解

    這篇文章主要介紹了Java正則表達式Pattern和Matcher原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Java?empty、null、blank的區(qū)別小結

    Java?empty、null、blank的區(qū)別小結

    本文主要介紹了Java?empty、null、blank的區(qū)別小結,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-06-06
  • Java static方法用法實戰(zhàn)案例總結

    Java static方法用法實戰(zhàn)案例總結

    這篇文章主要介紹了Java static方法用法,結合具體案例形式總結分析了java static方法功能、使用方法及相關操作注意事項,需要的朋友可以參考下
    2019-09-09
  • Spring注解之Service用法及示例詳解

    Spring注解之Service用法及示例詳解

    使用 @Service 注解可以將一個類聲明為業(yè)務邏輯組件,并將其對象存入 Spring 容器中,在控制器類中,通過注入該組件的實例,即可調(diào)用其中的方法,這篇文章主要介紹了Spring注解之Service用法及示例詳解,需要的朋友可以參考下
    2024-04-04
  • Java項目中實現(xiàn)使用traceId跟蹤請求全流程日志

    Java項目中實現(xiàn)使用traceId跟蹤請求全流程日志

    這篇文章主要介紹了Java項目中實現(xiàn)使用traceId跟蹤請求全流程日志方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Tomcat版本與Java版本的關系及說明

    Tomcat版本與Java版本的關系及說明

    這篇文章主要介紹了Tomcat版本與Java版本的關系及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • Java 十大排序算法之希爾排序刨析

    Java 十大排序算法之希爾排序刨析

    希爾排序是希爾(Donald Shell)于1959年提出的一種排序算法。希爾排序也是一種插入排序,它是簡單插入排序經(jīng)過改進之后的一個更高效的版本,也稱為縮小增量排序,同時該算法是沖破O(n2)的第一批算法之一。本文會以圖解的方式詳細介紹希爾排序的基本思想及其代碼實現(xiàn)
    2021-11-11
  • 實例講解Java設計模式編程中的OCP開閉原則

    實例講解Java設計模式編程中的OCP開閉原則

    這篇文章主要介紹了Java設計模式編程中的開閉原則,開閉原則的大意被作者總結為用抽象構建框架,用實現(xiàn)擴展細節(jié),需要的朋友可以參考下
    2016-02-02
  • maven的pom.xml中profiles的作用詳解

    maven的pom.xml中profiles的作用詳解

    這篇文章主要介紹了maven的pom.xml中profiles的作用詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論

视频| 壤塘县| 容城县| 和硕县| 江华| 丰台区| 大庆市| 正阳县| 桃源县| 安宁市| 土默特左旗| 喀什市| 镇原县| 报价| 繁昌县| 新龙县| 嘉义市| 中阳县| 泾川县| 莫力| 包头市| 孟州市| 宜宾市| 乳山市| 郯城县| 鄂州市| 武强县| 邻水| 循化| 凤翔县| 庆云县| 新竹县| 营口市| 沈阳市| 文山县| 织金县| 南汇区| 安溪县| 云龙县| 许昌县| 阜城县|