我有一个Spring应用程序,它为Postgres数据库提供了更新API端点。用户可以提交信息,更新将反映在数据库中。用户只提交他们必须更新的内容。例如,考虑以下对象:
class Dog {
String name;
int age;
String breed;
// Attributes and getters/setters...
}
当用户提交更新请求时,他们只发送希望更新的信息,例如只发送名称和品种。我有以下功能,用信息更新数据库:
public void update(String name, int age, String breed, JdbcTemplate template) {
UpdateBuilder query = new UpdateBuilder();
query.from("DogTable");
boolean updated = false;
if (name != null) {
query.set("name" + " = '" + name + "'");
updated = true;
}
if (age != null) {
query.set("age" + " = '" + age + "'");
updated = true;
}
if (breed != null) {
query.set("breed" + " = '" + breed + "'");
updated = true;
}
// And so on...
if (updated) {
query.set("UpdatedTime" + " = '" + new Date() + "'");
}
query.where("someKey" + " = '" + someId + "'");
template.update(query.toString());
}
(query.set()
只是一个构建查询字符串的助手类)
正如你所看到的,这与所有的"名字是给定的吗,年龄是给定的?"检查变得一团糟。这引出了我的问题:有没有一种数据驱动的方法可以做到这一点?我想做的是:
myJdbcTemplate.update(ListOfObjectsToUpdate, "TableName");
简单地说,JDBC模板将看到我提供的内容,并使用这些信息更新提供的表。这可能吗?我意识到使用字符串构建查询是不好的,但PreparedStatements在代码中看起来并没有好到哪里去(更不用说,它们并不能解决这个问题)。
您可以为此目的使用COALESCE函数-同时添加用户值和现有值,如果用户值不为null(预期更新),则可以将其设置为新值。
与此类似-
UPDATE "user" SET alternate_contact_name = COALESCE(<user value>, alternate_contact_name)
这是一个MySQL查询,但COALESCE
在Postgresql中的工作方式相同
如果user value
不为空,则会设置它并设置新值。当它为null并且列的原始值不为null时,如果拾取原始值。如果两者都为空,那也没关系。
这样,您就可以简单地传递所有参数,避免以不整洁的方式构建查询。