Java JPA标准谓词条件
我有以下用于构建条件生成器where condition的代码段 我想知道有没有更好的方法,因为我会有更多的条件和相同的条件将用于获得记录计数 任何洞见都是非常值得欣赏的Java JPA标准谓词条件,java,json,jpa,jpa-2.0,criteria-api,Java,Json,Jpa,Jpa 2.0,Criteria Api,我有以下用于构建条件生成器where condition的代码段 我想知道有没有更好的方法,因为我会有更多的条件和相同的条件将用于获得记录计数 任何洞见都是非常值得欣赏的 private List <Product> getProducts(MultivaluedMap params) throws JSONException { CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder(
private List <Product> getProducts(MultivaluedMap params) throws JSONException {
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery <Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root <Product> root = criteriaQuery.from(Product.class);
List <Predicate> p = new ArrayList <Predicate> ();
Predicate prodIdPredicate, prodNamePredicate;
JSONObject inputJSON = new JSONObject(params);
if (inputJSON.isNull("filter") == false) {
JSONObject filter = inputJSON.getJSONObject("filter");
JSONArray filters = filter.getJSONArray("filters");
for (int i = 0; i < filters.length(); i++) {
JSONObject j = (JSONObject) filters.get(i);
if (j.getString("field").equals("prodId")) {
prodIdPredicate = criteriaBuilder.like(root.get(Product_.prodId), j.getString("value"));
p.add(prodIdPredicate);
}
if (j.getString("field").equals("prodName")) {
prodNamePredicate = criteriaBuilder.like(root.get(Product_.prodName), j.getString("value"));
p.add(prodNamePredicate);
}
}
}
Predicate[] pr = new Predicate[p.size()];
p.toArray(pr);
criteriaQuery.where(pr);
private List getProducts(多值映射参数)抛出JSONException{
CriteriaBuilder CriteriaBuilder=getEntityManager().getCriteriaBuilder();
CriteriaQuery CriteriaQuery=criteriaBuilder.createQuery(Product.class);
Root=criteriaQuery.from(Product.class);
List p=newarraylist();
谓词prodIdPredicate、prodNamePredicate;
JSONObject inputJSON=新的JSONObject(参数);
if(inputJSON.isNull(“过滤器”)==false){
JSONObject filter=inputJSON.getJSONObject(“filter”);
JSONArray filters=filter.getJSONArray(“filters”);
对于(int i=0;i 首先,你必须考虑以分层的方式重构你的应用程序。你至少需要3层,达奥,服务和WebService。< /P>
所有关于数据库和JPA的内容都必须在DAO层中。所有与json相关的内容都必须在web服务层中。您的服务层必须管理事务以及web服务和DAO层之间的通信
首先让我们谈谈您的Web服务层。您的JSON对象可能来自Restful Web服务。由于几乎所有框架都支持JSON编组/解编组,因此手动解析数据传输对象是不明智的。我的意思是,您可能更喜欢声明FieldDto类并传递其实例,而不是JSONObj等等。这里有一个FieldDto
的例子。它是一个POJO
public class FieldDto {
private String prodId;
private String prodName;
// Getters & Setters etc.
}
您可以使用GSON或Jackson轻松地对json进行marshall/unmarshall处理。您的框架可能在默认情况下使用了其中一个来处理json转换
下一层是服务层。在服务层中,您可以管理事务并将DTO对象转换为DAO层可以轻松理解的对象。在这种情况下,您的服务层将fieldDto.getProdId()
和fielDto.getProdName()
传递到DAO层
最后一层是DAO层。首先让我们更改方法签名
public List <Product> getProducts(String prodId, String prodName) {
CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
CriteriaQuery <Product> criteriaQuery = criteriaBuilder.createQuery(Product.class);
Root <Product> root = criteriaQuery.from(Product.class);
List <Predicate> p = new ArrayList <Predicate> ();
if(prodId != null){
p.add(criteriaBuilder.like(root.get(Product_.prodId),prodId));
}
if(prodName != null){
p.add(criteriaBuilder.like(root.get(Product_.prodName), prodName));
}
if(!p.isEmpty()){
Predicate[] pr = new Predicate[p.size()];
p.toArray(pr);
criteriaQuery.where(pr);
}
return getEntityManager().createQuery(criteriaQuery).getResultList();
}
public List getProducts(字符串prodId,字符串prodName){
CriteriaBuilder CriteriaBuilder=getEntityManager().getCriteriaBuilder();
CriteriaQuery CriteriaQuery=criteriaBuilder.createQuery(Product.class);
Root=criteriaQuery.from(Product.class);
List p=newarraylist();
if(prodId!=null){
p、 添加(criteriaBuilder.like(root.get(Product.prodId)、prodId));
}
如果(prodName!=null){
p、 添加(criteriaBuilder.like(root.get(Product.prodName),prodName));
}
如果(!p.isEmpty()){
谓词[]pr=新谓词[p.size()];
p、 托雷(pr);
criteriaQuery.where(pr);
}
返回getEntityManager().createQuery(criteriaQuery).getResultList();
}
不是这样。这段代码仍然需要改进。在我的一个项目中,我创建了一个fluent api来管理所有样板文件部分。当你开始编写其他DAO类时,你会发现一些代码块会一次又一次地重复
下面是一个fluent api的示例。您可能需要构建您的版本
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import javax.persistence.metamodel.Attribute;
import javax.persistence.metamodel.CollectionAttribute;
import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Vector;
public final class SimpleSelectBuilder<E extends Entity> {
private final EntityManager entityManager;
private final CriteriaBuilder criteriaBuilder;
private final CriteriaQuery<E> criteriaQuery;
private final Root<E> root;
private final Collection<Predicate> predicates;
private Integer first = null;
private Integer max = null;
private LockModeType lockModeType = null;
public SimpleSelectBuilder(final EntityManager entityManager, final Class<E> entityClazz) {
this.entityManager = entityManager;
this.criteriaBuilder = entityManager.getCriteriaBuilder();
this.criteriaQuery = this.criteriaBuilder.createQuery(entityClazz);
this.root = criteriaQuery.from(entityClazz);
this.predicates = new Vector<>();
}
public SimpleSelectBuilder<E> and(final Attribute attribute, final Object value) {
final Expression expression = this.getExpression(attribute, root);
this.predicates.add(criteriaBuilder.equal(expression, value));
return this;
}
public SimpleSelectBuilder<E> andNotIn(final Attribute attribute, final Collection<Object> values) {
final Expression expression = this.getExpression(attribute, root);
this.predicates.add(criteriaBuilder.not(expression.in(values)));
return this;
}
public SimpleSelectBuilder<E> andIn(final Attribute attribute, final Collection<Object> values) {
final Expression expression = this.getExpression(attribute, root);
this.predicates.add(expression.in(values));
return this;
}
public SimpleSelectBuilder<E> andContains(final Attribute attribute, final Object value) {
final Expression expression = this.getExpression(attribute, root);
this.predicates.add(criteriaBuilder.isMember(value, expression));
return this;
}
public SimpleSelectBuilder<E> orderByAsc(final Attribute attribute) {
final List<Order> orders = new ArrayList<>();
if (this.criteriaQuery.getOrderList() != null) {
orders.addAll(this.criteriaQuery.getOrderList());
}
orders.add(criteriaBuilder.asc(this.getExpression(attribute, root)));
this.criteriaQuery.orderBy(orders.toArray(new Order[orders.size()]));
return this;
}
public SimpleSelectBuilder<E> orderByDesc(final Attribute attribute) {
List<Order> orders = this.criteriaQuery.getOrderList();
if (orders == null) {
orders = new ArrayList<>();
}
orders.add(criteriaBuilder.desc(this.getExpression(attribute, root)));
this.criteriaQuery.orderBy(orders.toArray(new Order[orders.size()]));
return this;
}
public SimpleSelectBuilder<E> setFirst(Integer first) {
this.first = first;
return this;
}
public SimpleSelectBuilder<E> setMax(Integer max) {
this.max = max;
return this;
}
public SimpleSelectBuilder<E> setLockModeType(LockModeType lockModeType) {
this.lockModeType = lockModeType;
return this;
}
public List<E> getResultList() {
final TypedQuery<E> query = this.prepareQuery();
if (lockModeType != null) {
query.setLockMode(lockModeType);
}
if (first != null) {
query.setFirstResult(first);
}
if (max != null) {
query.setMaxResults(max);
}
return query.getResultList();
}
public List<E> getCacheableResultList() {
final TypedQuery<E> query = this.prepareQuery();
if (lockModeType != null) {
query.setLockMode(lockModeType);
}
if (first != null) {
query.setFirstResult(first);
}
if (max != null) {
query.setMaxResults(max);
}
query.setHint("org.hibernate.cacheable", true);
query.setHint("org.hibernate.cacheMode", "NORMAL");
return query.getResultList();
}
public E getSingleResult() {
final TypedQuery<E> query = this.prepareQuery();
if (lockModeType != null) {
query.setLockMode(lockModeType);
}
return query.getSingleResult();
}
public E getCacheableSingleResult() {
final TypedQuery<E> query = this.prepareQuery();
if (lockModeType != null) {
query.setLockMode(lockModeType);
}
query.setHint("org.hibernate.cacheable", true);
query.setHint("org.hibernate.cacheMode", "NORMAL");
return query.getSingleResult();
}
private TypedQuery<E> prepareQuery() {
this.criteriaQuery.where(this.predicates.toArray(new Predicate[this.predicates.size()]));
return this.entityManager.createQuery(criteriaQuery);
}
private <T> Expression<T> getExpression(final Attribute attribute, final From<E, T> from) {
if (attribute instanceof SingularAttribute) {
SingularAttribute singularAttribute = (SingularAttribute) attribute;
return from.get(singularAttribute);
} else if (attribute instanceof PluralAttribute) {
PluralAttribute pluralAttribute = (PluralAttribute) attribute;
return from.get(pluralAttribute);
} else {
throw new PersistenceException("Attribute type of '" + attribute
+ "' must be one of [SingularAttribute, PluralAttribute].");
}
}
private <T> Join<E, T> getJoinExpression(final Attribute attribute, final From<E, T> from) {
if (attribute instanceof SingularAttribute) {
final SingularAttribute singularAttribute = (SingularAttribute) attribute;
return from.join(singularAttribute);
} else if (attribute instanceof CollectionAttribute) {
final CollectionAttribute collectionAttribute = (CollectionAttribute) attribute;
return from.join(collectionAttribute);
} else {
throw new PersistenceException("Attribute type of '" + attribute
+ "' must be one of [SingularAttribute, PluralAttribute].");
}
}
public SimpleSelectBuilder<E> joinAnd(final Attribute attribute, final Object value, final Attribute... joinOn) {
Join tableJoin = null;
for (final Attribute join : joinOn) {
if (tableJoin == null) {
tableJoin = this.getJoinExpression(join, root);
} else {
tableJoin = this.getJoinExpression(join, tableJoin);
}
}
if (tableJoin == null) {
throw new PersistenceException("SelectBuilder cannot construct your join statement");
}
final Expression expression = this.getExpression(attribute, tableJoin);
this.predicates.add(criteriaBuilder.equal(expression, value));
return this;
}
}
import javax.persistence.EntityManager;
导入javax.persistence.LockModeType;
导入javax.persistence.PersistenceException;
导入javax.persistence.TypedQuery;
导入javax.persistence.criteria.*;
导入javax.persistence.metamodel.Attribute;
导入javax.persistence.metamodel.CollectionAttribute;
导入javax.persistence.metamodel.PluralAttribute;
导入javax.persistence.metamodel.SingularAttribute;
导入java.util.ArrayList;
导入java.util.Collection;
导入java.util.List;
导入java.util.Vector;
公共最终类SimpleSelectBuilder{
私人最终实体管理人实体管理人;
私人最终标准制定者标准制定者;
私有最终准则查询准则查询;
私有最终根;
私有最终集合谓词;
private Integer first=null;
私有整数max=null;
私有LockModeType LockModeType=null;
公共SimpleSelectBuilder(最终EntityManager、最终类EntityLazz){
this.entityManager=entityManager;
this.criteriaBuilder=entityManager.getCriteriaBuilder();
this.criteriaQuery=this.criteriaBuilder.createQuery(entityClazz);
this.root=criteriaQuery.from(entityClazz);
this.predicates=新向量();
}
公共SimpleSelectBuilder和(最终属性,最终对象值){
final Expression=this.getExpression(属性,根);
this.predicates.add(criteriaBuilder.equal(expression,value));
归还这个;
}
公共SimpleSelectBuilder和NotIn(最终属性、最终集合值){
final Expression=this.getExpression(属性,根);
add(criteriaBuilder.not(expression.in(values));
归还这个;
}
公共SimpleSelectBuilder andIn(最终属性、最终集合值){
final Expression=this.getExpression(属性,根);
this.predicates.add(expr
public List <Product> getProducts(String prodId, String prodName) {
// TODO add like statement to SimpleSelectBuilder
return new SimpleSelectBuilder<Product>(this.getEntityManager(), Product.class)
.and(Product_.prodId, prodId))
.and(Product_.prodName, prodName))
.getResultList();
}