Skip to content

Persistent object change tracking

R edited this page Dec 13, 2019 · 2 revisions

ORM更新一个表,会先读取这个PO,有时候只会修改这个PO一个或很少的字段。但是ORM提交的数据库的时候如果没有field change tracking,会把所有值都发送到数据库,如果PO有large field(如mysql text、blob等)会出现明显的性能浪费。 例如mysql的话,会出现发送大数据字段的网络性能浪费,虽然mysql有校验 没有实际更新的字段是不会写入硬盘上。

引入maven包

        <dependency>
            <groupId>org.javers</groupId>
            <artifactId>javers-core</artifactId>
            <version>5.6.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>guava</artifactId>
                    <groupId>com.google.guava</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    public <T> T saveSelective(T model, boolean forceInsert, Consumer<T> changeFunc) {
        require(model, changeFunc);

        Javers javers = JaversBuilder.javers().build();
        T last = App.deepClone(model);
        changeFunc.accept(model);
        NQuery<PropertyChange> changes = NQuery.of(javers.compare(last, model).getChangesByType(PropertyChange.class));
        BeanMapper mapper = BeanMapper.getInstance();
        Class type = model.getClass();
        mapper.setConfig(type, type, pName -> (pName.equals("id") || changes.any(p -> p.getPropertyName().equals(pName))) ? pName : BeanMapper.IgnoreProperty, null);
        T selective = (T) mapper.map(model, type);
        return save(selective, forceInsert);
    }