Dorado 9 : 12. EntityUtils.java

dorado服务端的数据处理提供了一个重要的工具类:EntityUtils。

在以下的几种场景下我们可能会用到这个工具类。

获取或设置数据的状态

dorado支持批量数据提交功能:

我们可能在一个Grid中即做了新增,也做了修改删除等各种操作,如果这些数据一次性的批量提交到后台,我们希望在后台的逻辑代码中识别出这些记录的修改状态究竟是新增的还是删除的还是修改的。这种情况下我们就可以通过EntityUtils工具类解决这个问题。

    @DataResolver
    @Transactional
    public void saveAll(Collection<Product> products) {
        for(Product product :  products){
            if(EntityState.DELETED.equals(EntityUtils.getState(product))){
                System.out.println("删除产品 : " + product.getProductName());//执行产品删除操作
            }
            else if(EntityState.MODIFIED.equals(EntityUtils.getState(product))){
                System.out.println("修改产品 : " + product.getProductName());//执行产品修改操作
            }
            else if(EntityState.NEW .equals(EntityUtils.getState(product))){
                System.out.println("新增产品 : " + product.getProductName());//执行产品新增操作
            }
        }
        //productDao.persistEntities(products);
    }

这是一段典型的代码,前端提交了一个产品集合到后台,后台遍历产品集合的时候可以通过EntityUtils的getState方法获取到对象的状态,进而再交给业务逻辑层坐增删改有区别的持久化处理。

获取原始的数据对象

由于doardo为了维护记录的数据状态,以及其它数据同步方面的原因,dorado对提交到java后台的数据进行了cglib的代理处理,为了获取被代理的原始对象,我们可以通过EntityUtils解决这个问题,参考代码:

@DataResolver
@Transactional
public void saveAll(Collection<Product> products) throws Exception {
    for (Product product : products) {
        Product sourceProduct = EntityUtils.toPureData(product);
        if (EntityState.DELETED.equals(EntityUtils.getState(product))) {
            System.out.println("删除产品 : " + sourceProduct.getProductName());// 执行产品删除操作
        } else if (EntityState.MODIFIED.equals(EntityUtils.getState(product))) {
            System.out.println("修改产品 : " + sourceProduct.getProductName());// 执行产品修改操作
        } else if (EntityState.NEW.equals(EntityUtils.getState(product))) {
            System.out.println("新增产品 : " + sourceProduct.getProductName());// 执行产品新增操作
        }
    }
    productDao.persistEntities(products);
}

我们可以通过这行代码获取到原始的Product对象:

Product sourceProduct = EntityUtils.toPureData(product);

虚拟属性的存取

如果我们希望给业务数据对象添加一个POJO中不存在的新的属性,同时又不想改变POJO的结构,那么我们就可以通过EntityUtils工具类做到:

    @DataProvider
    public Collection<MockCategory> getCategories() throws Exception {
        Collection<MockCategory> categories = generateCategories();
        categories = EntityUtils.toEntity(categories);
        for (MockCategory category : categories) {
            EntityUtils.setValue(category, "categoryName", "CategoryName "
                    + category.getId());
        }
        return categories;
    }

上面的代码就是给MockCagegory对象添加了一个categoryName属性,并设置了一个值。

通过虚拟属性我们可以避免修改POJO对象,或创建新的VO对象。

提示

设置虚拟属性之前要确保操作的是一个被代理的数据对象,如果是业务逻辑层或持久层拿到的原始业务数据对象,我们用通过EntityUtils.toEntity(object)函数实现转换,这个函数即支持单个数据对象,也支持集合类型的数据对象。

当我们对数据对象添加了虚拟属性值后,我们还可以通过EntityUtils工具类获取虚拟属性的值。

    @DataProvider
    public Collection<MockCategory> getCategories() throws Exception {
        Collection<MockCategory> categories = generateCategories();
        categories = EntityUtils.toEntity(categories);
        for (MockCategory category : categories) {
            EntityUtils.setValue(category, "categoryName", "CategoryName "
                    + category.getId());
        }
        for (MockCategory category : categories) {
            String value = (String)EntityUtils.getValue(category, "categoryName");
        }
        return categories;
    }

通过EntityUtils的getValue方法可以获取虚拟属性的值,当然这个方法对数据对象本身的属性值的获取也是支持的,例如:

Long id = (Long)EntityUtils.getValue(category, "id");

上面的代码我们用了强制类型转换,事实上如果能预先确认数据类型的话,你也可以直接用别的接口函数代替:

Long id = EntityUtils.getLong(category, "id");

Attachments:

batchupdate.png (image/png)