之前在封装MongoDB的CURD方法的时候,对于兼容Long型自增主键的数据格式,更新操作特地修改了原生的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,比较老