Criteria 非常擅长处理许多可选搜索参数,例如您可能在具有多参数“搜索表单”的典型网页上找到的参数。使用 HQL,开发人员倾向于使用 StringBuilder 添加 where 子句表达式(避免这种情况!)。使用 Criteria,您不需要这样做。哈迪克也发表了类似的观点。
HQL/JPAQL 可用于大多数其他事情,因为代码往往更小并且更容易让开发人员理解。
如果使用 HQL,真正频繁的查询可以变成命名查询。我更喜欢稍后在进行一些分析之后再执行此操作。
I'm the guy who wrote the Hibernate 3 query translator back in 2004, so I know something about how it works.
Criteria, in theory should have less overhead than an HQL query (except for named queries, which I'll get to). This is because Criteria doesn't need to parse anything. HQL queries are parsed with an ANTLR-based parser and then the resulting AST is turned into SQL. However, with HQL/JPAQL you can define named queries, where the SQL is generated when the SessionFactory starts up. In theory, named queries have less overhead than Criteria.
So, in terms of SQL-generation overhead we have:
Named HQL/JPAQL Query - SQL generation happens only once.
Criteria - No need to parse before generating.
(non-named) HQL/JPAQL Query - Parse, then generate.
That said, choosing a query technique based on the overhead of parsing and SQL generation is probably a mistake in my opinion. This overhead is typically very small when compared to performing a real query on a real database server with real data. If this overhead does actually show up when profiling the app then maybe you should switch to a named query.
Here are the things I consider when deciding between Criteria and HQL/JPAQL:
First, you have to decide if you're OK with having a dependency on Hibernate-proprietary API in your code. JPA doesn't have Criteria.
Criteria is really good at handling many optional search parameters such as you might find on a typical web page with a multi-parameter 'search form'. With HQL, developers tend to tack on where clause expressions with StringBuilder (avoid this!). With Criteria, you don't need to do that. Hardik posted similar opinions.
HQL/JPAQL can be used for most other things, because the code tends to be smaller and easier for developers to understand.
Really frequent queries can be turned into named queries if you use HQL. I prefer to do this later, after some profiling.
I mostly prefer Criteria Queries for dynamic queries. For example it is much easier to add some ordering dynamically or leave some parts (e.g. restrictions) out depending on some parameter.
On the other hand I'm using HQL for static and complex queries, because it's much easier to understand/read HQL. Also, HQL is a bit more powerful, I think, e.g. for different join types.
Writing HQL makes the code messy. It doesn't look like writing clean Object Oriented Code anymore.
While writing Criteria Queries, IDE suggests us with Intellisense, so there is less chance of committing mistakes except when we write something like variable names in double quotes.
You are right and not. Result list is retrieved from database or cache with the org.hibernate.loader.Loader class. When cache is not enabled, prepared statement is build using the Dialect object which is created in SessionFactoryImp. So, statements either initialized per list call. Besides, low-level query is generated automatically. Basically, it is an aid, but there may be a case when a specific query will be more effective when manually written.
发布评论
评论(5)
我是 2004 年编写 Hibernate 3 查询翻译器的人,所以我知道它是如何工作的。
理论上,Criteria 的开销应该比 HQL 查询少(命名查询除外,我将对此进行介绍)。这是因为 Criteria 不需要解析任何内容。 HQL 查询使用基于 ANTLR 的解析器进行解析,然后将生成的 AST 转换为 SQL。但是,使用 HQL/JPAQL,您可以定义命名查询,其中 SQL 在以下情况下生成:
SessionFactory 启动。理论上,命名查询的开销比 Criteria 少。
因此,就 SQL 生成开销而言,我们有:
也就是说,在我看来,基于解析和 SQL 生成的开销来选择查询技术可能是一个错误。与在真实数据库服务器上使用真实数据执行真实查询相比,这种开销通常非常小。如果在分析应用程序时确实出现了这种开销,那么也许您应该切换到命名查询。
以下是我在 Criteria 和 HQL/JPAQL 之间做出决定时考虑的事项:
I'm the guy who wrote the Hibernate 3 query translator back in 2004, so I know something about how it works.
Criteria, in theory should have less overhead than an HQL query (except for named queries, which I'll get to). This is because Criteria doesn't need to parse anything. HQL queries are parsed with an ANTLR-based parser and then the resulting AST is turned into SQL. However, with HQL/JPAQL you can define named queries, where the SQL is generated when the
SessionFactory starts up. In theory, named queries have less overhead than Criteria.
So, in terms of SQL-generation overhead we have:
That said, choosing a query technique based on the overhead of parsing and SQL generation is probably a mistake in my opinion. This overhead is typically very small when compared to performing a real query on a real database server with real data. If this overhead does actually show up when profiling the app then maybe you should switch to a named query.
Here are the things I consider when deciding between Criteria and HQL/JPAQL:
我正在处理数百万张记录。我发现 HQL 比 Criteria 快得多。 Criteria 在性能方面落后很多。
如果您正在处理大量数据,那么请选择 HQL。
I am working on millions of record. I found HQL is much more faster than Criteria. Criteria lags a lot in performance.
If you are dealing with lot of data then go for HQL.
我最喜欢动态查询的条件查询。例如,根据某些参数动态添加一些排序或保留某些部分(例如限制)要容易得多。
另一方面,我使用 HQL 进行静态和复杂的查询,因为它更容易理解/阅读 HQL。另外,我认为 HQL 更强大一些,例如对于不同的连接类型。
JPA 和 Hibernate - 标准与 JPQL 或 HQL
I mostly prefer Criteria Queries for dynamic queries. For example it is much easier to add some ordering dynamically or leave some parts (e.g. restrictions) out depending on some parameter.
On the other hand I'm using HQL for static and complex queries, because it's much easier to understand/read HQL. Also, HQL is a bit more powerful, I think, e.g. for different join types.
JPA and Hibernate - Criteria vs. JPQL or HQL
我认为 Criteria 相对于 HQL 的其他优势:
编写 HQL 会使代码变得混乱。
它看起来不再像编写干净的面向对象代码了。
在编写条件查询时,IDE 建议我们使用 Intellisense,因此除非我们在双引号中编写诸如变量名之类的内容,否则犯错误的可能性较小。
Other Advantages I think for Criteria over HQL:
Writing HQL makes the code messy.
It doesn't look like writing clean Object Oriented Code anymore.
While writing Criteria Queries, IDE suggests us with Intellisense, so there is less chance of committing mistakes except when we write something like variable names in double quotes.
你是对的,但又不是。
结果列表是使用 org.hibernate.loader.Loader 类从数据库或缓存中检索的。当缓存未启用时,准备好的语句是使用 SessionFactoryImp 中创建的 Dialect 对象构建的。因此,语句要么在每次列表调用时初始化。
此外,低级查询是自动生成的。基本上,它是一种辅助,但在某些情况下,手动编写特定查询可能会更有效。
You are right and not.
Result list is retrieved from database or cache with the
org.hibernate.loader.Loader
class. When cache is not enabled, prepared statement is build using the Dialect object which is created in SessionFactoryImp. So, statements either initialized per list call.Besides, low-level query is generated automatically. Basically, it is an aid, but there may be a case when a specific query will be more effective when manually written.