簡體   English   中英

如何使用JPA和Hibernate使用映射為ORDINAL的Enum參數進行查詢

[英]How to query using an Enum parameter mapped as ORDINAL using JPA and Hibernate

我需要通過枚舉類型從數據庫中獲取數據。 我有以下枚舉:

public enum ShopType {
    VANS("VANS"), ATTICUS("ATTICUS"), FAMOUS("FAMOUS")

    ShopType(String label) {
        this.label = label;
    }

    private String label;

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }
}

在我的DAO類中,我有一個方法,它在jsp頁面上按所選類型返回對象列表。 jsp頁面上我發送選擇的值像String ,是不是?

那怎么看我的方法

@Transactional
public List<Shop> findByType(String type) {
    return sessionFactory.getCurrentSession().createQuery("from Shop where type=" + .....  .list();
}

我不知道如何創建正確的查詢。 Enum i存儲在我的數據庫中,如tinyint。

這是一個模型。

@Column(name = "type")
@Enumerated(EnumType.ORDINAL)
private ShopType type;

當你將enum設置為序數時,那么在查詢中你應該使用序數。 例;

@Transactional
public List<Shop> findByType(String type) {
    return sessionFactory.getCurrentSession().createQuery("from Shop where type=" + ShopType.valueOf(type).ordinal()).list();
}

如果更改@Enumerated(EnumType.STRING) ,那么您的查詢將如下所示;

@Transactional
public List<Shop> findByType(String type) {
    return sessionFactory.getCurrentSession().createQuery("from Shop where type=" + ShopType.valueOf(type).name()).list();
}

ShopType.valueOf(type) ,僅當字符串類型與枚舉名稱相同時才有效。 此外,如果您的標簽與枚舉名稱相同,那么您不需要標簽。 ShopType.VANS.name()等於"VANS"name()方法是final,可以肯定不能被覆蓋。

只需將String轉換為Enum並使用命名查詢參數

@Transactional
public List<Shop> findByType(String type) {
    ShopType enumType = shopTypeFromString(type);
    return sessionFactory.getCurrentSession().createQuery("from Shop where type=:p_type")
        .setParameter("p_type", enumType).list();
}

private ShopType shopTypeFromString(String type) {
    // You can implement this convertion in your own way
    return ShopType.valueOf(type);
}

您的查詢中的問題是您連接了bind參數值,除了導致您的問題之外,它還可能使您的應用程序暴露於SQL注入攻擊

如果使用綁定參數值編寫查詢:

Post post = entityManager.createQuery(
    "select p " +
    "from Post p " +
    "where p.status = :status", Post.class)
.setParameter("status", PostStatus.PENDING)
.getSingleResult();

assertEquals("High-Performance Java Persistence", post.getTitle());

Hibernate將在SQL查詢中正確使用ORDINAL值:

Query:["
    select 
        p.id as id1_0_,
        p.status as status2_0_, 
        p.title as title3_0_ 
    from 
        post p 
    where 
        p.status=?
"], 
Params:[
    0
]

有關一個工作示例,請查看我high-performance-java-persistence GitHub存儲庫中EnumOrdinalTest

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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