# rdt-v2 **Repository Path**: libinqingfeng/rdt-v2 ## Basic Information - **Project Name**: rdt-v2 - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-05-06 - **Last Updated**: 2025-05-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # rdt-v2 > rdt-v2是基于注解维护实体对象之间的冗余字段关系,然后可以进行统一更新或自动填充冗余列数据,可避免多次重复编写逻辑代码以及减少复杂关系维护的操作框架. 特性: ```` 使用简单,依赖性低,完成java bean类数据关系的维护 支持持久化数据相关的冗余数据统一更新 支持vo,dto,pojo等的数据引用冗余列填充(提供多组参数值配置,并对传入的数据进行条件分类,减少数据层的操作次数) 基于条件注解和依赖字段注解,通过条件标识对应持久化类中唯一数据 对数据操作层进行抽象,可根据具体场景自行实现/覆盖数据层数据的操作方法 基于方法可定制化,均可覆盖大部分所提供解析的方法 ```` > 注意事项 ```` 关于字段的注解仅支持在字段上配置 合理利用字段transient特性,以提升性能(可避免框架中不必要的逻辑处理) RdtResolver可配置提供外的注解,包含全局持久化类注解,id注解,transient注解,提供toJson方法的支持 建议唯一性数据标识不存在重复 class所在的包支持多组并以,分割,所要维持关系的类必须可被读取 注解中属性值为String[]的null字符串将会被解析为null,并未做去重处理 条件列类型必须一致 rdt-core及rdt-annotation作为核心jar rdt-jpa及rdt-spring-mongodb为已提供的数据层操作实现,可作为具体使用框架实现的参考 ```` > 如何引用 (当前版本1.0.1-SNAPSHOT) ```` io.github.joker-pper rdt-annotation ${version} io.github.joker-pper rdt-core ${version} io.github.joker-pper rdt-jpa ${version} io.github.joker-pper rdt-spring-mongodb-v1 ${version} io.github.joker-pper rdt-spring-mongodb-v2 ${version} ```` > 注解介绍: [详情](https://github.com/joker-pper/rdt-v2/tree/master/rdt-annotation) >使用配置: //属性配置类 public RdtProperties rdtProperties() { RdtProperties properties = new RdtProperties(); //读取class所在的包, 支持,分割 properties.setBasePackage(basePackage); //设置允许modify column类型不一致 properties.setIsModifyColumnMustSameType(false); //是否通过saveAll保存 properties.setComplexBySaveAll(false); //update出错时抛出异常 properties.setIsUpdateThrowException(true); //是否显示describe信息(debug级别默认显示) properties.setShowDescribe(true); return properties; } //框架依赖于该对象的功能解析,可覆盖相应实现方法 public RdtResolver rdtResolver() { return new RdtResolver() { //base class注解类,用于解析为存在的持久化实体类,默认包含提供的@RdtBaseEntity @Override protected Class[] customBaseEntityAnnotations() { return new Class[] {Document.class}; } @Override protected boolean isBaseClassByAnalysis(Class entityClass) { return false; } @Override protected String getColumnNameByAnalysis(Class entityClass, Field field) { return null; } @Override protected String getEntityNameByAnalysis(Class entityClass) { return null; } //class类的id,默认提供@RdtId(仅作为读取当前类中的id属性字段) @Override protected Class[] primaryIdAnnotations() { return new Class[]{Id.class}; } @Override protected String getPrimaryIdByAnalysis(Class aClass, Field field) { return null; } //transient注解,用于设置对应字段列属性 @Override protected Class[] columnTransientAnnotations() { return new Class[] {Transient.class}; } //log中输出json文本的依赖方法 @Override public String toJson(Object o) { //return SerializationUtils.serializeToJsonSafely(o); return JSON.toJSONString(o); } }; } //作为读取配置的对象 public RdtConfiguration rdtConfiguration() { return RdtConfigurationBuilder.build(rdtProperties(), rdtResolver()); } //持久层操作对象,默认提供mongodb与jpa的一些支持,但可能仍需要情况来提供 //对应的方法实现,也可以覆盖已存在的实现方法。 //未存在的可继承相关Operation父类,实现具体的查询/更新方法即可。 public RdtOperation mongoRdtOperation() { MongoRdtOperation operation = new MongoRdtOperation(rdtConfiguration()) { }; operation.setMongoTemplate(mongoTemplate); return operation; } > example (jpa-test示例, [test文件](https://github.com/joker-pper/rdt-v2/blob/master/rdt-test/rdt-jpa-test/src/test/java/com/joker17/rdt_jpa_test/GoodsAndOrderTest.java)) ``` /*** * 现有商品和订单两个实体 * 订单中持久化商品id,商品购买状态(1 已完成 2: 未付款),商品价格,未持久化商品名称(只是为了展示填充字段) * 当商品的价格改变时会更新相关订单中未付款的price数据 **/ @Entity @Table @Data @NoArgsConstructor @AllArgsConstructor public class Goods { @Id private String id; private String name; private Integer price; } @Entity @Table(name = "t_order") @Data @NoArgsConstructor @AllArgsConstructor public class Order { @Id private String id; @RdtFieldConditionRely(property = "type", targetPropertys = "id") @RdtFieldCondition(target = Goods.class, property = "id") private String goodsId; @Transient @RdtField(target = Goods.class, property = "name") private String goodsName; /** * 当订单类型为2时,当goods的金额值更改后进行更新(配置fillShow后,在fillShow时会依据条件填充该列值) */ @RdtFieldRely(property = "type") //@RdtFieldRely(property = "type", fillShow = RdtFillType.ENABLE) private Integer price; /** * type: 1 已完成 2: 未付款 (配置allowValues在save时会忽略对应值的验证,若未找到状态值,在fillSave时将会报错) */ @RdtRely(value = @KeyTarget(target = Goods.class, value = "2"), allowValues = "1") private Integer type; } //测试代码片段 @Resource private IGoodsService goodsService; @Resource private IOrderService orderService; @Resource private RdtOperation rdtOperation; /** * 初始化数据 */ @Test public void initData() { goodsService.deleteAll(); orderService.deleteAll(); Goods goods = new Goods("1", "商品1", 2333); goodsService.save(goods); List orderList = new ArrayList<>(); for (int i = 0; i < 6; i ++) { Order order = new Order(); order.setId(i + 1 + ""); order.setGoodsId("1"); //设置商品名称,由于设置为@Transient不会被保存 order.setGoodsName(goods.getName()); order.setPrice(goods.getPrice()); order.setType(new Random().nextInt(2) + 1); orderList.add(order); } orderService.saveAll(orderList); } /** * 更新goods同时更新状态为未付款的订单金额 */ @Test @Transactional @Rollback(false) public void updateGoods() { Goods goods = goodsService.getOne("1"); Goods before = JSON.parseObject(JsonUtils.toJson(goods), Goods.class); goods.setName("新商品1"); goods.setPrice(666666); goodsService.save(goods); //更新相关数据,将会只更新order表中price相关的数据 rdtOperation.updateMulti(goods, before); } /** * 显示所有订单信息 */ @Test public void findAllOrder() { logger.info("result: {}", JsonUtils.toJson(orderService.findAll())); } @Test public void newOrderWithFill() { Order order = new Order(); order.setId("222"); order.setGoodsId("1"); order.setType(2); //save填充当前数据中要持久化的price字段 rdtOperation.fillForSave(Arrays.asList(order)); logger.info("result: {}", JsonUtils.toJson(order)); //show填充当前数据中未持久化的goodsName字段 rdtOperation.fillForShow(Arrays.asList(order)); logger.info("result: {}", JsonUtils.toJson(order)); } @Test public void findAllOrderWithFill() { List orderList = orderService.findAll(); //默认只会填充列为transient的字段值(即更新+填充的方式可以同时使用,默认不会填充持久化的数据,可配置) rdtOperation.fillForShow(orderList); logger.info("result: {}", JsonUtils.toJson(orderList)); logger.info("----------------------------------------------------"); //会填充所有字段 rdtOperation.fillForShow(orderList, false, FillType.ALL); logger.info("result: {}", JsonUtils.toJson(orderList)); } ``` > api使用 [查看接口方法详情](https://github.com/joker-pper/rdt-v2/blob/master/rdt-core/src/main/java/com/joker17/redundant/operation/RdtOperation.java) ``` //更新方法 //更新当前对象的所有相关冗余字段数据 updateMulti(Object current); //根据当前对象与之前对象数据对比后,更新被引用字段值所发生改变后的相关冗余字段数据 updateMulti(Object current, Object before); //填充字段值方法(填充非持久化及启用填充的字段) void fillForShow(Collection collection); //填充字段值方法(填充持久化及启用填充的字段) void fillForSave(Collection collection); ``` 示例项目: rdt-spring-mongodb-test (包含更新示例) rdt-jpa-test (包含填充及更新示例)