簡體   English   中英

使用枚舉 (EnumType.STRING) 在實體上使用 LIKE 運算符執行 JPA 查詢

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

我能夠存儲、檢索和查詢具有枚舉類型的實體(使用 JPA/Hibernate)。 枚舉字段使用@Enumerated(EnumType.STRING) 進行注釋。

是否可以執行"SELECT a FROM MyEntity a WHERE a.myEnum LIKE :param"

這個想法是讓它匹配枚舉值字符串(在數據庫中)匹配“SYSTEM_%”或“BUSINESS_%”等模式的任何實體。

感謝您的幫助。

- - 更新:

當我嘗試用這個查詢時:

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

使用值(表示匹配任何內容......):

%%

我得到這個例外:

  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)

絕對地。 只需使用query.setString("param", "BUSINESS_%"); . 請注意,使用setParameter()而不是setString()會拋出 ClassCastException ,因為 Hibernate 嘗試將其setString()轉換為枚舉,但是setString()正是您想要的。

據說在 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);
    }
}

如果有額外的 else if (value instanceoff String) 會更好...

作為一種解決方法,您可以通過將模式連接到查詢來構建查詢。

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

它適用於 Hibernate 以及 Eclipselink。

但是,不要嘗試使用由用戶輸入生成的pattern ,因為以這種方式構建查詢容易受到 sql 注入攻擊。

我遇到了同樣的問題,我做了以下事情:

  • 定義映射到同一 db 列的第二個屬性
  • 該屬性的類型是字符串
  • 它既不可更新也不可插入
  • 調整枚舉屬性的設置方法
  • 使 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;

現在您可以對 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM