我有一个非常简单的mysql记录,如下所示:
+------+-------+-----------+
| id | name | password |
+------+-------+-----------+
| 1 | John | d0c91f13f |
+------+-------+-----------+
... ... ...
这是它的休眠实体;没有什么花哨的
@Entity
@Table(name = "user", schema = "", catalog = "trade")
public class UserEntity{
private long id;
private String name;
private String password;
@Id
@Column(name = "id")
public long getId(){
return id;
}
public void setId(long id){
this.id = id;
}
@Column(name = "name")
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
@Column(name = "password")
public String getPasswrod(){
return password;
}
public void setPassword(String password){
this.password = password;
}
}
为方便起见,我使用Gson从前端传入的json字符串解析实体。
记录的json字符串是这样的:
{"id":1, "name":"John", "password":"d0c91f13f"}
然后将从json String解析userEntity:
UserEntity userEntity = gson.fromJson(userJson, UserEntity.class);
我可以使用Session.save(userEntity)
和Session.update(userEntity)
插入或更新用户。
如果每个字段都包含在json字符串中,那么事情似乎就像预期的那样。
但是当省略某些字段时,例如password
:
{"id":1, "name":"John Smith"}
表示我应该进行部分更新并保留未修改的省略字段,出错了。因为
解析过程将password
设置为Null。并将其更新到数据库。
那么,在这种情况下是否有部分更新记录的解决方案?
逐个浏览每个字段并设置字段将是最后一个选项;还有什么呢?
提前致谢。
答案 0 :(得分:0)
如果您知道存在特定条目,则在更新之前获取条目将使用现有值填充对象,并且您只需更改Json提供的值。这样就可以避免像你描述的那样进行空更新。
但是,如果条目是新的,那么Json中缺少的任何内容都将作为null传递给数据库。
答案 1 :(得分:0)
1,假设您可以通过以下方式反序列化srcUserEntity:
UserEntity srcUserEntity = gson.fromJson(userJson, UserEntity.class);
2,您可以利用spring的BeanUtil复制属性方法。
BeanUtils.copyProperties(srcUserEntity, desUserEntity, SpringBeanUtil.getNullPropertyNames(srcUserEntity));
3,在你的Dao层中,只需先从数据库中获取模型,然后更新属性只需要更新,最后更新。请参阅以下代码:
Session currentSession = sessionFactory.getCurrentSession();
UserEntity modelInDB = (UserEntity)currentSession.get(UserEntity.class, user.getId());
//Set properties that needs to update in DB, ignore others are null.
BeanUtils.copyProperties(productStatusModelForPatch, modelInDB, SpringBeanUtil.getNullPropertyNames(productStatusModelForPatch));
currentSession.update(modelInDB);
4,对于getNullPropertyNames()方法,请参考[How to ignore null values using springframework BeanUtils copyProperties? (Solved)
public static String[] getNullPropertyNames (Object source) {
final BeanWrapper src = new BeanWrapperImpl(source);
java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
Set<String> emptyNames = new HashSet<String>();
for(java.beans.PropertyDescriptor pd : pds) {
Object srcValue = src.getPropertyValue(pd.getName());
if (srcValue == null) emptyNames.add(pd.getName());
}
String[] result = new String[emptyNames.size()];
return emptyNames.toArray(result);
}
// then use Spring BeanUtils to copy and ignore null
public static void myCopyProperties(Object, src, Object target) {
BeanUtils.copyProperties(src, target, getNullPropertyNames(src))
}