这是同样的问题:
How to dynamically generate SQL query based on user's selections?
唯一的区别是,我对使用Java / JPA(+可能是EclipseLink或Hibernate特定扩展)的解决方案感兴趣。
我需要创建一个GUI,用户可以使用该GUI选择几个属性,这些属性将用于查询数据库以查找合适的人员。我正在寻找如何根据用户的选择动态生成数据库查询的想法。
查询将包含几个字段,但为了得到这个想法,我将仅包含以下三个字段作为示例:
职业 - 可以有0到n个占用字符串。如果给出了职业字符串,其中一个必须匹配。
年龄 - 年龄可以是:
Age参数在查询中是可选的。此外,用户可以指定年龄是否为必需参数。如果不是必需的,并且没有年龄的人是他/她的个人资料,则此人的年龄标准将被忽略。
示例查询:
没有给出任何标准:
select * from persons
只有职业:
select * from persons where occupation = 'dentist'
已经举办了几项职业:
select * from persons where (occupation = 'dentist' or occupation = 'engineer')
年龄已经大于值,并且需要存在于个人资料中:
select * from persons where age >= 30
高度已作为范围给出,并且不需要存在于个人资料中:
select * from persons where (height is null or (height >= 30 and height <= 40))
不同标准的组合:
select * from persons where occupation = 'dentist' and age >= 30 and (height is null or (height >= 30 and height <= 40))
我已经实现了能够以字符串形式生成查询的代码,但它确实不太漂亮。我正在寻找能够实现这一目标的最有效和最有效的方法。
答案 0 :(得分:3)
我认为有很多不同的工具querydsl,torpedoquery e Object Query,这三个允许编写类型安全查询,否则你可以使用条件api,如果你是使用jpa 2也JPA2 Typesafe Query。
使用所有这些工具,您可以在运行时构建查询!!
答案 1 :(得分:1)
在Hibernate中,您可以使用Criteria个查询。
在Toplink中,我们获得了Expression, and ExpressionBuilder。
答案 2 :(得分:1)
如果要在JPA 1.X中执行此操作,可以使用此处所述的自定义查询构建器http://rrusin.blogspot.com/2010/02/jpa-query-builder.html。 这样可以创建如下查询:
return new JpaQueryBuilder().buildQuery(em,
new Object[] {
"select c from Car c where c.name is not null",
new JQBParam("name", name, " and c.name = :name"),
new JQBParam("type", type, " and c.type = :type")
}
)
答案 3 :(得分:1)
我使用Querydsl框架,因为我使用的是JPA 1.0,它不包含Criteria API,我还需要你描述的功能。编写Querydsl代码很简单,代码比Criteria API代码短。 Querydsl可以免费使用,它支持类型安全查询。
答案 4 :(得分:0)
在我的代码中,我正在使用AND
和OR
个对象。它们将列表作为参数(使用Java 5的可变参数看起来很好),并在字符串中将它们与必要的空格和括号连接起来。伪代码:
AND(WhereCond ... conds) { this.conds = conds; }
toString() { return conds.length == 0 ? "" : "(" + join(conds, " AND ") + ")" };
其中join()
将对象数组转换为字符串数组,然后使用参数连接元素。