我需要创建一个使用带有多个参数的JPA Criteria API的搜索方法.现在的问题是不是每个参数都是必需的.因此有些可能为null,并且它们不应包含在查询中.我已经用CriteriaBuilder尝试了这个,但我看不出如何让它工作.
使用Hibernate Criteria API,这非常简单.只需创建条件,然后添加限制.
Criteria criteria = session.createCriteria(someClass.class);
if(someClass.getName() != null) {
criteria.add(Restrictions.like("name", someClass.getName());
}
Run Code Online (Sandbox Code Playgroud)
我怎么能用JPA的Criteria API实现同样的目标?
我正在尝试动态构造查询,我的下一个目标是添加JOIN子句(我不知道如何使用API).
例如,到目前为止,这段代码对我有用:
...
Class baseClass;
...
CriteriaBuilder cb = JpaHandle.get().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery(this.baseClass);
Root entity_ = cq.from(this.baseClass);
Predicate restrictions = null;
...
restrictions = cb.conjunction();
restrictions = cb.and(restrictions, entity_.get("id").in(this.listId));
...
cq.where(restrictions);
...
Query qry = JpaHandle.get().createQuery(cq);
Run Code Online (Sandbox Code Playgroud)
(注意:JpaHandle来自wicket-JPA实现)
我的愿望是添加JOIN子句(尽可能通用)!
我在类中有特定的注释(this.baseClass)
例如 :
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "assay_id", nullable = false)
Run Code Online (Sandbox Code Playgroud)
那么,在标准JPA中有没有这样的方法呢?(注意:这不编译)
这是一个实际的失败方法:
...
Join<Experiment,Assay> experimentAssays = entity_.join( entity_.get("assay_id") );
Run Code Online (Sandbox Code Playgroud)
或者像那样:
...
CriteriaQuery<Customer> q = cb.createQuery(Customer.class);
Root<Customer> c = q.from(Customer.class);
SetJoin<Customer, PurchaseOrder> o = c.join(Customer_.orders);
Run Code Online (Sandbox Code Playgroud)
对我来说,如果它可能更加通用,它会很棒......:
...
Join joinClause = …Run Code Online (Sandbox Code Playgroud) 我正在阅读"JPA 2.0中的动态,类型安全查询"一文,并偶然发现了这个例子:
EntityManager em = ...
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Person> c = qb.createQuery(Person.class);
Root<Person> p = c.from(Person.class);
Predicate condition = qb.gt(p.get(Person_.age), 20);
// ^^ --- this one
c.where(condition);
TypedQuery<Person> q = em.createQuery(c);
List<Person> result = q.getResultList();
Run Code Online (Sandbox Code Playgroud)
我想知道,这里的下划线究竟是什么意思?
由于下划线是类名的有效部分,我不明白为什么可以在JPA中使用它.我在我的代码中使用现有实体检查了这一点,当然我的类无法解析为ClassName_
所以我的实体有:
@Column(name="TS", nullable=false)
private java.sql.Timestamp timestamp;
Run Code Online (Sandbox Code Playgroud)
我生成的MetaModel具有:
public static volatile SingularAttribute<MyEntity,Timestamp> timestamp;
Run Code Online (Sandbox Code Playgroud)
我想通过Max Timestamp值选择:
Root<MyEntity> root = query.from(MyEntity.class);
Expression maxExpression = cb.max(root.get(MyEntity_.timestamp));
Run Code Online (Sandbox Code Playgroud)
但我不被允许,因为:
max(Expression<N> x)应用数值max运算创建聚合表达式.<N extends java.lang.Number>表达
当然Timestamp不会延伸Number.
如何使用typesafe Criteria API MAX对Timestamp列进行操作?
我想使用条件来进行以下查询.我有一个实体与EmbeddedId定义:
@Entity
@Table(name="TB_INTERFASES")
public class Interfase implements Serializable {
@EmbeddedId
private InterfaseId id;
}
@Embeddable
public class InterfaseId implements Serializable {
@Column(name="CLASE")
private String clase;
}
Run Code Online (Sandbox Code Playgroud)
我想要做的标准查询是:
CriteriaBuilder criteriaBuilder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Interfase> criteriaQuery = criteriaBuilder.createQuery(Interfase.class);
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("clase"), "Clase"),
);
Run Code Online (Sandbox Code Playgroud)
但是这会抛出IllegalArgumentException:
java.lang.IllegalArgumentException: Not an managed type: class InterfaseId
Run Code Online (Sandbox Code Playgroud)
我也尝试过这个问题:
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("id").get("clase"), "Clase"),
);
Run Code Online (Sandbox Code Playgroud)
而且这个......
Root<Interfase> entity = criteriaQuery.from(Interfase.class);
criteriaQuery.where(
criteriaBuilder.equal(entity.get("id.clase", "Clase"),
);
Run Code Online (Sandbox Code Playgroud)
没有运气.所以我的问题是,当我的类使用Embedded和EmbeddedId注释时,如何使用条件进行查询?
谢谢!.毛罗.
我有一个非常复杂的模型.实体有很多关系,等等.
我尝试使用Spring Data JPA并准备了一个存储库.
但是当我调用metod findAll()时,对象a的规范有一个性能问题,因为对象非常大.我知道,因为当我调用这样的方法时:
@Query(value = "select id, name from Customer ")
List<Object[]> myFindCustomerIds();
Run Code Online (Sandbox Code Playgroud)
我的表现没有任何问题.
但是当我调用时
List<Customer> findAll();
Run Code Online (Sandbox Code Playgroud)
我的表现存在很大问题.
问题是我需要使用Specifications for Customer调用findAll方法,这就是为什么我不能使用返回对象数组列表的方法.
如何编写方法来查找具有Customer实体规范但仅返回ID的所有客户.
像这样:
List<Long> findAll(Specification<Customer> spec);
Run Code Online (Sandbox Code Playgroud)
请帮忙.
Criteria API和NamedQuery之间的决策是否有启发式/最佳实践/规则集?
到目前为止我的想法:
命名查询通常更具可读性.条件查询更灵活.
两者都是预编译的.我倾向于尽可能长时间地使用命名查询,然后改为标准.
但也许通过使用标准API来"灵活"查询的冲动可能暗示了次优设计(即关注点的分离)?
谢谢
是否有可能在Criteria API .in表达式中使用参数列表?
我有这样的事情:
List<Long> list = new ArrayList<Long>();
list.add((long)1);
list.add((long)2);
list.add((long)3);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Bewerbung> criteriaQuery = cb.createQuery(Bewerbung.class);
Root<Bewerbung> bewerbung = criteriaQuery.from(Bewerbung.class);
criteriaQuery.select(bewerbung).where(
cb.in(bewerbung.get(Bewerbung_.bewerberNummer)).value(list);
return em.createQuery(criteriaQuery).getResultList();
Run Code Online (Sandbox Code Playgroud)
表达式.value(list)不起作用,因为value()期望类型为long而不是列表的参数.在我的情况下,不可能使用子查询.任何人都可以帮我解决这个问题吗?
如何在JPA的Criteria API中表达文字true和文字false?
我正在寻找像Predicate alwaysTrue = CriterialBuilder.DefaultLiterals.TRUE(类似java.lang.Boolean.TRUE)的东西.
TL; DR:如何使用Spring Data JPA中的规范复制JPQL Join-Fetch操作?
我正在尝试构建一个类,它将使用Spring Data JPA处理JPA实体的动态查询构建.为此,我定义了许多创建Predicate对象的方法(例如在Spring Data JPA文档和其他地方建议的),然后在提交适当的查询参数时将它们链接起来.我的一些实体与帮助描述它们的其他实体具有一对多的关系,这些实体在查询时被急切地获取并且合并到用于DTO创建的集合或地图中.一个简化的例子:
@Entity
public class Gene {
@Id
@Column(name="entrez_gene_id")
privateLong id;
@Column(name="gene_symbol")
private String symbol;
@Column(name="species")
private String species;
@OneToMany(mappedBy="gene", fetch=FetchType.EAGER)
private Set<GeneSymbolAlias> aliases;
@OneToMany(mappedBy="gene", fetch=FetchType.EAGER)
private Set<GeneAttributes> attributes;
// etc...
}
@Entity
public class GeneSymbolAlias {
@Id
@Column(name = "alias_id")
private Long id;
@Column(name="gene_symbol")
private String symbol;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="entrez_gene_id")
private Gene gene;
// etc...
}
Run Code Online (Sandbox Code Playgroud)
查询字符串参数作为键值对从Controller类传递到Service类,在那里它们被处理并组装成Predicates:
@Service
public class GeneService …Run Code Online (Sandbox Code Playgroud) criteria-api ×10
java ×7
jpa ×7
jpa-2.0 ×3
spring ×2
api ×1
composite-id ×1
expression ×1
generics ×1
java-ee-6 ×1
join ×1
named-query ×1