在Java应用中处理数据库插入重复数据时,可以采用以下几种优雅的方式:
try {
// 执行插入操作
jdbcTemplate.update("INSERT INTO users(username, email) VALUES(?, ?)", username, email);
} catch (DuplicateKeyException e) {
// 处理唯一约束冲突
throw new UserFriendlyException("用户名或邮箱已被注册");
}
jdbcTemplate.update(
"INSERT INTO products(id, name, stock) VALUES(?, ?, ?) " +
"ON DUPLICATE KEY UPDATE stock = stock + VALUES(stock)",
productId, productName, quantity);
public void addUser(User user) {
if (userRepository.existsByUsername(user.getUsername())) {
throw new BusinessException("用户名已存在");
}
if (userRepository.existsByEmail(user.getEmail())) {
throw new BusinessException("邮箱已被注册");
}
userRepository.save(user);
}
@Entity
@Table(name = "users",
uniqueConstraints = {
@UniqueConstraint(columnNames = "username"),
@UniqueConstraint(columnNames = "email")
})
public class User {
// ...
}
// 使用时的异常处理
try {
userRepository.save(user);
} catch (DataIntegrityViolationException e) {
throw new DuplicateEntryException("用户信息已存在");
}
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(DuplicateKeyException.class)
public ResponseEntity<ErrorResponse> handleDuplicateKey(DuplicateKeyException ex) {
ErrorResponse error = new ErrorResponse(
"DATA_CONFLICT",
"数据已存在,请勿重复提交",
HttpStatus.CONFLICT.value()
);
return new ResponseEntity<>(error, HttpStatus.CONFLICT);
}
// 其他异常处理...
}
@PostMapping("/users")
public ResponseEntity<?> createUser(@Valid @RequestBody UserDto userDto) {
// 业务逻辑
}
// DTO类中添加验证
public class UserDto {
@NotBlank
@Size(min = 4, max = 20)
@UniqueUsername // 自定义验证注解
private String username;
@Email
@UniqueEmail // 自定义验证注解
private String email;
}
public void batchInsert(List<Product> products) {
try {
jdbcTemplate.batchUpdate(
"INSERT INTO products(id, name) VALUES(?, ?)",
new BatchPreparedStatementSetter() {
// 实现方法
});
} catch (DuplicateKeyException e) {
// 记录日志并返回友好提示
logger.warn("批量插入时发现重复数据");
throw new BusinessException("部分产品已存在,请检查数据");
}
}
选择哪种方式取决于你的具体业务需求、性能要求和框架选择。通常推荐结合数据库约束和应用层验证来提供最佳用户体验。