搜索嵌套对象的规范/谓词

jDu*_*ub9 1 java specifications jpa predicate spring-data

我正在使用带有Spring JPA和Specification Executor的Spring Boot.我有我的Specification/Predicate组合成功搜索我班级中的简单属性.但是,我在搜索其中的对象时遇到困难.他们需要单独的规格吗?我有一个类,其中包含2个多对一映射类,并希望从同一个类中搜索这些字段.

谓词实施

public Specification<User> getSpecification(SpecificationField field, Object searchCriteria){
    return new Specification<User>() {
    @Override
    public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {

    if(searchCriteria instanceof String){
        searchCriteria.toString().trim().toLowerCase();
    }

    switch(field){
    case USER_GROUP:    
        return cb.equal(cb.lower(root.<String> get("group").get("name")), searchCriteria);
    case USER_ROLE: 
        return cb.equal(cb.lower(root.<String> get("role").get("name")), searchCriteria);
    case USER_EMAIL: 
        return cb.equal(cb.lower(root.<String> get("email")), searchCriteria);
    case USER_FIRSTNAME: 
        return cb.equal(cb.lower(root.<String> get("firstName")), searchCriteria);
    case USER_LASTNAME: 
        return cb.equal(cb.lower(root.<String> get("lastName")), searchCriteria);
    case USER_USERNAME: 
        return cb.equal(cb.lower(root.<String> get("username")), searchCriteria);
    default:
        assert true;
        return null;
    }
Run Code Online (Sandbox Code Playgroud)

用户类

@Id
@GeneratedValue
@Column(name = "USER_ID")
private Long id;

@Column(name = "USER_FIRSTNAME", nullable = false)
private String firstName;

@Column(name = "USER_LASTNAME", nullable = false)
private String lastName;

@Column(name = "USER_EMAIL", nullable = false, unique = true)
private String email;

@Column(name = "USER_USERNAME", nullable = false, unique = true)
private String username;

@Column(name = "USER_PASSWORD", nullable = false)
private String encryptedPassword;

@ManyToOne
@JoinColumn(name = "USER_ROLE", nullable = false)
private Role role;

@ManyToOne
@JoinColumn(name = "USER_GROUP", nullable = false)
private Group group;
Run Code Online (Sandbox Code Playgroud)

角色类

@Id
@GeneratedValue
@Column(name = "ROLE_ID")
private Long id;

@Column(name = "ROLE_NAME", nullable = false, unique = true)
private String name;
Run Code Online (Sandbox Code Playgroud)

小组课程

@Id
@GeneratedValue
@Column(name = "GROUP_ID")
private Long id;

@Column(name = "GROUP_NAME", nullable = false, unique = true)
private String name;

@Column(name = "GROUP_TOKEN", nullable = false, unique = true)
private String token;
Run Code Online (Sandbox Code Playgroud)

-------------------------------------------------- ------------------------

编辑:

为嵌套对象提供了这个Predicate实现.

Root<Group> group = query.from(Group.class);
Root<Role> role = query.from(Role.class);

switch(field){
case USER_GROUP:
    return cb.equal(cb.lower(group.<String> get("name")), searchCriteria);
case USER_ROLE: 
    return cb.equal(cb.lower(role.<String> get("name")), searchCriteria);
Run Code Online (Sandbox Code Playgroud)

这样做效果更好,但不是很好.我有可能的组名称值DEV,UAT或PROD.如果我提供任何这些,我将获得我数据库中的所有用户.如果我不这样做,我就不会让任何用户回来.如何对此嵌套对象的名称进行文本搜索?

谢谢.

jDu*_*ub9 16

我自己找到了答案,但想与大家分享,以便它可以帮助其他人解决同样的问题.

@Override
public Predicate toPredicate(Root<User> userRoot, CriteriaQuery<?> query, CriteriaBuilder cb) {

    switch(field){
    case USER_GROUP:
        Join<User, Group> groupJoin = userRoot.join("group");
        return cb.equal(cb.lower(groupJoin.<String> get("name")), searchCriteria);
    case USER_ROLE: 
        Join<User, Role> roleJoin = userRoot.join("role");
        return cb.equal(cb.lower(roleJoin.<String> get("name")), searchCriteria);
Run Code Online (Sandbox Code Playgroud)

使用javax.persistence库中的Join类,我可以使用相同的Specification搜索我的类中的嵌套对象.

  • 我们能否有一种更通用的方法将其应用于所有实体? (3认同)