MongoTemplate的对象更新操作

之前在封装MongoDB的CURD方法的时候,对于兼容Long型自增主键的数据格式,更新操作特地修改了原生的save方法,具体如下

MongoDB新增Long型主键:根本原因以及对insert,save的影响

还自认为这方法太完美了,其实又是一个坑

Mongo配置类实现之后,具体的save方法我是这么写的

@Override
public void save(T t) {
    t.setModified(this.getNowTime());
    mongoTemplate.save(t);
}

也就是说实际上我是通过调用spring-data-mongodb里面MongoTemplate的save方法,但是有一点,传入的对象t必须包含主键id,我以为这样就能达到比如mybatis里的update方法的效果,结果这里有个坑,问题就是:save只会更新传入的字段,假如collection里已经存在的字段有值,但是传入的对象里没该字段,居然会将collection里的该字段清除,具体来说,就是:

save(t) = deleteById(t.getId()) + insert(t)

这样,如果我传入的不是全字段,就会有字段丢失,显然不合逻辑

无奈,只好重新写一个update实现

@Override
public void update(T t) {
    Update update = new Update();
    Field[] fields = t.getClass().getDeclaredFields();
    for (Field field : fields) {
        field.setAccessible(true);
        try {
            if ("serialVersionUID".equals(field.getName())
                    || "id".equals(field.getName())) {
                continue;
            }
            if (field.get(t) != null) {
                update.set(field.getName(), field.get(t));
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    /** 基类BaseDO里面的modified字段,手动设置更新!!! */
    update.set("modified", this.getNowTime());
    mongoTemplate.updateFirst(new Query(Criteria.where("_id").is(t.getId())), update, t.getClass());
}

通过反射遍历传进来的的字段,然后更新这些字段,同时要注意的一点,由于基类BaseDO里有一个private变量modified,通过getDeclaredFields()或者getFields()都没法获取,因此直接手动设置一下更新即可

spring-data-mongodb的版本是1.10.8,比较老

发表评论