需求如下:从第三方数据库抓取数据批量生成二开单据,此过程中需要根据基础资料编码获取基础资料对象,进行表单实例化对象的构建。在批量构建实例化时,需要多次根据基础资料编码从数据库查询数据,为了提高效率,此时就想到了用缓存解决,将从数据库查出的基础资料对象放入Redis缓存中,因此就用到了DynamicObjectSerializeUtil,对基础资料进行序列化存入Redis缓存和反序列化从Redis缓存取基础资料对象。不过后续发现可以使用标准的BusinessDataServiceHelper.loadSingleFromCache即可解决从缓存取数的需求,但还是记录一下使用Redis缓存和DynamicObjectSerializeUtil的用法。
过程如下:
IAppCache appCache = AppCache.get("bgm"); //实体类型 此处用币别演示 DynamicObjectType dtType = EntityMetadataCache.getDataEntityType("bd_currency"); //查询基础资料对象 QFilter filter = new QFilter("number", QCP.equals, "CNY"); DynamicObject obj = QueryServiceHelper.queryOne("bd_currency", "id,number,name,status,enable", filter.toArray()); //序列化 String objectSerialization = DynamicObjectSerializeUtil.serialize(new Object[]{obj}, dtType); //存入缓存 appCache.put("CNY", objectSerialization); //根据基础资料编码从缓存取数据 String cacheString = appCache.get("CNY", String.class); //反序列化 Object[] cacheObject = DynamicObjectSerializeUtil.deserialize(cacheString, dtType); //对于单个对象数据直接获取设值 obj = (DynamicObject) cacheObject[0];
以上在反序列化时,抛出异常:kd.bos.dataentity.exception.SerializationException: 未能找到PlainObject对应的数据类型,请检查是否Json字符串和类型注册时机:序列化,如图:
经过调试,发现QueryServiceHelper.queryOne查询出的基础资料为平铺对象"PlainObject",并不是实际的基础资料对象,如图:
所以,从数据库查询实体对象进行序列化时,不能用QueryServiceHelper.queryOne,而要用
BusinessDataServiceHelper.loadSingle方法。
BusinessDataServiceHelper和QueryServiceHelper的区别可以查看【性能规范】
https://developer.kingdee.com/article/241159931985186560?productLineId=29&isKnowledge=2
推荐阅读