Spring Boot 1.5.2.RELEASE:JDBC模板仅在记录不存在时插入

时间:2017-05-10 22:27:35

标签: spring jdbc spring-boot spring-jdbc

我有一个groovy方法,检查记录是否已经存在,只有在记录不存在时插入

 public insertRecord(senderId,recipientId,referenceId){
        logger.info("inserting digsig record ${referenceId}")
        TransactionDefinition txDef = new DefaultTransactionDefinition();
        TransactionStatus txStatus = transactionManager.getTransaction(txDef);
        try {
            String selectSQL = "SELECT top 1 ID from parcels where reference_id =?";
            Integer name = jdbcTemplate.queryForObject(selectSQL,[referenceId] as Object[], Integer.class);
            if(!name) {
                String sql = "INSERT INTO parcels (sender_id, recipient_id, reference_id) VALUES (?, ?, ?)";
                jdbcTemplate.update(sql, senderId, recipientId, referenceId);
                transactionManager.commit(txStatus);
            }
            else{
                logger.info("reference_id $referenceId already exists in parcels")
            }
        }
        catch (Exception e) {
            transactionManager.rollback(txStatus);
            logger.error("Exception in insertRecord : Message = ${e.message} | Stacktrace: ${e.stackTrace}")            
        }
    }

仅当parcels中已存在记录但是如果没有现有记录失败并显示Incorrect result size: expected 1, actual 0异常消息时,它才有效,如果记录不存在,有人可以帮助我使其工作吗? / p>

3 个答案:

答案 0 :(得分:1)

假设您使用的DBMS没有处理MERGEUPSERT sql语句,您可以使用存储过程(ick!)或两个JDBC调用来处理它。

首先,尝试更新,假设该行存在:

int numberOfRecordsAffected = jdbcTemplate.update("UPDATE ... WHERE id = ?", ... , id);

然后,您可以检查numberOfRecordsAffected,如果值为0,则表示没有预先存在的记录,您可以照常插入:

if (numberOfRecordsAffected == 0)
   jdbcTemplate.update("INSERT ... ", id, ...);

答案 1 :(得分:1)

JdbcTemplate#queryForObject的文档明确指出:

  

IncorrectResultSizeDataAccessException - 如果查询没有返回一行,或者没有返回该行中的一列

因此,如果您不想获得该异常,则必须使用不同的方法,该方法不会抛出该异常。那可能是例如

JdbcTemplate#queryForList(String sql, Class<T> elementType)

然后你必须检查列表大小以查看是否有结果。如果没有结果,则列表将为空。

答案 2 :(得分:0)

这是一个数据问题,应该在数据方面解决。 如果我理解正确,只有在给定的参考ID不存在时才要插入。然后你可以把它变成一个Unique键,并使用Insert Ignore来忽略id是否已经存在,而不是去两次db。