标准规范-如何编写通用类以通过实体的任何枚举字段过滤实体

问题描述

我有一个包含3个枚举字段的实体类。现在,我想编写一个规范类来基于这些枚举字段过滤记录。我知道我可以为每个枚举类写一个谓词。但是,我想知道是否可以编写任何通用类来过滤任何枚举。这样可以节省代码和维护工作。

下面是我的实体类

StoreID |PurchaseID |ShopID |LocationID |starttime           |Endtime
--------|-----------|-------|-----------|--------------------|-------------------
1020    |20200102   |9856   |10         |2020-01-08 09:08:53 |2020-01-08 09:09:48
1021    |20200103   |9856   |20         |2020-01-08 09:09:48 |2020-01-08 09:11:52
1022    |20200102   |9856   |30         |2020-01-08 09:12:53 |2020-01-08 09:14:52
1023    |20200104   |9856   |40         |2020-01-08 09:16:48 |2020-01-08 09:18:52

解决方法

是的。可以做到的。步骤

  1. 使用两种方法创建规范构建器类。一种基于枚举类获取枚举值的方法。第二种方法是根据先前方法返回的枚举值来过滤枚举。
@Component
public class SpecificationsBuilder<T>
{
public Specification<T> whereEnumFieldEquals(String key,List<String> names,Class claz)
    {
        Specification<T> finalSpec = null;
        for (String name : names)
        {
            @SuppressWarnings("unchecked")
            Specification<T> internalSpec = (Root<T> root,CriteriaQuery<?> query,CriteriaBuilder cb) -> cb
                    .equal(root.get(key),getEnum(name,claz));
            finalSpec = specOrCondition(finalSpec,internalSpec);
        }
        return finalSpec;
    }

public static <E extends Enum<E>> E getEnum(String text,Class<E> klass)
    {
        return Enum.valueOf(klass,text);
    }
}
  1. 在您的主要班级。创建一个类型为lead的规范生成器实例,并通过将enum.class作为参数来调用方法。下面的示例代码。 (请注意,这只是一个示例)
static SpecificationsBuilder<Lead> specbldr = new SpecificationsBuilder<Lead>();

specbldr.whereEnumFieldEquals(Lead_.SENTIMENT,sentiment,SentimentEnum.class));