java方法criterion_java – JPA Criteria谓词条件

首先,您必须考虑以分层方式重新构建应用程序.您至少需要3层,DAO,服务和WebService.

有关数据库和JPA的所有内容都必须位于DAO层中.所有与json相关的东西都必须在你的WebService层中.您的服务层必须管理Web服务和dao层之间的事务和通信.

首先,我们来谈谈您的Web服务层.您的JSON对象可能来自Restful Web服务.由于几乎所有框架都支持json编组/解组,因此手动解析数据传输对象是不明智的.我的意思是,你可能更喜欢声明一个FieldDto类并传递它的实例而不是JSONObject.这是FieldDto的一个例子.这是一个POJO.

public class FieldDto {

private String prodId;

private String prodName;

// Getters & Setters etc.

}

您可以使用GSON或Jackson轻松地对json进行编组/解组.可能你的框架默认使用其中一个来处理json转换.

下一层是服务层.在服务层中,您可以管理事务并将DTO对象转换为DAO层可以轻松理解的对象.在这种情况下,您的服务层将fieldDto.getProdId()和fielDto.getProdName()传递给DAO层.

你的最后一层是DAO层.首先让我们改变您的方法签名.

public List getProducts(String prodId, String prodName) {

CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Product.class);

Root root = criteriaQuery.from(Product.class);

List p = new ArrayList ();

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();

}

这不是它.此代码仍需改进.在我的一个项目中,我创建了一个流畅的api来管理所有的样板部件.当你开始编写其他DAO类时,你会发现一些代码块一遍又一遍地重复.

这是一个流畅的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 {

private final EntityManager entityManager;

private final CriteriaBuilder criteriaBuilder;

private final CriteriaQuery criteriaQuery;

private final Root root;

private final Collection predicates;

private Integer first = null;

private Integer max = null;

private LockModeType lockModeType = null;

public SimpleSelectBuilder(final EntityManager entityManager, final Class 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 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 andNotIn(final Attribute attribute, final Collection values) {

final Expression expression = this.getExpression(attribute, root);

this.predicates.add(criteriaBuilder.not(expression.in(values)));

return this;

}

public SimpleSelectBuilder andIn(final Attribute attribute, final Collection values) {

final Expression expression = this.getExpression(attribute, root);

this.predicates.add(expression.in(values));

return this;

}

public SimpleSelectBuilder 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 orderByAsc(final Attribute attribute) {

final List 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 orderByDesc(final Attribute attribute) {

List 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 setFirst(Integer first) {

this.first = first;

return this;

}

public SimpleSelectBuilder setMax(Integer max) {

this.max = max;

return this;

}

public SimpleSelectBuilder setLockModeType(LockModeType lockModeType) {

this.lockModeType = lockModeType;

return this;

}

public List getResultList() {

final TypedQuery 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 getCacheableResultList() {

final TypedQuery 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 query = this.prepareQuery();

if (lockModeType != null) {

query.setLockMode(lockModeType);

}

return query.getSingleResult();

}

public E getCacheableSingleResult() {

final TypedQuery 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 prepareQuery() {

this.criteriaQuery.where(this.predicates.toArray(new Predicate[this.predicates.size()]));

return this.entityManager.createQuery(criteriaQuery);

}

private Expression getExpression(final Attribute attribute, final From 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 Join getJoinExpression(final Attribute attribute, final From 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 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;

}

}

如果你使用这个.比你的方法成为这个.

public List getProducts(String prodId, String prodName) {

// TODO add like statement to SimpleSelectBuilder

return new SimpleSelectBuilder(this.getEntityManager(), Product.class)

.and(Product_.prodId, prodId))

.and(Product_.prodName, prodName))

.getResultList();

}

如果您编写自己的SimpleSelectBuilder来处理样板代码块并提高可重用性,那将会更好.例如,您需要在上面的代码中添加like语句.

管理所有层,事务,连接池等将花费您的时间.相反,您可能需要考虑使用中间件来管理所有这些.在我的项目中,我更喜欢Spring.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值