hibernate与jpa的关系,以及使用分页和动态查询

赵莉      2022-04-18     143

关键词:


最近由于项目调动,我去了使用JPA的项目组, 因为之前的项目组使用MyBatis,所以一时间关于JPA和Hibernate的知识体系记得不熟,导致出现了混乱;在网上看到了这篇文章,终于解决了我心中的疑惑:JPA是一种规范,Hibernate实现了这种规范 。
这篇短小精悍的文章给了我很多的启发,于是,我把它”复制”到了本文!


http://blog.sina.com.cn/s/blog_5f1619e80100yoxz.html


我知道Jpa是一种规范,而Hibernate是它的一种实现。除了Hibernate,还有EclipseLink(曾经的toplink),OpenJPA等可供选择,所以使用Jpa的一个好处是,可以更换实现而不必改动太多代码。
在play中定义Model时,使用的是jpa的annotations,比如javax.persistence.Entity, Table, Column, OneToMany等等。但它们提供的功能基础,有时候想定义的更细一些,难免会用到Hibernate本身的annotation。我当时想,jpa这 么弱还要用它干什么,为什么不直接使用hibernate的?反正我又不会换成别的实现。
因为我很快决定不再使用hibernate,这个问题就一直放下了。直到我现在在新公司,做项目要用到Hibernate。
我想抛开jpa,直接使用hibernate的注解来定义Model,很快发现了几个问题:
jpa中有Entity, Table,hibernate中也有,但是内容不同
jpa中有Column,OneToMany等,Hibernate中没有,也没有替代品
我原以为hibernate对jpa的支持,是另提供了一套专用于jpa的注解,但现在看起来似乎不是。一些重要的注解如Column, OneToMany等,hibernate没有提供,这说明jpa的注解已经是hibernate的核心,hibernate只提供了一些补充,而不是两 套注解。要是这样,hibernate对jpa的支持还真够足量,我们要使用hibernate注解就必定要使用jpa。
实际情况是不是这样?在被群里(Scala交流群132569382)的朋友鄙视一番却没有给出满意答案的时候,我又想起了万能的stackoverflow,上去提了两个问:
http://stackoverflow.com/questions/8306742/if-i-want-to-use-hibernate-with-annotation-do-i-have-to-use-javax-persistence
http://stackoverflow.com/questions/8306793/why-jpa-and-hibernate-both-have-entity-and-table-annotations
第一个是问如果想用hibernate注解,是不是一定会用到jpa的。网友的回答:“是。如果hibernate认为jpa的注解够用,就直接用。否则会弄一个自己的出来作为补充”
第二个是问,jpa和hibernate都提供了Entity,我们应该用哪个,还是说可以两个一起用?网友回答说“Hibernate的Entity是继承了jpa的,所以如果觉得jpa的不够用,直接使用hibernate的即可”。


这两天又仔细研究了一下JPA和Hibernate的使用,把了解到的东西和大家分享一下;先和大家简单讲一下JPA,Hibernate,Spring Data JPA的概念!


JPA java persistence api ,为POJO(就是我们的JavaBean)提供持久化标准规范,JavaEE规范之一
主要思想,3个:
1. ORM(Object Relational Mapping)映射元数据,通过XML或注解,描述对象和表之间的关系,框架据此将实体对象持久化到数据库
关键字:ORM映射、实体持久化
2. 规范的API,通过操作实体对象,就能执行对应数据库的CRUD操作,ORM框架让开发从繁琐的JDBC和SQL代码中解脱出来
关键字:实体对象、JDBC和SQL、解脱
3. 查询语言,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合
关键字:面向对象查询、SQL解耦

  1. ORM是JPA规范中的一个体现思想,JPA规范包含了ORM
  2. Sun公司为了简化现有Java EE和Java SE应用的对象持久化的开发工作,整合ORM技术,结束现在Hibernate、iBATIS、TopLink等ORM框架各自为营的局面,提出了新的JPA ORM规范。
  3. JPA的实现者(供应商):Hibernate、OpenJPA、TopLink等

Hibernate在JPA规范出现后,也提供了对JPA的实现,也就是说Hibernate有两套开发风格,一种我们以前学习的,另一种是JPA风格的。具体demo参考
http://www.micmiu.com/j2ee/hibernate/hibernate-jpa-demo/

Spring Data 是Spring 的一个子项目(不是很成熟), 旨在统一和简化对各类型持久化存储, 而不拘泥于是关系型数据库还是NoSQL 数据存储。(野心很大)


无论是哪种持久化存储, 数据访问对象(或称作为DAO,即Data Access Objects)通常都会提供对单一域对象的CRUD (创建、读取、更新、删除)操作、查询方法、排序和分页方法等。


Spring Data则提供了基于这些层面的统一接口(CrudRepository,PagingAndSortingRepository)以及对持久化存储的实现。

Spring Data 包含多个子项目:
l Commons - 提供共享的基础框架,适合各个子项目使用,支持跨数据库持久化
l Hadoop - 基于 Spring 的 Hadoop 作业配置和一个 POJO 编程模型的 MapReduce 作业
l Key-Value - 集成了 Redis 和 Riak ,提供多个常用场景下的简单封装
l Document - 集成文档数据库:CouchDB 和 MongoDB 并提供基本的配置映射和资料库支持
l Graph - 集成 Neo4j 提供强大的基于 POJO 的编程模型
l Graph Roo AddOn - Roo support for Neo4j
l JDBC Extensions - 支持 Oracle RAD、高级队列和高级数据类型
l JPA - 简化创建 JPA 数据访问层和跨存储的持久层功能
l Mapping - 基于 Grails 的提供对象映射框架,支持不同的数据库
l Examples - 示例程序、文档和图数据库
l Guidance - 高级文档

(Spring Data就像一口缸,什么都想往里装,想实现完全统一的数据访问层的API)

Spring Data JPA是在JPA规范下提供了Repository层的实现,但是使用哪一种ORM需要你来决定(默认使用Hibernate JPA的实现)。虽然ORM框架都实现了JPA规范,但是在不同的ORM框架之间切换仍然需要编写不同的代码,而通过使用Spring data jpa能够方便大家在不同的ORM框架之间进行切换而不要更改代码。并且spring data jpa 对Repository层封装的很好,也省去了不少的麻烦。

对于hibernate和spring data jpa来说,他们的增删改方法都是自带的有,并且一般情况下够用。
重点要了解的是,他们查询的各种用法,包括了分页和动态查询:
首先是Hibernate,使用sessionFactory创建的session对象进行动态和分页查询。
然后我们重点讲一下Spring Data JPA,它分为以下几种:

第2种和第3种差不多,但是hql比自带的方法灵活一点,也可以支持更复杂的查询,例如模糊查询!接下来,我就挑几个重要的举举例子:

使用Specification查询,需要让数据访问层(dao)的接口继承JpaSpecificationExecutor

其他只需要继承JpaRepository

一.(JPA自带的查询,适用于查询指定条件的数据)

二.(本地sql查询,注意表名啥的都用数据库中的名称,适用于特定数据库的查询)

三.(Query注解,hql语局,适用于查询指定条件的数据)


同时hql语句也支持很多的函数,可以用于复杂查询。这是地址:Hql的函数使用

四.(Criteria查询,适用于动态sql查询)


CriteriaBuilder 中各个方法的对应
equle : filed=value
gt / greaterThan : filed > value
lt / lessThan : filed=value
le / lessThanOrEqualTo: filed <=value
notEqule : filed !=value
like : filed like value
notLike : filed not like value

五.(扩充findAll(Specification对象查询),适用于动态sql查询)

可以定义多个 Specification,然后通过 Specifications 对象将其连接起来

这个代码生成的 SQL 是

? toPredicate 中还有 CriteriaQuery 参数,这个对象提供了更多有用的查询,如分组之类的查询

也可以使用lambda表达式


以上的简单查询 和 Example对象查询没有举出例子。大多数来说:jpa自带的查询方法可以满足简单查询的需求,稍微复杂一点可以用带注解的HQL方法,涉及到动态条件查询的,Specification对象查询比较常用,因为支持Pageable分页,实际上它是基于Criteria查询的。有兴趣的同学,可以自己去研究研究这些东西


其实网上很多人说JPA反人类,也有人说Mybatis不好用。在我看来,JPA在一般的场景下,处理起来很快,但涉及到复杂的sql查询,例如报表业务,确实会让人崩溃,但无论多复杂,总有解决方案,但是限制他的还是性能和无法做sql优化。因此,很多需要掌控底层实现的公司选择使用Mybatis,但我们不能因此不去学习和使用JPA/Hibernate,毕竟,当初。自动化是人类社会不断的追求,Mybatis也不可能一成不变,具体可以参考Mybatis的通用Mapper。英语培训费用只能说我们面对工具,不是抛开谁不用,而是根据业务场景,综合择优;实在不行,自己造轮子,反而更能符合自身的需求。
对于占了国内半壁江山的Hibernate/Mybatis来说,有一些小众但是也有越来越多人使用的框架:JOOQ,QueryDsl,有兴趣也可以学习一下。
希望这篇文章能对你有帮助!
















































java示例代码_使用JPA Hibernate与同一实体建立关系

java示例代码_使用JPA Hibernate与同一实体建立关系 查看详情

springdatajpa:分页和排序

...序 由Cliff发表在天码营之前我们学习了如何使用Jpa访问关系型数据库。通过Jpa大大简化了我们对数据库的开发工作。但是,之前的例子中我们只提到了最简单的CRUD(增删改查)操作。实际上,SpringDataJpa对于分页... 查看详情

jpa

...用于对象持久化的API。  JPA与ORM框架(对象关系模型如Hibernate)的关系就如同JDBC与mysql数据库驱动一样,前者是java官方提供的标准(只提供接口),后者是具体厂商的实现类。  学Hibernate时主要使用的是配置的方式;而学JP... 查看详情

jpa与hibernate的关系

1.JPA  JPA全称:JavaPersistenceAPI  JPA通过JDK5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。  JPA的出现?  JPA的出现有两个原因:  其一,简化现有JavaEE和Java... 查看详情

在 JPA/Hibernate 中正确使用 flush()

】在JPA/Hibernate中正确使用flush()【英文标题】:Correctuseofflush()inJPA/Hibernate【发布时间】:2011-05-1513:51:14【问题描述】:我正在收集有关flush()方法的信息,但我不太清楚何时使用它以及如何正确使用它。根据我的阅读,我的理解... 查看详情

EAGER 和分页:Spring MVC + JPA Repository + Hibernate

】EAGER和分页:SpringMVC+JPARepository+Hibernate【英文标题】:EAGERandPagination:SpringMVC+JPARepository+Hibernate【发布时间】:2017-08-2218:37:45【问题描述】:我有一个实体A,它与一个实体B(fetchmode=EAGER)有关系@OneToMany。实体A在LAZY中也与其他实... 查看详情

jpa和hibernate的关系

...istenceAPI,是JavaEE5的标准ORM接口,也是ejb3规范的一部分。Hibernate,当今很流行的ORM框架,是JPA的一个实现,但是其功能是JPA的超集。JPA和Hibernate之间的关系,可以简单的理解为JPA是标准接口,Hibernate是实现。那么Hibernate是如何实... 查看详情

hibernate/jpa double OneToOne 与一个实体的双向关系

】hibernate/jpadoubleOneToOne与一个实体的双向关系【英文标题】:hibernate/jpadoubleOneToOneBidirectionalRelationshiptooneentity【发布时间】:2019-04-2307:15:35【问题描述】:我有以下结构,我不知道如何放入正确的休眠映射。publicclassCompany@OneToOne... 查看详情

hibernate注解与jpa注解

...09; JPA注解是JAVAEE的规范和标准,JPA是标准接口,Hibernate是实现,但是其功能是JPA的超集。一般在实际开发中,优先考虑使用JPA注解,这样更有利于程序的移植和扩展。 Hibernate如何实现与JPA的关系 通过hi 查看详情

JPA+Hibernate - 实体关系中的循环 - 级联策略

】JPA+Hibernate-实体关系中的循环-级联策略【英文标题】:JPA+Hibernate-Cyclesinentityrelationships-Cascadestrategy【发布时间】:2012-11-2908:59:02【问题描述】:我有一组相互连接的实体形成一个循环,即父实体P与两个子实体C1和C2具有两个一... 查看详情

使用 JPA 和 Hibernate 提供程序的多对多关系不会创建主键

】使用JPA和Hibernate提供程序的多对多关系不会创建主键【英文标题】:ManyToManyrelationshipusingJPAwithHibernateproviderisnotcreatingprimarykeys【发布时间】:2011-03-2906:54:56【问题描述】:我使用Hibernate作为提供者创建了两个具有多对多关系的... 查看详情

hibernate注解开发(未完待续)

...注解的目的  简化繁琐的ORM映射文件(*.hbm)的配置2.JPA和hibernate的关系  JPA:javapersistenceAPI,JPA注解是JavaEE的标准和规范。  两者的关系可以简单理解为JPA是接口,Hibernate是实现,但是其功能是JPA的超集。Hibernate如何实现与JPA... 查看详情

如何从 @ManyToMany 关系中删除与 JPA 和 Hibernate 中的许多子对象的子对象

】如何从@ManyToMany关系中删除与JPA和Hibernate中的许多子对象的子对象【英文标题】:Howtoremovechildobjectsfroma@ManyToManyrelationwithlotsofchildreninJPAandHibernate【发布时间】:2017-10-1917:32:49【问题描述】:假设我有两个实体:组织和用户。每... 查看详情

使用jpa和hibernate提供程序的manytomany关系不会创建主键

我使用Hibernate作为具有ManyToMany关系的提供程序创建了两个JPA实体(Client,InstrumentTraded)。让Hibernate为MySQL生成表后,看起来ManyToMany关系表不包含两个外键的主键。这允许多对多表中的重复记录,这不是期望的结果。生成的表:c... 查看详情

带有分页和排序的 Spring Boot JPA 规范 API

】带有分页和排序的SpringBootJPA规范API【英文标题】:SpringbootJPASpecificationAPIwithPaginationandSorting【发布时间】:2021-01-2818:11:16【问题描述】:我正在尝试在SpringBoot中实现搜索。由于搜索参数是动态的,我不得不去规范api。我的要... 查看详情

JPA + Hibernate + Spring + OneToMany 删除级联

】JPA+Hibernate+Spring+OneToMany删除级联【英文标题】:JPA+Hibernate+Spring+OneToManydeletecascade【发布时间】:2014-11-1601:21:16【问题描述】:我已经阅读了一些相关的问题,但它们与我的问题并不完全相同。我正在使用JPA+Hibernate+Spring,我想... 查看详情

@Transactional 与 JPA 和 Hibernate 有啥用?

】@Transactional与JPA和Hibernate有啥用?【英文标题】:Whatistheuseof@TransactionalwithJPAandHibernate?@Transactional与JPA和Hibernate有什么用?【发布时间】:2019-06-1623:42:48【问题描述】:我正在学习如何使用JPA和Hibernate以及MySQL数据库创建RESTAPI... 查看详情

分页和排序问题

...特殊情况是分页。当尝试对大表(例如10000行)进行分页以及按特定列对其进行排序时,最好的方法是什么?我了解与此相关的一些问题是:我无法一次性将整个表返回客户端我无法使用ja 查看详情