参考来自:https://stackoverflow.com/questions/1109061/insert-on-duplicate-update-in-postgresql/1109198#1109198

功能需求:接口定义中包含字段update,当它为true时,批量插入中有记录造成唯一键重复时,不报异常,而是执行更新。

1.接口定义

 {
"resources":
[
{
"name":"*",
"display_name": "*",
"description": "*",
"service": "*"
},
....
],
"update":"true" }

2.代码

原本是通过报的异常 DuplicateKeyException,在catch语句里执行update。但是这样操作有一个问题,后面单独说。

             try {
resourceDao.insert(resource); } catch (DuplicateKeyException e) {
// if (StringUtils.equals(update,Constants.KEY_FALSE)) {
// throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
// }else if (StringUtils.equals(update,Constants.KEY_TRUE)){
// resourceDao.update(resource);
// }
throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
} catch (Exception e) {
throw new AuthServiceException(ErrorCode.RESOURCE_CREATE_FAILED, new Object[]{resource.getFdResName()}, e);
}

3.SQL语句

示例语句:

1 INSERT INTO the_table (id, column_1, column_2)
2 VALUES (1, 'A', 'X')3 ON CONFLICT (唯一键) DO UPDATE
4 SET column_1 ='A',
5 column_2 = 'X';

完整语句:

     <insert id="insert" parameterType="Resource" useGeneratedKeys="true" keyProperty="fdResid">
INSERT INTO t_resource
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="fdResName != null">
fd_res_name,
</if>
<if test="fdDisplayName != null">
fd_display_name,
</if>
<if test="fdResDesc != null">
fd_res_desc,
</if>
<if test="fdTenantId != null">
fd_tenantid,
</if>
<if test="fdService != null">
fd_service,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="fdResName != null">
#{fdResName,jdbcType=VARCHAR},
</if>
<if test="fdDisplayName != null">
#{fdDisplayName,jdbcType=VARCHAR},
</if>
<if test="fdResDesc != null">
#{fdResDesc,jdbcType=VARCHAR},
</if>
<if test="fdTenantId != null">
#{fdTenantId,jdbcType=INTEGER},
</if>
<if test="fdService != null">
#{fdService,jdbcType=VARCHAR},
</if>
</trim> <if test="fdUpdate == 'true'">
ON CONFLICT(fd_res_name, fd_tenantid, fd_service) DO UPDATE
<set>
<if test="fdDisplayName != null">fd_display_name = #{fdDisplayName},</if>
<if test="fdResDesc != null">fd_res_desc = #{fdResDesc},</if>
<if test="fdService != null">fd_service = #{fdService},</if>
<if test="fdModifyDate != null">
fd_modify_date = #{fdModifyDate,jdbcType=VARCHAR},
</if>
<if test="fdModifyPerson != null">
fd_modify_person = #{fdModifyPerson,jdbcType=VARCHAR},
</if>
</set>
</if>
</insert>

4.遇到的问题

之前提到过,之前的处理是通过所报异常信息来做的。如果重复了,在catch语句里执行update。

1              catch (DuplicateKeyException e) {
2 if (StringUtils.equals(update,Constants.KEY_FALSE)) {
3 throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
4 }else if (StringUtils.equals(update,Constants.KEY_TRUE)){
5 resourceDao.update(resource);
6 }
7 throw new AuthServiceException(ErrorCode.RESOURCE_DUPLICATE_KEY, new Object[]{resource.getFdResName()}, e);
8 }

但是在插入重复数据时,报了如下错误:

 Caused by: org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block

原因是这个类ServiceResource上标记了@Transactional(在没有事务管理的场景下,是可以像上面那样做的):

           

2017.7.7 postgreSQL在插入造成重复时执行更新的更多相关文章

  1. 2017.9.15 postgresql批量插入造成冲突后执行更新

    参考来自:https://stackoverflow.com/questions/40647600/postgresql-multi-value-upserts/46233907#46233907 1 ...

  2. 当插入数据失败时,防止mysql自增长字段的自增长的方法

    问题描述: 当mysql设置了自增长字段时(注意:一个表中只能设置一个自增长字段,可以不是主键,但必须是键 ),如果插入数据失败,那么自增长字段仍然会占用这个自增长值,再次成功插入数据时就会造成断层. ...

  3. MYSQL插入处理重复键值的几种方法

    当unique列在一个UNIQUE键上插入包含重复值的记录时,默认insert的时候会报1062错误,MYSQL有三种不同的处理方法,下面我们分别介绍. 先建立2个测试表,在id列上创建unique约 ...

  4. 【转】insert忽略重复、mysql插入操作跳过、插入覆盖覆盖、mysql更新重复

    需求背景:一般情况,插入数据的时候,有脏数据的情况,主键重复的话,直接insert into 会报错的,然后下面的sql都不再执行了,如果可以确定后面的数据可以覆盖前面的数据,直接用replace i ...

  5. sql语句-------重复时插入更新

    ON DUPLICATE KEY UPDATE重复时插入更新 insert into user(id,username) value('231',"二人") on duplicat ...

  6. 跟我一起读postgresql源码(八)——Executor(查询执行模块之——可优化语句的执行)

    2.可优化语句的执行 可优化语句的共同特点是它们被查询编译器处理后都会生成査询计划树,这一类语句由执行器(Executor)处理.该模块对外提供了三个接口: ExecutorStart.Executo ...

  7. 跟我一起读postgresql源码(十)——Executor(查询执行模块之——Scan节点(下))

    接前文跟我一起读postgresql源码(九)--Executor(查询执行模块之--Scan节点(上)) ,本篇把剩下的七个Scan节点结束掉. T_SubqueryScanState, T_Fun ...

  8. 【转】Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍

    Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍 要求: 今天要测试上千条数据,且每条数据要求执行多次,(模拟多用户多次抽奖) 1.用户id有175个,且没有任何排序规 ...

  9. Jmeter===Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍(转)

    Jmeter中使用CSV Data Set Config参数化不重复数据执行N遍 要求: 今天要测试上千条数据,且每条数据要求执行多次,(模拟多用户多次抽奖) 1.用户id有175个,且没有任何排序规 ...

随机推荐

  1. 【POJ 2406 Power Strings】

    Time Limit: 3000MSMemory Limit: 65536K Description Given two strings a and b we define a*b to be the ...

  2. mongo基本命令

    > show dbs    -- 查看数据库列表 > use admin   --创建admin数据库,如果存在admin数据库则使用admin数据库 > db   ---显示当前使 ...

  3. jquery对中文进行base64加密,后台用java进行base64解密

    项目中遇到将中文从前台传到后台过程中,出现乱码,一番尝试之后,均是乱码,然后尝试在js代码中先进行base64加密,然后在Java中再进行解密,完美的解决了乱码问题,步骤如下 一,html页面引入jQ ...

  4. jira7.3/7.2安装、中文及破解

    jira是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪(bug管理).客户服务.需求收集.流程审批.任务跟踪.项目跟踪和敏捷管理等工作领域. 现在我们来介绍,有关jira安装. ...

  5. Echarts 基础知识浅析

    1. 引入Echarts Echarts是基于canvas的数据可视化产品,由百度公司推出 参考官方文档,引入教程示例即可,注意有两种引入方式: (1)直接引入 (2)模块化引入 2. 基本API使用 ...

  6. College student reflects on getting started in open source(二)

    My budding interest grew into a full-time obsession: creating artwork on my clunky, laggy laptop. 我萌 ...

  7. mysql 查询结果创建表

    用 SELECT 的结果创建表 关系数据库的一个重要概念是,任何数据都表示为行和列组成的表,而每条 SELECT 语句的结果也都是一个行和列组成的表.在许多情况下,来自 SELECT 的“表”仅是一个 ...

  8. Linux 安装配置JDK

    一.下载jdk 参考:http://www.codingyun.com/article/40.html 可以先下载到本地,然后ftp到服务器 也可以直接在服务器下载(windows版本的区分32位与6 ...

  9. bzoj 4765 普通计算姬 dfs序 + 分块

    题目链接 Description "奋战三星期,造台计算机".小G响应号召,花了三小时造了台普通计算姬.普通计算姬比普通计算机要厉害一些.普通计算机能计算数列区间和,而普通计算姬能 ...

  10. 小Z爱图论(NOIP信(sang)心(bin)赛)From FallDream

    题目: 小Z最近喜欢上了图论,于是他研究了一下图的连通性问题.但是他遇到了一个难题. 给定一个n个点的有向图,求有多少点对(i,j)满足从i点出发能到达点j ? 小Z仅会简单的朴素算法,所以他想问问你 ...