如何使用 CriteriaQuery 查询 OneToOne 实体的特定值
How to query OneToOne entity for specific value with CriteriaQuery
我有一个实体(人),它是另一个实体(用户)的一对一。我需要使用 CriteriaQuery 找到所有匹配 User.name 的 Person 实体。
我可以为 Person 的直接属性做简单的 CriteriaQuery 就好了:
builder.like(builder.lower(root.get(column)), "%" + pattern.toLowerCase() + "%")
我对如何在这种更复杂的情况下执行 CriteriaQuery 查询有点迷茫。根据我在这里和其他地方的搜索,我认为我必须使用某种 Join 但我无法理解它。
@Entity()
public class Person extends ModelCore {
@Basic()
private String iD = null;
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumns({ @JoinColumn(name = "T_User") })
private User user = null;
}
@Entity()
public class User extends ModelCore {
@Basic()
private String iD = null;
@Basic()
private String name = null;
}
@Entity()
public class ModelCore{
@Basic()
private Long dbID = null;
}
已解决
Nikos 的解决方案非常有效(谢谢!):
String username = ... // the criterion
EntityManager em = ...
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
Join<Person, User> joinUser = root.join("user");
query.where(cb.like(cb.lower(joinUser.get("name")), "%" + username.toLowerCase() + "%"));
编辑 1:添加 ModelCore 作为基础 class。
编辑 2:添加工作解决方案
条件 API 随着复杂性的增加可能会令人困惑。我始终遵循的第一步是写下 JPQL 查询。在这种情况下:
SELECT p
FROM Person p
JOIN User u
WHERE LOWER(u.name) LIKE :username
将此转换为标准 API 是:
// These are initializations
String username = ... // the criterion
EntityManager em = ...
CriteriaBuilder cb = em.getCriteriaBuilder();
// Next line means "the result of the query is Person"
CriteriaQuery<Person> query = cb.createQuery(Person.class);
// This matches the "FROM Person p" part of the JPQL
Root<Person> root = query.from(Person.class);
// This matches the "JOIN User u" part of the JPQL
Join<Person, User> joinUser = root.join("user"); // if you have created the metamodel, adjust accordingly
// This is the "WHERE..." part
query.where(cb.like(cb.lower(joinUser.get("name")), "%" + username.toLowerCase() + "%"));
WHERE 部分令人困惑,因为您必须将中缀 SQL/JPQL 运算符转换为前缀(即 x LIKE y
变为 cb.like(x, y)
),但映射很简单。
我有一个实体(人),它是另一个实体(用户)的一对一。我需要使用 CriteriaQuery 找到所有匹配 User.name 的 Person 实体。
我可以为 Person 的直接属性做简单的 CriteriaQuery 就好了:
builder.like(builder.lower(root.get(column)), "%" + pattern.toLowerCase() + "%")
我对如何在这种更复杂的情况下执行 CriteriaQuery 查询有点迷茫。根据我在这里和其他地方的搜索,我认为我必须使用某种 Join 但我无法理解它。
@Entity()
public class Person extends ModelCore {
@Basic()
private String iD = null;
@OneToOne(cascade = { CascadeType.ALL })
@JoinColumns({ @JoinColumn(name = "T_User") })
private User user = null;
}
@Entity()
public class User extends ModelCore {
@Basic()
private String iD = null;
@Basic()
private String name = null;
}
@Entity()
public class ModelCore{
@Basic()
private Long dbID = null;
}
已解决
Nikos 的解决方案非常有效(谢谢!):
String username = ... // the criterion
EntityManager em = ...
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Person> query = cb.createQuery(Person.class);
Root<Person> root = query.from(Person.class);
Join<Person, User> joinUser = root.join("user");
query.where(cb.like(cb.lower(joinUser.get("name")), "%" + username.toLowerCase() + "%"));
编辑 1:添加 ModelCore 作为基础 class。 编辑 2:添加工作解决方案
条件 API 随着复杂性的增加可能会令人困惑。我始终遵循的第一步是写下 JPQL 查询。在这种情况下:
SELECT p
FROM Person p
JOIN User u
WHERE LOWER(u.name) LIKE :username
将此转换为标准 API 是:
// These are initializations
String username = ... // the criterion
EntityManager em = ...
CriteriaBuilder cb = em.getCriteriaBuilder();
// Next line means "the result of the query is Person"
CriteriaQuery<Person> query = cb.createQuery(Person.class);
// This matches the "FROM Person p" part of the JPQL
Root<Person> root = query.from(Person.class);
// This matches the "JOIN User u" part of the JPQL
Join<Person, User> joinUser = root.join("user"); // if you have created the metamodel, adjust accordingly
// This is the "WHERE..." part
query.where(cb.like(cb.lower(joinUser.get("name")), "%" + username.toLowerCase() + "%"));
WHERE 部分令人困惑,因为您必须将中缀 SQL/JPQL 运算符转换为前缀(即 x LIKE y
变为 cb.like(x, y)
),但映射很简单。