简体   繁体   English

使用枚举 (EnumType.STRING) 在实体上使用 LIKE 运算符执行 JPA 查询

[英]Perform JPA query with LIKE operator on entity with enum (EnumType.STRING)

I am able to store, retrieve and query entities with enum types (using JPA/Hibernate).我能够存储、检索和查询具有枚举类型的实体(使用 JPA/Hibernate)。 The enum fields are annotated with @Enumerated(EnumType.STRING).枚举字段使用@Enumerated(EnumType.STRING) 进行注释。

Is it possible to do things like "SELECT a FROM MyEntity a WHERE a.myEnum LIKE :param" ?是否可以执行"SELECT a FROM MyEntity a WHERE a.myEnum LIKE :param"

The idea is to have it match any entity where the enum value string (in DB) matches a pattern like "SYSTEM_%" or "BUSINESS_%".这个想法是让它匹配枚举值字符串(在数据库中)匹配“SYSTEM_%”或“BUSINESS_%”等模式的任何实体。

Thanks for helping out.感谢您的帮助。

--- Update: - - 更新:

When I tried to query with this:当我尝试用这个查询时:

`@Query("SELECT e FROM MyEntity e WHERE e.myEnum LIKE :value")`

Using the values (to indicate match whatever...):使用值(表示匹配任何内容......):

%%

I get this exception:我得到这个例外:

  Caused by: java.lang.IllegalArgumentException: Parameter value [%%] did not match expected type [mypackage.MyEntity$MyEnum]
        at org.hibernate.ejb.AbstractQueryImpl.validateParameterBinding(AbstractQueryImpl.java:370)
        at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:343)
        at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:374)
        at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:71)

Absolutely.绝对地。 Just use query.setString("param", "BUSINESS_%");只需使用query.setString("param", "BUSINESS_%"); . . Note that using setParameter() instead of setString() throws a ClassCastException as Hibernate tries to cast it to an enum, however setString() does exactly what you want.请注意,使用setParameter()而不是setString()会抛出 ClassCastException ,因为 Hibernate 尝试将其setString()转换为枚举,但是setString()正是您想要的。

saidly there is a shortcut in the org.springframework.orm.hibernate3.HibernateTemplate:据说在 org.springframework.orm.hibernate3.HibernateTemplate 中有一个快捷方式:

protected void applyNamedParameterToQuery(Query queryObject, String paramName, Object value)
        throws HibernateException {

    if (value instanceof Collection) {
        queryObject.setParameterList(paramName, (Collection) value);
    }
    else if (value instanceof Object[]) {
        queryObject.setParameterList(paramName, (Object[]) value);
    }
    else {
        queryObject.setParameter(paramName, value);
    }
}

would be greate if there is an extra else if (value instanceoff String)...如果有额外的 else if (value instanceoff String) 会更好...

As a workaround you can build a query by concatenating pattern to the query.作为一种解决方法,您可以通过将模式连接到查询来构建查询。

em.createQuery("SELECT e FROM MyEntity e WHERE e.myEnum LIKE '" + pattern +"'")

It works with Hibernate as well as Eclipselink.它适用于 Hibernate 以及 Eclipselink。

However don't try this with pattern made from user input because constructing queries this way is vulnerable to sql injection attack.但是,不要尝试使用由用户输入生成的pattern ,因为以这种方式构建查询容易受到 sql 注入攻击。

I ran into the same problem and I did the following:我遇到了同样的问题,我做了以下事情:

  • define a second attribute mapping to the same db column定义映射到同一 db 列的第二个属性
  • type of that attribute is String该属性的类型是字符串
  • it is neither updateable nor insertable它既不可更新也不可插入
  • adapt the set methods of the enum attribute调整枚举属性的设置方法
  • make the String attribute a readonly property使 String 属性成为只读属性
    @Column(name = "status")
    @Enumerated(EnumType.STRING)
    private StatusEnum status;

    public void setStatus(StatusEnum status) {
        this.status = status;
        this.statusString = status.toString();
    }
    
    @Column(name ="status", updatable = false, insertable = false)
    private String statusString;

Now you can make queries using 'like' against the statusString:现在您可以对 statusString 使用 'like' 进行查询:

TypedQuery<MyEntity> query = 
    em.createQuery("select e from MyEntity e where e.statusString like 'CLOSED%', MyEntity.class);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 实体管理器@Enumerated(EnumType.STRING)-如何使其使用toString()? - Entity manager @Enumerated(EnumType.STRING) - how can I make it use toString()? 在数据库上从@Enumerated更改为@Enumerated(EnumType.STRING) - Change from @Enumerated to @Enumerated(EnumType.STRING) on database 控制Hibernate EnumType.STRING属性的排序顺序 - Control sort order of Hibernate EnumType.STRING properties 您可以使用 integer 值而不是 EnumType.STRING 或 ORDINAL 来保存枚举吗? - Can you save enums using an integer value instead of the EnumType.STRING or ORDINAL? Hibernate 和 Java 和 Postgres @Enumerated(value=EnumType.STRING) - 引起:org.postgresql.util.PSQLException:int 类型的错误值 - Hibernate and Java and Postgres @Enumerated(value=EnumType.STRING) - Caused by: org.postgresql.util.PSQLException: Bad value for type int JPA @Query与实体一样的参数 - JPA @Query with Entity like parameter Java JPA 类枚举字符串选项 - Java JPA enum-like String options Enum.valueOf(Class <T> enumType,String name)问题 - Enum.valueOf(Class<T> enumType, String name) question JPA - 如何使用LIKE运算符和AttributeConverter进行查询 - JPA - How to query with a LIKE operator in combination with an AttributeConverter 声明变量为Enum之间的区别 <EnumType> 和EnumType - Difference between declare variable as Enum<EnumType> and EnumType
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM