三年总结出来的11个JPA和Hibernate查询配置小技巧

时间:2024-07-26 12:05:44

JPA和Hibernate提供了一系列暗示hints能够帮助你更好地定制你的查询语言,这些小暗示或暗语是一种附加信息,你可以利用这些暗语做很多事情,比如设置查询的timeout,使用实体图或定义查询缓存的缓存。

在我们介绍一系列暗语之前,首先我们看看如何使用查询暗语,你可以在EntityManager.find 方法中使用它,EntityManager.find接受一个HashMap<String,Object>类型,该HashMap的值就是你提供的暗语设置,相当于提供一个附加参数。

EntityGraph<?> graph = em.getEntityGraph(“graph.AuthorBooks”);HashMap<String, Object> properties = new HashMap<>();properties.put(“javax.persistence.fetchgraph”, graph);em.find(Author.class, 1L, properties);

注意到properties是一个HashMap的值,里面是你要设置的暗语javax.persistence.fetchgraph

此外,Query接口提供了setHint(String name, Object value)方法来设置暗语:

EntityGraph<?> graph = em.getEntityGraph(“graph.AuthorBooks”);em.createQuery(“SELECT a FROM Author a”).setHint(“javax.persistence.fetchgraph”, graph).getResultList();

你也能使用@NamedQuery提供暗语设置:

@NamedQuery(name = “selectAuthors”, query = “SELECT a FROM Author a”, hints = @QueryHint(name = QueryHints.COMMENT, value = “a custom SQL comment”))

这样暗语将在每个named query的实例中使用,你就不必再设置了:

em.createNamedQuery(“selectAuthors”).getResultList();

好了,上面介绍了使用方法,下面是暗语的列表介绍:

JPA Hints

1. javax.persistence.lock.timeout (Long – milliseconds)

获得一个持久锁的timeout

2. javax.persistence.query.timeout (Long – milliseconds)

定义了一个查询在其被取消之前运行运行多长时间,Hibernate并不提供,而是希望借助JDBC驱动的 JDBCStatement.setTimeout 方法实现.

3. javax.persistence.cache.retrieveMode (CacheRetrieveMode – USE | BYPASS)

retrieveMode 支持值 USE 和 BYPASS ,告诉 Hibernate:如果使用USE ,使用二级缓存查询返回一个实体,而使用 BYPASS 就是直接从数据库获得这个实体。

4. javax.persistence.cache.storeMode (CacheStoreMode – USE | BYPASS | REFRESH)

定义了如何将一个改变的实体写入二级缓存中,使用 USE 表示使用缓存,如已经存在即修改,如缓存中不存在就将实体加入缓存,,如果使用BYPASS 只更新已经存在的实体,如果不存在就不加入缓存。如果使用 REFRESH,在实体从缓存中抓取之前首先将实体放入缓存。

5. javax.persistence.loadgraph (EntityGraph)

提供一个实体图作为加载图(load graph)给查询。

6. javax.persistence.fetchgraph (EntityGraph)

提供一个实体图作为一个fetchgraph用于查询

下面是Hibernate Hints部分:

7. org.hibernate.flushMode (FlushMode – AUTO | ALWAYS | COMMIT | MANUAL)

如果你修改一个实体,Hibernate还在一级缓存中保留这些改变,直到全部flush到数据库,默认情况下,这会在每次查询之前发生flush,但是你能提供一个flushMode的值来控制flush的时机::

AUTO = 由Hibernate决定是否将修改后的实体写入数据库

ALWAYS = 在每次查询之前都会写入

COMMIT = Hibernate不会将修改写入数据库直到事务被提交了

MANUAL = 你得自己将会话中修改flush到数据库中。

8. org.hibernate.readOnly (boolean)

如果你不想将任何修改应用到实体,你能设置这个值为真true,这会失效Hibernate的脏数据检查,提高性能。

9. org.hibernate.fetchSize (Long – number of records)

Hibernate提供这个值给JDBC驱动,定义在一个批处理的查询行数,这能提高JDBC和数据库之间的通讯效率。

10. org.hibernate.comment (String – custom comment)

如果在persistence.xml 文件设置这个值true, Hibernate会为每个查询产生一个comment,将其写入到日志文件,如果你需要分析巨量和复杂SQL日志有用。

11. org.hibernate.cachable

如果你要使用Hibernate的查询缓存,你得在persistence.xml 文件中配置它,将这个值设为true。

写在最后:欢迎留言讨论,加关注,持续更新!!!