一、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
-
MyBatis
-
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 做了很好的支持。