2010-03-15 84 views
17

在使用Hibernate时,有没有什么方法可以指定可选参数(例如,当从表单提供搜索参数,而不是所有参数都是必需的)?我正在使用本机SQL查询,但问题可能也适用于命名的HQL查询。Hibernate中带有命名查询的可选参数?

我很肯定这个答案是'不',但我还没有在文档中找到确切的答案。

回答

10

AFAIK,没有这样的事情,所以你必须为此写一个动态查询。也许看看这个previous answer显示了如何在HQL中执行此操作(可以转换为SQL),并且还显示了Criteria API如何使它更简单,并因此更适合我的这一工作。

更新:(回答OP的评论)使用旧数据库对于Hibernate来说确实很棘手。也许你可以使用动态原生查询并返回non-managed entities。但从长远来看,事情可能会变得更糟(我不能告诉你)。也许Hibernate并不是您的案例中的最佳选择,而像iBATIS这样的东西可以为您提供所需的灵活性。

+0

谢谢。这几乎是我所想的。我熟悉你在其他答案中提出的两种方法,但我坚持使用一种噩梦般的遗留数据库模式,这对我的特殊情况来说并不适合Hibernate方法。到目前为止,我已经完成了它的工作,但有一些新的要求,我似乎无法满足使用直接的Hibernate映射。我可能会放弃并使用iBATIS来处理这种情况。不是真正的兴奋,添加另一种技术作为一种创可贴,但我想这就是生活。谢谢。 – Ickster 2010-03-15 02:14:53

+0

@Ickster查看我的更新。 – 2010-03-15 03:21:14

+1

感谢您的更新。我也考虑过这种方法,并且考虑到我正在处理的参数的数量,我决定使用iBATIS可能更干净。感谢您的建议。 – Ickster 2010-03-15 15:30:03

29

如在different answer提到前面引用的question,下面的HQL建设工作对我来说:

select o from Product o WHERE :value is null or o.category = :value 

如果:值在给定值为null,将返回所有产品。

又见Optional or Null Parameters

请注意,这不会因this bug的Sybase的某些版本的工作,所以下面是一个另类:

select o from Product o WHERE isnull(:value, 1) = 1 or o.category = :value 
5

遗憾的是“可选或空参数下的解决方案“不适用于IN列表。 我不得不改变了查询作为跟随...

命名查询定义:

select ls from KiCOHeader co 
... 
join lu.handlingType ht 
where (:inHandlingTypesX = 1 OR ht.name in (:inHandlingTypes)) 

代码:

Set<KiHandlingTypeEnum> inHandlingTypes = ... 

Query query = persistence.getEm().createNamedQuery("NAMED_QUERY"); 
query.setParameter("inHandlingTypesX", (inHandlingTypes == null) ? 1 : 0); 
query.setParameter("inHandlingTypes", inHandlingTypes); 

List<KiLogicalStock> stocks = query.getResultList(); 

非常有趣的工作。

+0

不能工作了.. – george 2016-11-17 16:59:38

2

处理可选列表参数的另一个解决方案是使用COALESCE函数检查null。 COALESCE为supported by Hibernate返回列表中的第一个非空参数,允许您在列表中有多个项目时检查列表上的空值而不中断语法。

HQL例如具有可选的参数和列表参数:

select obj from MyEntity obj 
where (COALESCE(null, :listParameter) is null or obj.field1 in (:listParameter)) 
    and (:parameter is null or obj.field2 = :parameter) 

这与SQL Server方言为我工作。

+0

这对我没有用,当':listParameter'没有被定义时,hibernate抱怨'COALESCE(null,)'。我的解决方案是也传递一个额外的参数,并以这种方式写入where条件:'(:listParamterSize = 0或obj.field1 in(:listParameter))' – jeremija 2015-05-13 09:59:32

+0

它有效,但必须定义':listParameter',至少为空。此解决方案的优点是您可以将参数传递为null,并且不需要额外的参数。 – 2015-11-27 09:53:52