1. ORM 框架

纵观 ORM 框架,MyBatis 以灵活著称,但是要维护复杂的配置,并且不是 Spring 官方的天然全家桶,还得做额外的配置工作,如果资深的架构师还得做很多封装;Hibernate 以 HQL 和关系映射著称,但是就是使用起来不是特别灵活;那么 Spring Data JPA 来了,感觉要夺取 ORM 的 JPA 霸主地位了,底层以 Hibernate 为封装,对外提供了超级灵活的使用接口,又非常符合面向对象和 Rest 的风格,感觉是架构师和开发者的福音,并且 Spring Data JPA 与 Spring Boot 配合起来使用具有天然的优势;

1.1 市场上 ORM 框架比对

  • MyBatis:MyBatis 本是 Apache 的一个开源项目 iBatis,2010 年这个项目由 Apache Software Foundation 迁移到了 Google Code,并且改名为 MyBatis,其着力于 POJO 与 SQL 之间的映射关系,可以进行更为细致的 SQL,使用起来十分灵活、上手简单、容易掌握,所以深受开发者的喜欢,目前市场占有率最高,比较适合互联应用公司的 API 场景;缺点就是工作量比较大,需要各种配置文件的配置和 SQL 语句。
  • Hibernate:Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库,并且对象有自己的生命周期,着力点对象与对象之间关系,有自己的 HQL 查询语言,所以数据库移植性很好。Hibernate 是完备的 ORM 框架,是符合 JPA 规范的,有自己的缓存机制,上手来说比较难,比较适合企业级的应用系统开发。
  • Spring Data JPA:可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现,引用 JPQL(Java Persistence Query Language)查询语言,属于 Spring 的整个生态体系的一部分。由于 Spring Boot 和 Spring Cloud 在市场上的流行,Spring Data JPA 也逐渐进入大家的视野,他们有机的整体,使用起来比较方便,加快了开发的效率,使开发者不需要关系和配置更多的东西,完全可以沉浸在 Spring 的完整生态标准的实现下,上手简单、开发效率高,又对对象的支持比较好,又有很大的灵活性,市场的认可度越来越高。
  • OpenJPA :是 Apache 组织提供的开源项目,它实现了 EJB 3.0 中的 JPA 标准,为开发者提供功能强大、使用简单的持久化数据管理框架,但功能、性能、普及性等方面更加需要加大力度,所以用的人不人不是特别多。
  • QueryDSL:QueryDSL 可以在任何支持的 ORM 框架或者 SQL 平台上以一种通用的 API 方式来构建查询,目前 QueryDSL 支持的平台包括 JPA、JDO、SQL、Java Collections、RDF、Lucene、Hibernate Search,同时 Spring Data JPA 也对 QueryDSL 做了很好的支持。

    1.2 JPA 的介绍以及哪些开源实现

    JPA(Java Persistence API)中文名 Java 持久层 API,是 JDK 5.0 注解或 XML 描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
    Sun 引入新的 JPA ORM 规范出于两个原因:其一,简化现有 Java EE 和 Java SE 应用开发工作;其二,Sun 希望整合 ORM 技术,实现天下归一。

1.2.1 JPA 包括以下三方面的内容
  • 一套 API 标准,在 javax.persistence 的包下面,用来操作实体对象,执行 CRUD 操作,框架在后台替代我们完成所有的事情,开发者从繁琐的 JDBC 和 SQL 代码中解脱出来。
  • 面向对象的查询语言:Java Persistence Query Language(JPQL),这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的 SQL 语句紧密耦合。
  • ORM(Object/Relational Metadata)元数据的映射,JPA 支持 XML 和 JDK 5.0 注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。

    1.2.2 JPA 的开源实现
    JPA 的宗旨是为 POJO 提供持久化标准规范,由此可见,经过这几年的实践探索,能够脱离容器独立运行,方便开发和测试的理念已经深入人心了。Hibernate 3.2+、TopLink 10.1.3 以及 OpenJPA、QueryDSL 都提供了 JPA 的实现,以及最后的 Spring 的整合 Spring Data JPA。目前互联网公司和传统公司大量使用了 JPA 的开发标准规范。
    JPA - 图1

    2. Spring Data

    2.1 Spring Data 介绍

    Spring Data 项目是从 2010 年开发发展起来的,从创立之初 Spring Data 就想提供一个大家熟悉的、一致的、基于 Spring 的数据访问编程模型,同时仍然保留底层数据存储的特殊特性。它可以轻松地让开发者使用数据访问技术包括:关系数据库、非关系数据库(NoSQL)和基于云的数据服务。
    Spring Data Common 是 Spring Data 所有模块的公用部分,该项目提供跨 Spring 数据项目的共享基础设施,它包含了技术中立的库接口以及一个坚持 Java 类的元数据模型。
    Spring Data 不仅对传统的数据库访问技术:JDBC、Hibernate、JDO、TopLick、JPA、MyBatis 做了很好的支持和扩展、抽象、提供方便的 API,还对 NoSQL 等非关系数据做了很好的支持:MongoDB 、Redis、Apache Solr 等。

    2.2 Spring Data子项目

主要项目(Main Modules):

  • Spring Data Commons
  • Spring Data Gemfire
  • Spring Data JPA
  • Spring Data KeyValue
  • Spring Data LDAP
  • Spring Data MongoDB
  • Spring Data REST
  • Spring Data Redis
  • Spring Data for Apache Cassandra
  • Spring Data for Apache Solr

社区支持的项目(Community Modules):

  • Spring Data Aerospike
  • Spring Data Couchbase
  • Spring Data DynamoDB
  • Spring Data Elasticsearch
  • Spring Data Hazelcast
  • Spring Data Jest
  • Spring Data Neo4j
  • Spring Data Vault

其他(Related Modules):

  • Spring Data JDBC Extensions
  • Spring for Apache Hadoop
  • Spring Content

当然了还有许多开源社区做出的许多贡献如 MyBatis 等。
市面上主要的如图所示:
JPA - 图2

2.3 Spring Data 操作的主要特性

Spring Data 项目旨在为大家提供一种通用的编码模式,数据访问对象实现了对物理数据层的抽象,为编写查询方法提供了方便。通过对象映射,实现域对象和持续化存储之间的转换,而模板提供的是对底层存储实体的访问实现,操作上主要有如下特征:

  • 提供模板操作,如 Spring Data Redis 和 Spring Data Riak;
  • 强大的 Repository 和定制的数据储存对象的抽象映射;
  • 对数据访问对象的支持(Auting 等)。

JPA - 图3

2.4 Spring Data JPA主要类及结构图

我们需要掌握和使用到的类:

七个大 Repository 接口:

  • Repository(org.springframework.data.repository);
  • CrudRepository(org.springframework.data.repository);
  • PagingAndSortingRepository(org.springframework.data.repository);
  • JpaRepository(org.springframework.data.jpa.repository);
  • QueryByExampleExecutor(org.springframework.data.repository.query);
  • JpaSpecificationExecutor(org.springframework.data.jpa.repository);
  • QueryDslPredicateExecutor(org.springframework.data.querydsl)。

两大 Repository 实现类:

  • SimpleJpaRepository(org.springframework.data.jpa.repository.support);
  • QueryDslJpaRepository(org.springframework.data.jpa.repository.support)。

    类的结构关系图如图所示

    JPA - 图4
    基本上面都是我们要关心的类和接口,先做到大体心中有个数。

    需要了解到的类,真正的 JPA 的底层封装类
  • EntityManager(javax.persistence);

  • EntityManagerImpl(org.hibernate.jpa.internal)。


3.Repository


Repository是Spring Data里面做数据库操作的最底层的抽象接口,最顶级的父类,源码里面其实什么方法都没有,仅仅起到一个标识作用。管理域类以及域类的ID类型作为类型参数,此接口主要作为标记接口来捕获要使用的类型,并帮助用户发现扩展此接口的接口。Spring底层做动态代理的时候发现只要是它的子类或者实现类,都代表储存库操作。

image.png

Repository可以分为三个部分:

  • 即本篇要介绍的正常的 JpaRepository 这条线的操作。
  • ReactiveRepository 这条线响应式编程,主要支持目前的 NoSQL 方面的操作,因为 NoSQL 大部分的操作都是分布式的,所以足可以看的出来 Spring Data 的野心,想提供关于所有 Data 方面的操,目前主要有 Cassandra、MongoDB 的实现,与 JPA 属于平级项目。
  • RxJava2CrudRepository 这条线是为了支持 RxJava 2 做的标准的响应式编程的接口。

    各实现

  1. CrudRepository
  2. PagingAndSortingRepository
  3. JpaRepository
  4. SimpleJpaRepository

image.png

3.1 CrudRepository

CrudRepository 提供了公共的通用的 CRUD 方法;
image.png

3.2 PagingAndSortingRepository

PagingAndSortingRepository继承 CrudRepository 所有他的基本方法,它都有增加了分页和排序等对查询结果进行限制的一些基本的、常用的、通用的一些分页方法;

  • 根据排序取所有的对象的集合。
  • 根据分页和排序进行查询,并用 Page 对象封装。Pageable 对象包含分页和 Sort 对象。

PagingAndSortingRepository 和 CrudRepository 都是 Spring Data Common 的标准接口,如果我们采用 JPA 那它对应的实现类就是 Spring Data JPA 的 Model 里面的 SimpleJpaRepository。如果是其他 NoSQL 实现 MongoDB,那它的实现就在 Spring Data MongoDB 的 Model 里面。

3.3 JpaRepository


JpaRepository 到这里可以进入到分水岭了,上面的那些都是 Spring Data 为了兼容 NoSQL 而进行的一些抽象封装,而从 JpaRepository 开始是对关系型数据库进行抽象封装,从类图可以看得出来它继承 PagingAndSortingRepository 类,也就继承了其所有方法,并且其实现类也是 SimpleJpaRepository。从类图上还可以看出 JpaRepository 继承和拥有了QueryByExampleExecutor 的相关方法;

通过和CrudRepository相比较其支持了Query By Example、批量删除、提高删除效率、手动刷新数据库的更改方法,将默认实现的查询结果变成了 List。

3.4 SimpleJpaRepository

SimpleJpaRepository 是 JPA 整个关联数据库的所有 Repository 的接口实现类,如果想进行扩展,可以继承此类,如 QueryDsl 的扩展,还有默认的处理机制。如果将此类里面的实现方法看透了,基本上 JPA 的 API 就能掌握大部分,同时也是 Spring JPA 的动态代理的实现类,包括我们后面讲的 Query Method;

SimpleJpaRepository 的实现机制很清晰,即通过 EntityManger 进行实体的操作,JpaEntityInforMation 里面存着实体的相关信息,还有 crud 方法的元数据等等;

https://gitchat.csdn.net/columnTopic/5ab9c2e0c864031e9f8302dc https://blog.csdn.net/qq_38796327/article/details/90599867