Hibernate5.4官方用户指南
Hibernate查询语言(HQL)和Java持久化查询语言(JPQL)都是以对象模型为查询对象的语言,与SQL类似。JPQL是HQL的子集。
HQL和JPQL都是非类型安全的方法来执行查询操作。Criteria查询提供了一种类型安全的查询方法。
略
Hibernate的Session接口继承了JPA的EntityManager接口。
Hibernate的Query接口继承了JPA的Query接口。
1 获取JPA的Query或TypedQuery
Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name"
);
TypedQuery typedQuery = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name"
// createQuery第二个参数实体类类型
, Person.class
);
2 获取命名查询的 JPA的Query或TypedQuery
@NamedQuery(
name = "get_person_by_name",
query = "select p from Person p where name = :name"
)
Query query = entityManager.createNamedQuery( "get_person_by_name" );
TypedQuery typedQuery = entityManager.createNamedQuery(
"get_person_by_name", Person.class
);
3 获取命名查询的 Hibernate的Query或TypedQuery
Hibernate提供了一个@NamedQuery注解,@NamedQuery注解提供了配置各种查询功能的方法,如:刷新模式、可缓存性、超时。
@NamedQueries({
@NamedQuery(
name = "get_phone_by_number",
query = "select p " +
"from Phone p " +
"where p.number = :number",
timeout = 1,
readOnly = true
)
})
Phone phone = entityManager
.createNamedQuery( "get_phone_by_number", Phone.class )
.setParameter( "number", "123-456-7890" )
.getSingleResult();
4 基本的JPA的Query用法
Query接口可用于控制查询的执行(类似Hibern提供的@NamedQuery注解的功能),如:指定超时、控制缓存以下:
Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
// timeout - in milliseconds
.setHint( "javax.persistence.query.timeout", 2000 )
// flush only at commit time
.setFlushMode( FlushModeType.COMMIT );
5 执行查询前,最后一步是绑定一定义参数的值。
JPA名称参数绑定:
Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" );
// For generic temporal field types (e.g. `java.util.Date`, `java.util.Calendar`)
// we also need to provide the associated `TemporalType`
Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.createdOn > :timestamp" )
.setParameter( "timestamp", timestamp, TemporalType.DATE );
JPA位置参数绑定:
Query query = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like ?1" )
.setParameter( 1, "J%" );
6 JPA提供了两种方法检索结果集
List persons = entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.getResultList();
Person person = (Person) entityManager.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.getSingleResult();
HQL查询表示从Hibernate的Query获得Session。若HQL是命名查询,则使用getNamedQuery获取Session;或者使用createQuery查询。
1 获取Hibernate Query
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name"
);
2 获取命名查询的 Hibernate Query
org.hibernate.query.Query query = session.getNamedQuery( "get_person_by_name" );
3 Hibernate基本查询用法
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
// timeout - in seconds
.setTimeout( 2 )
// write to L2 caches, but do not read from them
.setCacheMode( CacheMode.REFRESH )
// assuming query cache was enabled for the SessionFactory
.setCacheable( true )
// add a comment to the generated SQL if enabled via the hibernate.use_sql_comments configuration property
.setComment( "+ INDEX(p idx_person_name)" );
4 Hibernate名称参数绑定
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
// StringType.INSTANCE
.setParameter( "name", "J%", StringType.INSTANCE );
5 Hibernate名称参数绑定(推断类型)
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" );
6 Hibernate名称参数绑定(简写形式)
org.hibernate.query.Query query = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name " +
" and p.createdOn > :timestamp" )
.setParameter( "name", "J%" )
.setParameter( "timestamp", timestamp, TemporalType.TIMESTAMP);
7 Hibernate提供两种最常用方法检索结果集
List persons = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.list();
Person person = (Person) session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.uniqueResult();
hibernate提供了用于使用服务器端游标滚动查询和处理结果。
Query.scroll()返回一个org.hibernate.ScrollableResults,ScrollableResults可以对ResultSet结果集任何方向(前、后)导航滚动。
1 滚动ResultSet包含的实体
try ( ScrollableResults scrollableResults = session.createQuery(
"select p " +
"from Person p " +
"where p.name like :name" )
.setParameter( "name", "J%" )
.scroll()
) {
while(scrollableResults.next()) {
Person person = (Person) scrollableResults.get()[0];
process(person);
}
}
2 Hibernate支持Query.iterate()
当已知加载的条目已经存储在二级缓存中时,它用于加载实体。迭代背后的想法是只在SQL查询中获得匹配的标识符。通过二级缓存查找,可以从中解析标识符。如果这些二级缓存查找失败,则需要针对数据库发出其他查询。
除了Java类和属性的名称外,查询不区分大小写。
HQL和JPQL都允许执行:SELECT、UPDATE、DELETE语句。
HQL允许执行INSERT语句。
注意:何时执行UPDATE、DELETE语句?
执行批量更新或删除操作时,可能导致数据库与活动持久性上下文中的实体间出现不一致。通常,批量更新或删除应该只在新持久化上下文中的事务内执行,或者在获取或访问其状态可能受此操作影响的实体之前执行。