一、Spring数据访问原则
1、将数据访问的功能放到一个或多个专注于此项任务的组件中。这样的组件通常称为数据访问对象(data access object,DAO)或Repository。
2、编写良好的Repository应该以接口的方式暴露数据访问层所提供的功能(好处1:便于测试,好处2:数据访问的具体实现通过接口进行了隔离);
3、为了将数据访问层与应用程序的其他部分隔离开来,
二、Spring数据访问异常体系
1、目的
将数据访问层与应用程序的其他部分隔离开来,Spring采用的方式之一就是提供统一的数据访问异常体系
2、spring异常体系优势
Spring数据访问的异常体系用来解决:
- JDBC的异常体系过于简单——实际上,JDBC的异常体系算不上一个体系。
- Hibernate的异常体系是其本身所独有的。我们需要的数据访问异常要具有描述性而且又与特定的持久化框架无关。
3、特点
- 没有与特定的持久化方式相关联
- 异常种类很多、很细粒度
- 异常都继承自DataAccessException。这是非检查型异常:可以根据需要选择是否捕获。之所以spring这么设计是因为:Spring认为触发异常的很多问题是不能(无法)在catch代码块中修复的,比如数据库连接失败等等,是应用程序无法解决的。而不是强制开发人员编写catch代码块(里面经常是空的)。这把是否要捕获异常的权力留给了开发人员。
4、使用
三、数据访问模板化
1、思想
- Spring的模板类负责:事务控制、 管理资源、处理异常(处理数据访问的固定部分)。
- 回调负责:应用程序相关的数据访问的语句、 绑定参数、整理结果集
3、使用(实现)
下表是Spring提供的数据访问模板,分别适用于不同的持久化机制:
jca.cci.core.CciTemplate
|
JCA CCI
连接
|
jdbc.core.JdbcTemplate
|
JDBC
连接
|
jdbc.core.namedparam.NamedParameterJdbcTemplate
|
支持命名参数的
JDBC
连接
|
jdbc.core.simple.SimpleJdbcTemplate
|
通过
Java 5
简化后的
JDBC
连接(Spring 3.1
中已经废弃)
|
orm.hibernate3.HibernateTemplate
|
Hibernate 3.x
以上的
Session
|
orm.ibatis.SqlMapClientTemplate
| iBATIS SqlMap客户端 |
orm.jdo.JdoTemplate
|
Java
数据对象(
Java Data Object)实现
|
orm.jpa.JpaTemplate
|
Java
持久化
API
的实体管理器
|
以下三个是比较常用的:
- JDBC:JdbcTemplate
- Hibernate:HibernateTemplate(最流行的基于POJO的ORM方案)
- JPA:JpaTemplate(最流行的基于POJO的ORM方案)
4、准备
3.1 配置数据源
- 通过JDBC驱动程序定义的数据源:无连接池、适合小应用
- 通过JNDI查找的数据源;(最好)
- 数据库连接池的数据源。(其次)
-
Apache Commons DBCP
-
c3p0
-
BoneCP
-
-
【嵌入式】的数据源:测试、开发
3.1.1 使用【JNDI】数据源
1、前提
使用web服务器时(如tomcat),web服务器允许你配置通过JNDI获取数据源。
2、好处
- 数据源完全可以在应用程序之外进行管理,这样应用程序只需在访问数据库的时候查找数据源就可以了。
- 在应用服务器中管理的数据源通常以池的方式组织,从而具备更好的性能
- 支持系统管理员对其进行热切换
3、使用方式
其中JndiObjectFactoryBean是spring内置提供的
3.1.2 使用【数据库连接池】数据源
1、说明
- 这些都是第三方数据库连接池作为数据源
- 如果无法使用JNDL配置数据源,其次选择在spring中配置数据库连接池数据源,spring没有提供实现,但是可以通过集成下面连接池进行实现:
-
Apache Commons DBCP
-
c3p0
-
BoneCP
-
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-dbcp</artifactId>
<version>7.0.47</version>
</dependency>
1)
XML形式
前四个属性是必需的:
- driverClassName指定了JDBC驱动类的全限定类名。这里配置的是H2数据库的数据源。
- url用于设置数据库的JDBCURL。最
- username和password用于在连接数据库时进行认证
其他属性如下表:
initialSize
|
池启动时创建的连接数量
|
maxActive
|
同一时间可从池中分配的最多连接数。如果设置为0,表示无限制
|
maxIdle
|
池里不会被释放的最多空闲连接数。如果设置为
0
,表示无限制
|
maxOpenPreparedStatements
|
在同一时间能够从语句池中分配的预处理语句(prepared statement
)的最大数量。如果设置为
0
,表示无限制
|
maxWait
|
在抛出异常之前,池等待连接回收的最大时间(当没有可用连接时)。如果设置为-1
,表示无限等待
|
minEvictableIdleTimeMillis
|
连接在池中保持空闲而不被回收的最大时间
|
minIdle
|
在不创建新连接的情况下,池中保持空闲的最小连接数
|
poolPreparedStatements
|
是否对预处理语句(
prepared statement
)进行池管理(布尔值)
|
2.2 配置C3P0数据源
依赖包:
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
XML形式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.5.xxx:3306/ml_test"/>
<property name="user" value="root"/>
<property name="password" value="xxxx"/>
</bean>
</beans>
其中value部分可以引用外部配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:property-placeholder location="db/db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
其中通过<context:property-placeholder location="db/db.properties"/>引入外部配置文件后,通过${xxx}的方式使用
3.1.3 使用【基于JDBC驱动】的数据源
1、说明:使用简单,无连接池,适用场景有限(小应用,开发环境)
2、种类:
- org.springframework.jdbc.datasource.DriverManagerDataSource:每次返回新连接,无池化管理
- org.springframework.jdbc.datasource.SimpleDriverDataSource:直接使用JDBC驱动,来解决在特定环境下的类加载问题,这样的环境包括OSGi容器
- org.springframework.jdbc.datasource.SingleConnectionDataSource:在每个连接请求时都会返回同一个的连接
3、使用
3.1.4 使用【嵌入式】的数据源
1、作用(适用场景)
开发 和 测试时,好处:每次重启应用或运行测试的时候,都能够重新填充测试数据
2、使用:
- h2数据库位于类路径下
- type配置为H2为使用H2数据库,配置成DERBY为使用derby数据库
-
可以不配置也可以配置多个<jdbc:script>元素来搭建数据库,上面的配置包含了两个<jdbc:script>元素:第一个引用了schema.sql,它包含了在数据库中创建表的SQL;第二个引用了test-data.sql,用来将测试数据填充到数据库中。
-
<jdbc:embedded-database>元素 还会暴露一个数据源,我们可以像使用其他的数据源那样来使用它。 在这里, id 属性被设置成了 dataSource ,这也是所暴露数据源的 bean ID 。因此,当我们需要 javax.sql.DataSource 的时候,就可 以注入 dataSource bean 。
3.2 选择数据源
1、使用场景:
package com.mzj.springframework.dao._01_dataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;
import javax.sql.DataSource;
/**
* @Auther: mazhongjia
* @Date: 2020/4/20 13:07
* @Version: 1.0
*/
@Configuration
public class DataSourceConfiguration {
/**
* 开发数据源
*
* @return
*/
@Profile("development")
@Bean
public DataSource embeddedDataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("classpath:schema.sql")
.addScript("classpath:test-data.sql")
.build();
}
/**
* 生成环境的数据源
*
* @return
*/
public DataSource dataSource() {
JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
jndiObjectFactoryBean.setResourceRef(true);
jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
return (DataSource) jndiObjectFactoryBean.getObject();
}
}
2)XML方式
- 当且仅当developmentprofile处于激活状态时,会创建嵌入式数据库;
- 当且仅当qa profile处于激活状态时,会创建DBCPBasicDataSource;
- 当且仅当productionprofile处于激活状态时,会从JNDI获取数据源
3.3 使用Spring的JDBC框架访问数据库
方式1:使用JDBC访问数据库
- 优点
- 低层次,完全控制如何读取和管理数据
-
使用 JDBC 能够更好地对数据访问的性能进行调优
-
JDBC允许使用数据库所有特性
-
缺点
-
业务无关模式化代码、冗长,如资源申请、资源释放、异常处理
-
不知道SQLException 异常的具体原因,不知道如何处理
-
方式2:使用持久层框架访问数据库
- 引入:清理资源和异常处理,非常重要,要保证正确性、健壮性。
- Spring的JDBC框架作用:承担了资源管理和异常处理的工作,从而简化了JDBC代码,让我们只需编写从数据库读写数据的必需代码。
Spring的JDBC框架使用
1、spring的JDBC模板
1)三种可选的模板
JdbcTemplate
|
最基本的
Spring JDBC
模板,这个模板支持简单的JDBC
数据库访问功能以及基于索引参数的查询
| 绝大多数时候使用 |
NamedParameterJdbcTemplate
|
使用该模板类执行查询时可以将值以命名参数的形式绑定到SQL
中,而不是使用简单的索引参数;
|
只有在你需要使用命名参数的时候,才需要使用
|
SimpleJdbcTemplate
|
该模板类利用
Java 5
的一些特性如自
动装箱、泛型以及可变参数列表来简化
JDBC
模板的使用
|
Spring 3.1开始被废弃
|
2、JdbcTemplate使用
步骤1:定义DataSource
略,见前文。
步骤2:声明JdbcTemplate的bean,并向其注入DataSource
JavaConfig方式:
XML方式:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:property-placeholder location="db/db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
步骤3:将jdbcTemplate装配到Repository(业务DAO)中并使用它来访问数据库
/**
* Repository1 bean(DAO),依赖JdbcTemplate
* @param jdbcTemplate
* @return
*/
@Bean
public SpitterRepository spitterRepository(JdbcTemplate jdbcTemplate) {
return new JdbcSpitterRepository(jdbcTemplate);
}
步骤4:SpitterRepository是接口,需要实现之,即JdbcSpitterRepository
比如insert:
public Spittle save(Spittle spittle) {
long spittleId = insertSpittleAndReturnId(spittle);
return new Spittle(spittleId, spittle.getSpitter(), spittle.getMessage(), spittle.getPostedTime());
}
private long insertSpittleAndReturnId(Spittle spittle) {
SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate).withTableName("Spittle");
jdbcInsert.setGeneratedKeyName("id");
Map<String, Object> args = new HashMap<String, Object>();
args.put("spitter", spittle.getSpitter().getId());
args.put("message", spittle.getMessage());
args.put("postedTime", spittle.getPostedTime());
long spittleId = jdbcInsert.executeAndReturnKey(args).longValue();
return spittleId;
}
- 已经没有创建、释放、连接的样板代码:样板代码被巧妙地隐藏到JDBC模板类中了
- 已经没有SQLException处理的代码:在内部,JdbcTemplate将会捕获所有可能抛出的SQLException,并将通用的SQLException转换为表10.1所列的那些更明确的数据访问异常,然后将其重新抛出。因为Spring的数据访问异常都是运行时异常,所以我们不必在save()方法中进行捕获
3.4 使用Spring集成ORM框架访问数据库
1、ORM框架:
-
Hibernate
-
My Batis
-
JDO,(Java Data Objects ),Java数据对象
-
JPA、( Java Persistence API )、Java持久化API
- 延迟加载:复杂的对象关系,用到时才真正加载
- 预先抓取:使用一次查询获取完整的关联对象
- 级联:更改数据库中的表会同时修改其他表
3、ORM框架可以提供
-
支持集成 Spring 声明式事务;
-
透明的异常处理;
-
线程安全的、轻量级的模板类;
-
DAO支持类;
-
资源管理
3.4.1 使用Spring集成Hibernate框架访问数据库
1、支持特性
- 缓存
- 延迟加载
- 预先抓取
- 分布式缓存
2、使用说明
- Session接口提供了基本的数据访问功能,如保存、更新、删除以及从数据库加载对象的功能
- SessionFactory主要负责创建Session接口的实现以及Session的打开、关闭以及管理
Spring中使用时,需要通过spring提供的Hibernate的Session工厂bean实现:
(依赖关系:Spring的SessionFactoryBean依赖DataSource,业务Repository依赖 SessionFactory)
通过Spring的某一个SessionFactoryBean来获取Hibernate的SessionFactory,Spring提供的Hibernate Session工厂bean有三类:
- org.springframework.orm.hibernate3.LocalSessionFactoryBean:Hibernate使用的是3.2-4之间版本(不包括4)+ 使用XML定义映射
- AnnotationSessionFactoryBean:Hibernate使用的4以下的版本(不包括4)+ 使用注解方式定义持久
- org.springframework.orm.hibernate4.LocalSessionFactoryBean:Hibernate使用4及以上版本 + 支持基于XML的映射和基于注解(通过JPA的@Entity或@MappedSuperclass以及Hibernate的@Entity)的映射
这里只列出与hibernate4集成代码示例:
1)增加依赖:
<springframe.version>4.3.3.RELEASE</springframe.version>
<!--基础依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframe.version}</version>
</dependency>
<!--集成hibernate依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframe.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.1.6.Final</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!--测试数据库依赖-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.182</version>
</dependency>
2)在Spring应用上下文中配置【数据源】以及【spring提供的Hibernate的Session工厂bean】
3)创建自己的(业务)Repository类了
方式一:Spring和Hibernate的早期版本,使用HibernateTemplate
缺点:Repository实现会直接与Spring耦合
方式二:使用上下文Session(Contextual session)
原理:会直接将Hibernate的SessionFactory装配到业务Repository中,并使用它来获取Session,在Repository中不会看到spring的影子
优点:Repository类及实现不与spring偶合(除了@Repository注解以外.....)
代码见:com.mzj.springframework.dao._03_hibernate._4子包中代码。
3.4.2 使用Spring集成JPA访问数据库
1、说明
JPA:Java持久化API
JPA是下一代Java持久化标准,JPA基于POJO的持久化机制,JPA借鉴了Hibernate+Java数据对象(JDO)+Java5的注解
2、Spring集成JPA传统方式(开发麻烦(业务Repository中使用EntityManager操作数据库),过时的,了解即可,后面的Spring Data JPA实现原理没变,只不过Spring给我们简化了这个过程)
原理:使用EntityManagerFactory(实体管理器工厂)的实现类来获取EntityManager(实体管理器)实例
EntityManager的创建与管理有两种方式(关键的区别不在于EntityManager本身,而是在于EntityManager的创建和管理方式):
- 应用程序管理类型:适用于非JAVAEE程序(程序直接向实体管理器工厂请求实体管理器,EntityManagerFactory创建EntityManager,程序负责打开或关闭实体管理器、在事务中对其进行控制)
- 容器管理类型:适用于JAVAEE程序(实体管理器由Java EE创建和管理、实体管理器直接通过注入或JNDI来获取,应用程序根本不与实体管理器工厂打交道)
Spring都会负责管理EntityManager。如果你使用的是应用程序管理类型的实体管理器,Spring承担了应用程序的角色并以透明的方式处理EntityManager。在容器管理的场景下,Spring会担当容器的角色。
这两种实体管理器工厂分别由对应的Spring工厂Bean创建:
- LocalEntityManagerFactoryBean生成应用程序管理类型的EntityManager-Factory
- LocalContainerEntityManagerFactoryBean生成容器管理类型的EntityManagerFactory。
使用方式:
1)spring上下文中配置实体管理器工厂LocalEntityManagerFactoryBean
略。
2)编写基于JPA的业务Repository
略。
3、Spring Data JPA(自动化的Spring集成JPA实现方式)
优点:只编写Repository接口就可以了。根本就不再需要实现类了。
使用
1)增加依赖
<springframe.version>4.3.3.RELEASE</springframe.version>
<!--基础依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframe.version}</version>
</dependency>
<!--集成springdata-jpa依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${springframe.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.0.1.Final</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!--测试数据库依赖-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.182</version>
</dependency>
package com.mzj.springframework.dao._04_springdata_jpa.db;
import java.util.List;
import com.mzj.springframework.dao._04_springdata_jpa.vo.Spitter;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* Repository interface with operations for {@link Spitter} persistence.
* @author habuma
*/
public interface SpitterRepository extends JpaRepository<Spitter, Long> {
Spitter findByUsername(String username);
List<Spitter> findByUsernameOrFullNameLike(String username, String fullName);
}
-
通过给出泛型类型<Spitter,Long>,JpaRepository 进行了参数化,使他能知道这是一个用来持久化Spitter 对象的 Repository ,并且 Spitter 的 ID 类型为Long 。
-
另外,它还会 自动继承18个执行持久化操作的通用方法 ,如保存Spitter 、删除 Spitter 以及根据 ID 查询 Spitter 。
方式一:JavaConfig的方式:
@Configuration
@EnableJpaRepositories("com.mzj.springframework.dao._04_springdata_jpa")
会根据这个包路径进行扫描,扫描它的基础包及其子包来查找扩展自Spring Data JPA Repository接口的所有接口。如果发现了扩展自Repository的接口,它会自动生成(在应用启动的时候)这个接口的实现(在Spring的应用上下文创建的时候生成的)。
4)如果自带的18个方法不够,可以添加自定义方法
方式一:在业务Repository接口中按照下面的DSL【语法规则】增加自定义查询
原理:当创建Repository实现的时候,Spring Data会检查Repository接口的所有方法,解析方法的名称,并基于被持久化的对象来试图推测方法的目的。本质上,Spring Data定义了一组小型的领域特定语言(domain-specific language ,DSL),在这里,持久化的细节都是通过Repository方法的签名来描述的。
语法规则:
在
findByUsername()
这个样例中,动词是
find
,断言是Username
,主题并没有指定,暗含的主题是
Spitter
完整的示例为: 一句话总结:使用属性名和关键字构建Repository方法签名,就能让Spring Data JPA生成方法实现,完成几乎所有能够想象到的查询。Spring Data这个小型的DSL依旧有其局限性,有时候通过方法名称表达预期的查询很烦琐,甚至无法实现。如果遇到这种情形的话,Spring Data能够让我们通过@Query注解来解决问题。 |
方式二:通过@Query注解添加(声明)自定义查询
使用场景1:
如果所需的数据无法通过方法名称进行恰当地描述,那么我们可以使用@Query注解,为Spring Data提供要执行的查询。
局限性:
- 按照spring data jpa约定我们自己创建接口的实现类
- 约定:Repository接口的实现类名叫【Repository接口Impl】,但是此类不需要implements Repository接口
- 为了让使用Repository接口的代码能通过Repository接口看到这个自定义方法,需要再单独定义一个接口,将准备实现的方法放入接口中,然后让【Repository接口Impl】实现这个接口,并让【Repository接口】也extends这个接口
- 在【Repository接口Impl】中注入EntityManager(通过@PersistenceContext注解注入)
- 【Repository接口Impl】实现这个接口的方法实现中,通过EntityManager实现复杂查询
其他说明:Impl后缀只是默认的做法,如果你想使用其他后缀的话,只需在配置@EnableJpa-Repositories的时候,设置repositoryImplementationPostfix属性即可
5)使用JPA注解或者hibernate JPA注解对实体类属性进行声明以进行ORM映射
或者《Spring Data Jpa 从入门到精通》
市场上 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 做了很好的支持。