How to implement Spring Data Jpa Dynamic Query and Joint inquiry -
current project used spring data jpa , spring boot, time found it's convinence until meet requirement, found hard deal. have buyer entity , supplier entity , middle entity(buyersupplier), if i'd search buyer phone or name or both or all, have supply many methods, below:
if(phone!=null&&name!=null) list<buyer> findbyphoneandname(phone,name) else if(phone!=null) list<buyer> findbyphone(phone) else if(name!=null) list<buyer> findbyname(name) else list<buyer> findall()
obviously, above code bad.and actually, business logic more complex, meantime want search buyer belong special supplier , maybe special status buyer. corresponding sql below:
select b.* buyer b, buyer_supplier bs b.id = bs.buyer_id , bs.supplier_id = 1 , bs.stauts = 'activated' , b.name '%foo%' , b.phone '%123%'
and want build dynamic sql, below:
select b.* buyer b, buyer_supplier bs b.id = bs.buyer_id if(name != null) , b.name '%foo%' if(phone!=null) , b.phone '%123%' if(supplierid>0) , b.supplier_id = 1 if(status!=null) , bs.stauts = 'activated'
could give me code sample or documents teach me how implement above target?
imo, still need write code if(phone!=null&&name!=null)
.but can enscape code,and write once. first, should know specification<t>
support dynamic query well.just paste code below.
specification<goods> spec = new specification<goods>() { @override public predicate topredicate(root<goods> root, criteriaquery<?> query, criteriabuilder cb) { predicate predicate = cb.conjunction(); if (goodssearch.getgoodsclassid() != -1) { predicate = cb.and(predicate, cb.equal(root.get("goodsclassid"), goodssearch.getgoodsclassid())); } return query.where(predicate).getrestriction(); } }; return goodsdao.findall(spec, pageable);
ok,you can use lambda instead of anonymous class.then can enscape specification<t>
, put code if(phone!=null&&name!=null)
in it. sample code:
public specification<t> term(string fieldname, operator operator, object value) { return new specification<t>() { @override public predicate topredicate(root<t> root, criteriaquery<?> criteriaquery, criteriabuilder builder) { if (value == null) { return null; } path expression = null; // if a.b, use join if (fieldname.contains(".")) { string[] names = stringutils.split(fieldname, "."); expression = root.get(names[0]); (int = 1; < names.length; i++) { expression = expression.get(names[i]); } } else { expression = root.get(fieldname); } // different operation switch (operator) { case eq: return builder.equal(expression, value); case ne: return builder.notequal(expression, value); case lt: return builder.lessthan(expression, (comparable) value); case gt: return builder.greaterthan(expression, (comparable) value); case like: return builder.like((expression<string>) expression, "%" + value + "%"); case lte: return builder.lessthanorequalto(expression, (comparable) value); case gte: return builder.greaterthanorequalto(expression, (comparable) value); case bt: list<object> paramlist = (list<object>) value; if (paramlist.size() == 2) { return builder.between(expression, (comparable) paramlist.get(0), (comparable) paramlist.get(1)); } case in: return builder.in(expression).value(value); default: return null; } } }; }
i did not write sample code if(phone!=null&&name!=null)
in it.
Comments
Post a Comment