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

自己手寫(xiě)Mybatis通用batchInsert問(wèn)題

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

自己手寫(xiě)Mybatis通用batchInsert

寫(xiě)完才在群里有人告知本來(lái)tk mybatis就提供了批量insert的功能,那就放上來(lái)做個(gè)紀(jì)念吧.

先寫(xiě)個(gè)數(shù)據(jù)字典(其實(shí)tk mybatis自身也有相應(yīng)的功能)。

/**
?* 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類(lèi),缺少@Table標(biāo)識(shí)");
? ? }
? ? 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;
? }
}

再寫(xiě)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 寫(xiě)的sqlprovider,傳入的是MappedStatement,這時(shí)候返回的SQL不是raw SQL,還能支持<if>,<foreach>這些mybatis表達(dá)式, 而如果用與mapper接口相同的參數(shù)方式返回sql,那這些表達(dá)式則不會(huì)被mybatis解釋?zhuān)苯觽鞯絛atabase服務(wù)器那邊, 導(dǎo)致異常。

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

使用Mapper通用insert方法遇到的問(wèn)題

環(huán)境

  • spingboot
  • sqlserver
  • mybatis
  • Mapper

insert拋出不能為標(biāo)識(shí)列插入顯式值的異常

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

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

延伸:@Column還有一些值可供設(shè)值,

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

這個(gè)問(wèn)題,用過(guò)給自增id加 @GeneratedValue(generator =’“JDBC”)等,無(wú)效;

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

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

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

相關(guān)文章

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

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

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

    Java正則表達(dá)式Pattern和Matcher原理詳解

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

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

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

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

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

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

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

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

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

    Tomcat版本與Java版本的關(guān)系及說(shuō)明

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

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

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

    實(shí)例講解Java設(shè)計(jì)模式編程中的OCP開(kāi)閉原則

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

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

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

最新評(píng)論

巫山县| 邵阳县| 罗田县| 武邑县| 阳山县| 武山县| 咸丰县| 炉霍县| 澄城县| 阿拉善左旗| 黑龙江省| 苏尼特左旗| 岑溪市| 罗甸县| 高台县| 思茅市| 东丽区| 基隆市| 同德县| 霍林郭勒市| 长顺县| 壶关县| 红河县| 丹江口市| 和平区| 临安市| 昌邑市| 德阳市| 松江区| 峡江县| 富蕴县| 铁力市| 兴安县| 新邵县| 东源县| 基隆市| 页游| 绥滨县| 罗山县| 建水县| 济南市|