搜索嵌套对象的规范/谓词 [英] Specification/Predicate to Search Nested Objects

查看:81
本文介绍了搜索嵌套对象的规范/谓词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将Spring Boot与Spring JPA和Specification Executor结合使用.我的规范/谓词"组合成功地在我的班级中搜索了简单的属性.但是,我在搜索其中的对象时遇到了困难.他们是否需要单独的规范?我有一类具有2个一对多"映射类的类,并且想从同一类中搜索这些字段.

I'm using Spring Boot with Spring JPA and Specification Executor. I have my Specification/Predicate combo successfully searching the simple attributes within my class. However, I am having difficulties searching the objects within. Do they need a separate Specification? I have a class that has 2 Many To One mapping classes within and would like to search those fields from within the same class.

谓词实现

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;
    }


用户类别


User Class

@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;


角色类


Role Class

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

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


小组课程


Group Class

@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;

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

熟悉此嵌套对象的谓词实现.

Came up with this Predicate implementation for the nested objects.

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

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

This is working better, but not great. I have the possible group name values of DEV, UAT, or PROD. If I give any of these I get all the Users in my Database. If I don't I don't get any Users back. How can I do a text search on the name of this nested object?

谢谢.

推荐答案

我自己找到了答案,但想与大家分享,以便对遇到相同问题的其他人有所帮助.

I found the answer myself, but wanted to share with everybody so that it may help other people with the same issue.

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

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

Using the Join class from the javax.persistence library I could search the nested objects within my class with the same Specification.

这篇关于搜索嵌套对象的规范/谓词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆