当前位置: 首页 > 知识库问答 >
问题:

是否对单表的日期、整数和字符串数据类型字段执行多列搜索?

谈炳
2023-03-14

我正在处理Spring Data-多栏搜索和Spring Data Jpa-类型规范

但根据我的代码,只有字符串字段被考虑(根据日志中的 where 子句)::

select
    employee0_.employee_id as employee1_0_,
    employee0_.birth_date as birth_da2_0_,
    employee0_.email_id as email_id3_0_,
    employee0_.first_name as first_na4_0_,
    employee0_.last_name as last_nam5_0_,
    employee0_.project_association as project_6_0_,
    employee0_.status as status7_0_ 
from
    employee employee0_ 
where
    employee0_.first_name like ? 
    or employee0_.email_id like ? 
    or employee0_.status like ? 
    or employee0_.last_name like ?

下面是我开发的代码。

员工.java

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
public class Employee implements Serializable{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="EMPLOYEE_ID")
    private Long employeeId;

    @Column(name="FIRST_NAME")
    private String firstName;

    @Column(name="LAST_NAME")
    private String lastName;

    @Column(name="EMAIL_ID")
    private String email;

    @Column(name="STATUS")
    private String status;

    @Column(name="BIRTH_DATE")
    private LocalDate birthDate;

    @Column(name="PROJECT_ASSOCIATION")
    private Integer projectAssociation;
}

注意:用户可以使用全局搜索来搜索任何值,无论用户搜索什么,都应该能够看到数据,而不管数据类型如何。

EmployeeSpecification.java

public class EmployeeSpecification {

    public static Specification<Employee> textInAllColumns(String text, List<String> attributes) {
        if (!text.contains("%")) {
            text = "%" + text + "%";
        }
        final String finalText = text;

        return (root, query, builder) -> builder
                .or(root.getModel().getDeclaredSingularAttributes().stream().filter(a -> {
                    if (a.getJavaType().getSimpleName().equalsIgnoreCase("String")) {
                        return true;
                    }else if(a.getJavaType().getSimpleName().equalsIgnoreCase("date")) {
                        return true;
                    }
                    else {
                        return false;
                    }
                }).map(a -> builder.like(root.get(a.getName()), finalText)).toArray(Predicate[]::new));
    }
}

但这种方法只考虑String字段,而不考虑Date和Integer数据类型。我们如何才能做到这一点?

共有2个答案

宋育
2023-03-14

分析问题,我给你一个更灵活的解决方案,这段代码解决了你的问题,并允许动态生成查询。这个想法是使用任何类型的对象来进行查询。

首先,创建这个类以保存查询的参数

@RequiredArgsConstructor
public class Search {
    @Getter
    @NonNull private String field;
    @Getter
    @NonNull private String operator;
    @Getter
    @NonNull private Object value;
}

然后根据每个对象的以下代码构建规范

public static Specification<Employee> searchFreeAttrsEmployee(List<Search> attributes) {
    return new Specification<Employee>() {
        private static final long serialVersionUID = 4817323527595445596L;
        public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
            List<Predicate> r=new ArrayList<Predicate>(); 
            attributes.stream().forEach(t -> {
                r.add(setParams(t, root, builder));
            });
            Predicate list[] = new Predicate[r.size()];
            r.toArray(list);
            return builder.or(list);
        }
    };
}

public static Predicate setParams(Search t, Root<?> root, CriteriaBuilder builder) {
    if (t.getOperator().equals("like")) {
        return builder.like(root.get(t.getField()), t.getValue().toString());
    }
    if (t.getOperator().equals("equal")) {
        return builder.equal(root.get(t.getField()), t.getValue().toString());
    }       
    if (t.getOperator().equals("gtInt")) {
        return builder.gt(root.get(t.getField()), Integer.valueOf(t.getValue().toString()));
    }       
    if (t.getOperator().equals("eqInt")) {
        return builder.equal(root.get(t.getField()), Integer.valueOf(t.getValue().toString()));
    }       

    return null;
}

}

以这种方式运行搜索

    List<Search> l=new ArrayList<Search>();
    l.add(new Search("firstName","like","Peter"));
    List<Employee> list = pe.findAll(Specifications.searchFreeAttrsEmployee(l));

您可以聚合许多属性以进行搜索。我希望这样,这段代码将是有用的。

问候

齐意致
2023-03-14

改变:

if(a.getJavaType().getSimpleName().equalsIgnoreCase("date")) 

自:

if(a.getJavaType().getSimpleName().equalsIgnoreCase("LocalDate"))
 类似资料:
  • 请帮助解决此错误... 因为我在该对象上使用了bigdecimal类型,而没有添加一个操作@字段(type=FieldType.Double) 有没有办法配置默认的FieldType。大十进制加倍?或者我们需要在每个大十进制中添加字段注释

  • 问题2:如何将这个日期值从转换为-作为pojo类中的静态方法?将其放入某个外部实用程序类中。 编辑#1:我对这些POJO使用模式。

  • 问题内容: 在上次考试中,我们进行了练习以确定以下代码的输出: 我的回答是,但现在我意识到这是错误的答案。应该是。但为什么? 问题答案: 假设您的语法是: 表达式是从左到右求值的,在这种情况下,2 + 3求和为5,当“添加”到字符串结果为时,将其加到1时,再加上1,结果是:

  • 我想检查数据帧中的列是否由字符串组成,以便为机器学习目的用数字标记它们。有些列由数字组成,我不想更改它们。列示例如下所示: 谢谢=)

  • 我正在尝试使用PHP编写一个函数来确定字符串是否是日期/时间。基本上,有效日期/时间如下所示: 显然,尽管它是完全动态的,但任何值都可以更改,但它应该始终以的形式出现,我如何编写正则表达式来检查此模式并在匹配时返回true。

  • 本文向大家介绍mongodb 数据类型(null/字符串/数字/日期/内嵌文档/数组等),包括了mongodb 数据类型(null/字符串/数字/日期/内嵌文档/数组等)的使用技巧和注意事项,需要的朋友参考一下 MongoDB的文档类似于JSON,JSON只是一种简单的表示数据的方式,只包含了6种数据类型(null、布尔、数字、字符串、数组及对象). JSON的数据类型的局限性: 1.无日期类型,