20715894 nanoseconds spent executing 1 flushes (flushing a total of 13 entities and 13 collections);
88175 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
}
正如你所看到的JPQL查询和对12个选定的Author实体的每一个调用getBooks办法,招致了13个查询。这比大少数开发人员所以为的还要多,在他们看到如此复杂的代码片段的时分。
假设你让Hibernate初始化所需的关联,那么你可以很容易地避免这种状况。有若干不同的方式可以做到这一点。最复杂的办法是添加JOIN FETCH语句到FROM子句中。
Author a = em.createQuery(
"SELECT a FROM Author a JOIN FETCH a.books WHERE a.id = 1",
Author.class).getSingleResult();
错误4:选择比所需的更多记载
当我通知你选择太多的记载会减慢运用顺序的速度时,我敢保证你一定不会感到诧异。但是我依然常常会发现这个成绩,当我在咨询电话中剖析运用顺序的时分。
其中一个缘由能够是JPQL不支持你在SQL查询中运用OFFSET和LIMIT关键字。这看起来似乎不能限制查询中检索到的记载数量。但是,你可以做到这一点。你只需求在Query接口上,而不是在JPQL语句中设置此信息。
我在下面的代码片段中做到这一点。我首先经过id排序选定的Author实体,然后通知Hibernate检索前5个实体。
List<Author> authors = em.createQuery("SELECT a FROM Author a ORDER BY a.id ASC", Author.class)
.setMaxResults(5)
.setFirstResult(0)
.getResultList();
错误5:不运用绑定参数
绑定参数是查询中的复杂占位符,并提供了许多与功用有关的益处:
它们十分易于运用。
Hibernate自动执行所需的转换。
Hibernate会自动本义Strings,避免SQL注入破绽。
而且也可以协助你完成一个高功用的运用顺序。
大少数运用顺序执行少量相反的查询,只在WHERE子句中运用了一组不同的参数值。绑定参数允许Hibernate和数据库辨认与优化这些查询。
你可以在JPQL语句中运用命名的绑定参数。每个命名参数都以“:”扫尾,前面跟它的名字。在查询中定义了绑定参数后,你需求调用Query接口上的setParameter办法来设置绑定参数值。
TypedQuery<Author> q = em.createQuery(
"SELECT a FROM Author a WHERE a.id = :id", Author.class);
q.setParameter("id", 1L);
Author a = q.getSingleResult();
错误6:执行业务代码中的一切逻辑
关于Java开发人员来说,在业务层完成一切的逻辑是自但是然的。我们可以运用我们最熟习的言语、库和工具。
但有时分,在数据库中完成操作少量数据的逻辑会更好。你可以经过在JPQL或SQL查询中调用函数或许运用存储进程来完成。
让我们快速看看如何在JPQL查询中调用函数。假设你想深化讨论这个话题,你可以阅读我关于存储进程的文章。
你可以在JPQL查询中运用标准函数,就像在SQL查询中调用它们一样。你只需援用该函数的称号,后跟一个左括号,一个可选的参数列表和一个右括号。
Query q = em.createQuery("SELECT a, size(a.books) FROM Author a GROUP BY a.id");
List<Object[]> results = q.getResultList();
并且,经过JPA的函数function,你也可以调用数据库特定的或自定义的数据库函数。
TypedQuery<Book> q = em.createQuery(
"SELECT b FROM Book b WHERE b.id = function('calculate', 1, 2)",
Book.class);
Book b = q.getSingleResult();
错误7:在理由地调用flush办法
(责任编辑:admin)