插入具有重复唯一键的记录时如何获取主键
How to get the primary key when inserting a record with a duplicate unique key
我有一个 DAO 方法,用于将电子邮件记录插入和更新到 table 中,并使用电子邮件地址的唯一键。方法 returns 记录的 id,但是当插入重复的电子邮件时,我正在努力获取原始的现有记录的 id。我咨询了MYSQL: Getting existing primary key when inserting record with duplicate unique key?,但是我用的是JdbcTemplate。我尝试使用 'ON DUPLICATE KEY UPDATE',但它一直抛出 NullPointerException。
代码如下:
@Override
public Integer insertOrUpdate(final Email e) {
if (e == null) throw new IllegalArgumentException();
if (e.getIdEmail() != null) {
String sql = "UPDATE Email SET email=? WHERE idEmail=?";
jdbcTemplate.update(sql, e.getEmail(), e.getIdEmail());
return e.getIdEmail();
}
else {
final String sql = "INSERT IGNORE INTO Email (email) VALUES (?) ON DUPLICATE KEY UPDATE email=email";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, e.getEmail());
return ps;
}
}, keyHolder);
return ((Long) keyHolder.getKey()).intValue();
}
}
在我尝试使用 'ON DUPLICATE KEY UPDATE' 之前,它为重复键抛出 MySQLIntegrityViolationException,但现在 keyHolder 不断抛出 NullPointerException。
如果 keyHolder 为 null,我通过单独查询 id 解决了这个问题。
这是更新后的代码:
@Override
public Integer insertOrUpdate(final Email e) {
if (e == null) throw new IllegalArgumentException();
if (e.getIdEmail() != null) {
String sql = "UPDATE Email SET email=? WHERE idEmail=?";
jdbcTemplate.update(sql, e.getEmail(), e.getIdEmail());
return e.getIdEmail();
}
else {
final String sql = "INSERT IGNORE INTO Email (email) VALUES (?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, e.getEmail());
return ps;
}
}, keyHolder);
if (keyHolder.getKey() != null)
return ((Long) keyHolder.getKey()).intValue();
else {
String sql2 = "SELECT idEmail FROM Email WHERE email=?";
return jdbcTemplate.queryForObject(sql2, new Object[] {e.getEmail()}, Integer.class);
}
}
}
我有一个 DAO 方法,用于将电子邮件记录插入和更新到 table 中,并使用电子邮件地址的唯一键。方法 returns 记录的 id,但是当插入重复的电子邮件时,我正在努力获取原始的现有记录的 id。我咨询了MYSQL: Getting existing primary key when inserting record with duplicate unique key?,但是我用的是JdbcTemplate。我尝试使用 'ON DUPLICATE KEY UPDATE',但它一直抛出 NullPointerException。
代码如下:
@Override
public Integer insertOrUpdate(final Email e) {
if (e == null) throw new IllegalArgumentException();
if (e.getIdEmail() != null) {
String sql = "UPDATE Email SET email=? WHERE idEmail=?";
jdbcTemplate.update(sql, e.getEmail(), e.getIdEmail());
return e.getIdEmail();
}
else {
final String sql = "INSERT IGNORE INTO Email (email) VALUES (?) ON DUPLICATE KEY UPDATE email=email";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, e.getEmail());
return ps;
}
}, keyHolder);
return ((Long) keyHolder.getKey()).intValue();
}
}
在我尝试使用 'ON DUPLICATE KEY UPDATE' 之前,它为重复键抛出 MySQLIntegrityViolationException,但现在 keyHolder 不断抛出 NullPointerException。
如果 keyHolder 为 null,我通过单独查询 id 解决了这个问题。
这是更新后的代码:
@Override
public Integer insertOrUpdate(final Email e) {
if (e == null) throw new IllegalArgumentException();
if (e.getIdEmail() != null) {
String sql = "UPDATE Email SET email=? WHERE idEmail=?";
jdbcTemplate.update(sql, e.getEmail(), e.getIdEmail());
return e.getIdEmail();
}
else {
final String sql = "INSERT IGNORE INTO Email (email) VALUES (?)";
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, e.getEmail());
return ps;
}
}, keyHolder);
if (keyHolder.getKey() != null)
return ((Long) keyHolder.getKey()).intValue();
else {
String sql2 = "SELECT idEmail FROM Email WHERE email=?";
return jdbcTemplate.queryForObject(sql2, new Object[] {e.getEmail()}, Integer.class);
}
}
}