重用多个存储库标准的最佳方法是什么?
What is the best approach to reuse multiple repository criterias?
我有一个包含许多方法组合的存储库层,以匹配搜索条件。重用此条件的最佳方法是什么?我认为像 findByNameAndIdAndBirthdayAndAccounaNumber 这样的方法名称不是一个好主意!谢谢!
public Order findByIdAndName(String orderId) {
List<OrderEntity> list = entityManager.createNamedQuery(OrderEntity.QUERY_FIND_BY_ORDERID_AND_NAME, OrderEntity.class)
.setParameter("orderId", orderId)
.setParameter("name", name).getResultList();
if (list.isEmpty()) {
return null;
}
OrderEntity orderEntity = list.get(0);
return toOrder(orderEntity);
}
听起来您可能正在寻找允许您编写如下方法的规范模式:
public Order findOrderBySpecification(Specification specification) {
}
然后使用一个或多个规范的组合来调用它,例如按帐号,按帐号和姓名等
这里有一个使用标准 API:
的例子
http://java.dzone.com/articles/java-using-specification
另请参阅下面的文章,其中提到了 Spring 数据项目,但即使您不使用 Spring,也可能值得一读。
http://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
此外,您可以更简单地使用上面文章中引用的 QueryDSL 库来实现这一点,而不是使用 Straight JPA(即没有 Spring)的相当冗长的 Criteria API。
http://blog.mysema.com/2010/04/querydsl-as-alternative-to-jpa-2.html
http://www.querydsl.com/static/querydsl/2.1.0/reference/html/ch02s02.html
尝试在存储库实现中使用规范模式。
OrderSpecificationByName.java
public class OrderSpecificationByName implements OrderSpecification, HibernateSpecification {
private String name;
public OrderSpecificationByName(String name) {
super();
this.name = name;
}
@Override
public boolean isSatisfiedBy(Object order) {
return ((Order)order).hasName(name);
}
@Override
public Criterion toCriteria() {
return Restrictions.eq("name", name);
}
}
OrderSpecificationById.java
public class OrderSpecificationById implements OrderSpecification, HibernateSpecification {
private Long id;
public OrderSpecificationById(String id) {
super();
this.id = id;
}
@Override
public boolean isSatisfiedBy(Object order) {
return ((Order)order).hasId(id);
}
@Override
public Criterion toCriteria() {
return Restrictions.eq("id", id);
}
}
那么你必须实现逻辑规范 AndSpecification
、OrSpecification
、NotSpecification
等。
AndSpecification.java
public class AndSpecification implements HibernateSpecification {
private Specification first;
private Specification second;
public AndSpecification(Specification first, Specification second) {
first = first;
second = second;
}
@Override
public boolean isSatisfiedBy(Object candidate) {
return first.isSatisfiedBy(candidate) && second.isSatisfiedBy(candidate);
}
@Override
public Criterion toCriteria() {
Conjunction conjuntion = Restrictions.conjunction();
conjuntion.add(first.toCriteria());
conjuntion.add(second.toCriteria());
return conjuntion;
}
}
OrderRepository.java
public List<Order> query(HibernateSpecification specification) {
Session session = sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Order.class);
criteria(specification.toCriteria());
return criteria.list();
}
我有一个包含许多方法组合的存储库层,以匹配搜索条件。重用此条件的最佳方法是什么?我认为像 findByNameAndIdAndBirthdayAndAccounaNumber 这样的方法名称不是一个好主意!谢谢!
public Order findByIdAndName(String orderId) {
List<OrderEntity> list = entityManager.createNamedQuery(OrderEntity.QUERY_FIND_BY_ORDERID_AND_NAME, OrderEntity.class)
.setParameter("orderId", orderId)
.setParameter("name", name).getResultList();
if (list.isEmpty()) {
return null;
}
OrderEntity orderEntity = list.get(0);
return toOrder(orderEntity);
}
听起来您可能正在寻找允许您编写如下方法的规范模式:
public Order findOrderBySpecification(Specification specification) {
}
然后使用一个或多个规范的组合来调用它,例如按帐号,按帐号和姓名等
这里有一个使用标准 API:
的例子http://java.dzone.com/articles/java-using-specification
另请参阅下面的文章,其中提到了 Spring 数据项目,但即使您不使用 Spring,也可能值得一读。
http://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
此外,您可以更简单地使用上面文章中引用的 QueryDSL 库来实现这一点,而不是使用 Straight JPA(即没有 Spring)的相当冗长的 Criteria API。
http://blog.mysema.com/2010/04/querydsl-as-alternative-to-jpa-2.html http://www.querydsl.com/static/querydsl/2.1.0/reference/html/ch02s02.html
尝试在存储库实现中使用规范模式。
OrderSpecificationByName.java
public class OrderSpecificationByName implements OrderSpecification, HibernateSpecification {
private String name;
public OrderSpecificationByName(String name) {
super();
this.name = name;
}
@Override
public boolean isSatisfiedBy(Object order) {
return ((Order)order).hasName(name);
}
@Override
public Criterion toCriteria() {
return Restrictions.eq("name", name);
}
}
OrderSpecificationById.java
public class OrderSpecificationById implements OrderSpecification, HibernateSpecification {
private Long id;
public OrderSpecificationById(String id) {
super();
this.id = id;
}
@Override
public boolean isSatisfiedBy(Object order) {
return ((Order)order).hasId(id);
}
@Override
public Criterion toCriteria() {
return Restrictions.eq("id", id);
}
}
那么你必须实现逻辑规范 AndSpecification
、OrSpecification
、NotSpecification
等。
AndSpecification.java
public class AndSpecification implements HibernateSpecification {
private Specification first;
private Specification second;
public AndSpecification(Specification first, Specification second) {
first = first;
second = second;
}
@Override
public boolean isSatisfiedBy(Object candidate) {
return first.isSatisfiedBy(candidate) && second.isSatisfiedBy(candidate);
}
@Override
public Criterion toCriteria() {
Conjunction conjuntion = Restrictions.conjunction();
conjuntion.add(first.toCriteria());
conjuntion.add(second.toCriteria());
return conjuntion;
}
}
OrderRepository.java
public List<Order> query(HibernateSpecification specification) {
Session session = sessionFactory.getCurrentSession();
Criteria criteria = session.createCriteria(Order.class);
criteria(specification.toCriteria());
return criteria.list();
}