对象聚合的映射工具
从实体类到值对象的映射。支持代理(值对象是实例对象的子类), 模板(值对象包含实例对象的属性), ASF的元组(Pair, Triple)及其集合
1: 支持: 目标对象(起始对象实例)与目标关联对象的一对一,一对多, 多对多。工具通过描述其关联关系减少日常的Set. 内置一些实现策略同时提供策略的自定义实现
例如: 通过订单获取其关联的购买者,配送地址;
2: 支持: 自定义BoolExpress表达式,传入表达式后通过decide方法对传入对象参数完成判断
例如: 用户的角色=x 并且 积分 > y. 此时传入用户对象即可计算当前传入的用户是否满足表达式。对于表达式由程序使用者来构建是实用的
3: 支持: 关联关系的表达式描述,减小构造关联关系的书写时间。工具对于表达式的格式是内置式的。当然您也可以重新定义并重新编译。工具内置有:BeanParser来进行表达式的解析
BeanParser 通过自定义表达式完成对象的实例化(parse)或转成Map结构(toMap),也可以使用自定义表达式来对实例进行格式化(format)
完整示例:
// 1) 创建通用映射
ToroMapper<OrdersVo> mapper = new ToroMapper<>(OrdersVo.class);
// 2.1) 通过方法创建连接关系描述(
// link=VO.product,
// use=orders.productId,
// eq=Product.id,
// type=orders.productId和Product.id的类型)
LinkRelation mlr = mapper
.link(设置的属性名)
.use(选择对象中的查询属性名)
.eq(匹配选择对像中的属性名)
.type(use/eq中的类型)
.tag(标签名:可选)
.build();
// 2.2) 通过描述表达式创建连接关系描述
LinkRelation mlr = mapper.link(() -> "product=select(productId)&eq(id:long)");
// 3) 执行
结果 = mapper
.many(起始对象|起始对象供应函数)|one|any
.pair(右.mlr)|triple(中.mlr, 右.mlr)|proxy(mlr,...)|template(mlr,...)
.transfer()|transfer(消费函数)|transfer(映射函数)|transfer(消费函数&映射函数)
.parallel(是否并行:可选)
.apply()
.compose(关联关系)|compose(标签名, 关联关系), ...
.strategy(自定义策略:可选)
.cache(缓存关联关系图:可选)
.get();
目前尚未展开
Java JDK11+
ASF commons lang3 V3.12.0
BULL Bean Utils V2.1.1-jdk11
示例使用的对象在test中均可找到.不在此说明, 同时在test下有更详细的使用示例. 以下仅作部分描述
值对象是实例对象的子类; 例:OrdersVo继承自Orders。
// 1)一对一聚合
// R: 一张订单的购买者和商品的聚合
ProxyMapper<OrdersVo> mab = ProxyMapper.proxy(OrdersVo.class);
MapperAttrStatements mae = mab
.one()
.attr("members")
.used("memberId")
.usedType("long")
.select(memberSelectFun)
.attr("product")
.used("productId")
.usedType(TypeEnum.BLong)
.select(productSelectFun)
.attr("coupons")
.collection("java.util.HashSet")
.used("id")
.usedType(TypeEnum.BLong)
.select(orderCouponFun);
Optional<OrdersVo> ovo = mab
.by(o3,true)
.get(mae);
// 1.1
if(ovo.isPresent()){
Members members = ovo.get().getMembers();
Product product = ovo.get().getProduct();
String css = ovo.get().getCoupons().stream().map(Coupon::getNames).collect(Collectors.joining(","));
System.out.println(String.format("%s by %s payed %f used coupon list: %s", members.getNames(), product.getTitle(), ovo.get().getAmout(), css));
}else {
System.out.println("map fail");
}
// 1)一对一聚合
// R: 一张订单的购买者和商品的聚合
ProxyMapper<OrdersVo> mab = ProxyMapper.proxy(OrdersVo.class);
MapperAttrStatements mae = mab
.one()
.expr("members=select(memberId)")
.select(memberSelectFun)
.expr("product=select(productId)")
.select(productSelectFun)
.expr("coupons:java.util.HashSet=select(id)")
.select(orderCouponFun);
/* 无处理操作
Optional<OrdersVo> ovo = mab
.by(o3, true)
.get(mae);*/
// 对结果进行前置处理
Optional<OrdersVo> ovo = mab
.by(o3, true)
.consume(System.out::println)
.get(mae);
// 1.1
if(ovo.isPresent()){
OrdersVo ov = ovo.get();
Members members = ov.getMembers();
Product product = ov.getProduct();
String css = ov.getCoupons().stream().map(Coupon::getNames).collect(Collectors.joining(","));
System.out.println(String.format("%s by %s payed %f used coupon list: %s", members.getNames(), product.getTitle(), ov.getAmout(), css));
}else {
System.out.println("map fail");
}
值对象中含有关联对象的属性; 例:OrdersTVo 中属性由订单(Orders),商品(Product),购买者(Members)的部分属性组成。
TemplateMapper<OrdersTVo> mab = TemplateMapper.template(OrdersTVo.class);
TemplateStatements maeMember = mab
.many("Member", "memberId", "id")
.field(TemplateExpression.Builder.newInstance().target("buyer").used("id").usedType(TypeEnum.BLong).build())
.field(TemplateExpression.Builder.newInstance().target("buyerNames").used("names").usedType(TypeEnum.Str).build());
TemplateStatements maeProduct = mab
.many("Product", "productId", "id")
.field(TemplateExpression.Builder.newInstance().target("product").used("id").usedType(TypeEnum.BLong).build())
.field(TemplateExpression.Builder.newInstance().target("productTitle").used("title").usedType(TypeEnum.Str).build());
BatchQueryFace<Members> mb = (Collection<String> memberIds) -> queryMemberFace(memberIds);
BatchQueryFace<Product> pb = (Collection<String> productIds)->queryProductFace(productIds);
Collection<OrdersTVo> rs = mab
.by(Arrays.asList(o3, o4, o5), false)
.batch()
.compose("Member", mb)
.compose("Product", pb)
.get(Arrays.asList(maeMember, maeProduct));
rs.stream().forEach(ele->{
System.out.println(ele);
});
TemplateMapper<OrdersTVo> mab = TemplateMapper.template(OrdersTVo.class);
TemplateStatements maeMember = mab
.many("Member", "memberId", "id")
.expr("buyer=select(id:long)")
.expr("buyerNames=select(names:java.lang.String)");
TemplateStatements maeProduct = mab
.many("Product", "productId", "id")
.expr("product=select(id:long)")
.expr("productTitle=select(title:java.lang.String)");
BatchQueryFace<Members> mb = (Collection<String> memberIds) -> queryMemberFace(memberIds);
BatchQueryFace<Product> pb = (Collection<String> productIds)->queryProductFace(productIds);
Collection<OrdersTVo> rs = mab
.by(Arrays.asList(o3, o4, o5), false)
.batch()
.compose("Member", mb)
.compose("Product", pb)
.get(Arrays.asList(maeMember, maeProduct));
rs.stream().forEach(ele->{
System.out.println(ele);
});
若VO对象中存在某个关联对象的多个属性并且以某个字符串开头(affix). 以下示例会是更好的选择
TemplateMapper<ArticleVo> mab = TemplateMapper.template(ArticleVo.class);
TemplateAffixStatements autAffix = mab
.one("Author", "authorId").affix("aut");
TemplateAffixStatements secAffix = mab
.one("ArticleSection", "sectionId").affix("sec");
Optional<ArticleVo> data = mab
.by(ar5, false)
.affix()
.basis()
.compose("Author", authorSelectFun)
.compose("ArticleSection", sectionSelectFun)
.get(Arrays.asList(autAffix, secAffix));
if (data.isPresent()){
System.out.println(data.get());
} else {
System.out.println("ArticleVo build fail");
}
ASF Pair的表达式示例: PairMapperTest
Function<Long, Orders> leftFun = (orderId) -> ohm.get(orderId);
Function<Long, Product> rightFun = (productId) -> phm.get(productId+"");
/* 查看指定的订单*/
Pair<Orders, Product> pair= TupleMapper
.pair
.<Orders>one()
.expr("R(productId:long)")
.supply(()->leftFun.apply(1001L))
.get(rightFun);
System.out.println("left-right object:");
System.out.println(pair.getLeft());
System.out.println(pair.getRight());
ASF Triple的表达式示例: ManyTripleMapperTest
Function<Collection<Long>, Collection<Orders>> leftFun = (orderIdSet) -> queryOrdersById(orderIdSet);
Function<Collection<Long>, Collection<Product>> middleFun = (productIdSet) -> queryProductById(productIdSet);
Function<Collection<Long>, Collection<Members>> rightFun = (memberIdSet) -> queryMemberById(memberIdSet);
/* 查看指定的订单*/
Collection<Triple<Orders, Product, Members>> rs = TupleMapper
.triple
.many()
.expr("M(productId:long)#R(memberId:long)&ML(id:long)#RJ(id:long)")
.by(leftFun.apply(Arrays.asList(1000L, 1001L, 1002L)))
.get(middleFun, rightFun);
rs.stream().forEach(ele->{
System.out.println("------------------left-middle-right object:------------------");
System.out.println(ele.getLeft());
System.out.println(ele.getMiddle());
System.out.println(ele.getRight());
});
boolean rs = false;
try {
rs = BoolExpress
.getInstance()
.expression("GE:int(score,300)|EQ:int(level,2)")
.decide(new MemberInfo(100, 2));
}catch (Exception e){
e.printStackTrace();
}
System.out.println(rs);
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。