更新数据库 JDBC 有一些应该被忽略的值
Update Database with JDBC having some values which should be ignored
我在使用 JDBC 更新 table 列时遇到了一些问题。如果我有一个 table 例如 User(name,address,hobby,...)
想象一下大约 15 个字段。然后我通过前端从表单中获取一个对象,用户可以在其中输入所有应该更改的条目。现在我需要将更改保存在数据库中,但并非所有字段都已更改,因此我的 DAO 有一些 null
值。例如 name
和 address
应该更改,而 table 中的其他条目不应该更改。有什么巧妙的方法可以将其放入 JDBC PreparedStatement
中吗?或者您知道其他解决方案吗?我试图避免很多 value != null
语句。
提前致谢!
(我使用 spring 作为后端,angular 作为前端)
因为你使用的是Spring,所以你可以使用NamedParameterJdbcTemplate
,但真正的技巧是使用COALESCE
来在给定值时使用回退值是 NULL
:
@Autowired
private DataSource dataSource;
public void updateUser(int id, String name, String address, String hobby) {
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
String sql = "UPDATE User" +
" SET Name = COALESCE(:name, Name)" +
", Address = COALESCE(:address, Address)" +
", Hobby = COALESCE(:hobby, Hobby)" +
" WHERE Id = :id";
MapSqlParameterSource paramMap = new MapSqlParameterSource();
paramMap.addValue("id" , id , Types.INTEGER);
paramMap.addValue("name" , name , Types.VARCHAR);
paramMap.addValue("address", address, Types.VARCHAR);
paramMap.addValue("hobby" , hobby , Types.VARCHAR);
if (jdbcTemplate.update(sql, paramMap) == 0)
throw new EmptyResultDataAccessException("User not found: " + id, 1);
}
或者,如果您将 POJO 与用户数据一起使用:
public class User {
private int id;
private String name;
private String address;
private String hobby;
// Getters and setters here
}
public void updateUser(User user) {
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
String sql = "UPDATE User" +
" SET Name = COALESCE(:name, Name)" +
", Address = COALESCE(:address, Address)" +
", Hobby = COALESCE(:hobby, Hobby)" +
" WHERE Id = :id";
BeanPropertySqlParameterSource paramMap = new BeanPropertySqlParameterSource(user);
if (jdbcTemplate.update(sql, paramMap) == 0)
throw new EmptyResultDataAccessException("User not found: " + id, 1);
}
您可以拥有的简单解决方案是使用 SimpleJdbcInsert 并添加 usingGeneratedKeyColumns("ID")。
@Autowired
private DataSource dataSource;
@Override
public ResponseEntity<Void> insertEntity(Entity obj) {
SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate.getDataSource());
simpleJdbcInsert.withTableName(TABLE_APP_REPO).usingGeneratedKeyColumns("ID");
BeanPropertySqlParameterSource paramSource = new BeanPropertySqlParameterSource(obj);
try {
simpleJdbcInsert.execute(paramSource);
} catch (Exception e) {
return ResponseEntity.badRequest().build();
}
return ResponseEntity.ok().build();
}
我在使用 JDBC 更新 table 列时遇到了一些问题。如果我有一个 table 例如 User(name,address,hobby,...)
想象一下大约 15 个字段。然后我通过前端从表单中获取一个对象,用户可以在其中输入所有应该更改的条目。现在我需要将更改保存在数据库中,但并非所有字段都已更改,因此我的 DAO 有一些 null
值。例如 name
和 address
应该更改,而 table 中的其他条目不应该更改。有什么巧妙的方法可以将其放入 JDBC PreparedStatement
中吗?或者您知道其他解决方案吗?我试图避免很多 value != null
语句。
提前致谢!
(我使用 spring 作为后端,angular 作为前端)
因为你使用的是Spring,所以你可以使用NamedParameterJdbcTemplate
,但真正的技巧是使用COALESCE
来在给定值时使用回退值是 NULL
:
@Autowired
private DataSource dataSource;
public void updateUser(int id, String name, String address, String hobby) {
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
String sql = "UPDATE User" +
" SET Name = COALESCE(:name, Name)" +
", Address = COALESCE(:address, Address)" +
", Hobby = COALESCE(:hobby, Hobby)" +
" WHERE Id = :id";
MapSqlParameterSource paramMap = new MapSqlParameterSource();
paramMap.addValue("id" , id , Types.INTEGER);
paramMap.addValue("name" , name , Types.VARCHAR);
paramMap.addValue("address", address, Types.VARCHAR);
paramMap.addValue("hobby" , hobby , Types.VARCHAR);
if (jdbcTemplate.update(sql, paramMap) == 0)
throw new EmptyResultDataAccessException("User not found: " + id, 1);
}
或者,如果您将 POJO 与用户数据一起使用:
public class User {
private int id;
private String name;
private String address;
private String hobby;
// Getters and setters here
}
public void updateUser(User user) {
NamedParameterJdbcTemplate jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
String sql = "UPDATE User" +
" SET Name = COALESCE(:name, Name)" +
", Address = COALESCE(:address, Address)" +
", Hobby = COALESCE(:hobby, Hobby)" +
" WHERE Id = :id";
BeanPropertySqlParameterSource paramMap = new BeanPropertySqlParameterSource(user);
if (jdbcTemplate.update(sql, paramMap) == 0)
throw new EmptyResultDataAccessException("User not found: " + id, 1);
}
您可以拥有的简单解决方案是使用 SimpleJdbcInsert 并添加 usingGeneratedKeyColumns("ID")。
@Autowired
private DataSource dataSource;
@Override
public ResponseEntity<Void> insertEntity(Entity obj) {
SimpleJdbcInsert simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate.getDataSource());
simpleJdbcInsert.withTableName(TABLE_APP_REPO).usingGeneratedKeyColumns("ID");
BeanPropertySqlParameterSource paramSource = new BeanPropertySqlParameterSource(obj);
try {
simpleJdbcInsert.execute(paramSource);
} catch (Exception e) {
return ResponseEntity.badRequest().build();
}
return ResponseEntity.ok().build();
}