java 如何使用 JPA 和 Hibernate 使用映射为 ORDINAL 的枚举参数进行查询
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26106557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to query using an Enum parameter mapped as ORDINAL using JPA and Hibernate
提问by user3127896
I need to get data from database by enum type. I have following enum:
我需要通过枚举类型从数据库中获取数据。我有以下枚举:
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;
}
}
In my DAO class i have method which returns list of objects by selected type on jsp
page. On jsp
page i send selected value like String
, is it right?
在我的 DAO 类中,我有一个方法,它按jsp
页面上的选定类型返回对象列表。在jsp
页面上,我发送选定的值,例如String
,对吗?
That how looks my method
那看起来我的方法
@Transactional
public List<Shop> findByType(String type) {
return sessionFactory.getCurrentSession().createQuery("from Shop where type=" + ..... .list();
}
I don't know how to create right query. Enum i store in my database like tinyint.
我不知道如何创建正确的查询。枚举我像tinyint一样存储在我的数据库中。
Here is a model.
这是一个模型。
@Column(name = "type")
@Enumerated(EnumType.ORDINAL)
private ShopType type;
回答by Petar Butkovic
As you set your enum as ordinal, then in query you should use ordinal. Example;
当您将枚举设置为序号时,那么在查询中您应该使用序号。例子;
@Transactional
public List<Shop> findByType(String type) {
return sessionFactory.getCurrentSession().createQuery("from Shop where type=" + ShopType.valueOf(type).ordinal()).list();
}
If you change @Enumerated(EnumType.STRING)
, then your query will look like;
如果您更改@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)
, This will work only if string type is same as enum name.
Also if your label is same as enum name, then you don't need label.
ShopType.VANS.name()
is equals"VANS"
and name()
method is final, you can be sure that can't be overridden.
ShopType.valueOf(type)
, 仅当字符串类型与枚举名称相同时才有效。此外,如果您的标签与枚举名称相同,那么您就不需要标签。
ShopType.VANS.name()
是等于"VANS"
和name()
方法是最终的,你可以确定不能被覆盖。
回答by vp8106
Just convert String to Enum and use named query parameter
只需将 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);
}
回答by Vlad Mihalcea
The problem in your query is that you concatenated the bind parameter value which, apart from causing your issue, may expose your application to SQL injection attacks.
您查询中的问题是您连接了绑定参数值,这除了导致您的问题之外,还可能使您的应用程序暴露于SQL 注入攻击。
If you write the query using bind parameter values:
如果您使用绑定参数值编写查询:
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 will properly use the ORDINAL value in the SQL query:
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
]
For a working example, check out the EnumOrdinalTest
in my high-performance-java-persistence
GitHub repository.
有关工作示例,请查看EnumOrdinalTest
我的high-performance-java-persistence
GitHub 存储库中的。