中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ORM 規范

發布時間:2020-04-06 13:55:38 來源:網絡 閱讀:482 作者:灰白世界 欄目:編程語言

JPA 概述

JPA 介紹

JPA 本質上就是一種 ORM 規范,不是 ORM 框架,因為 JPA 并未提供 ORM 實現,它只是制定了一套規范,提供了一些接口,具體實現由 ORM 廠商決定。

JPA 包括三方面的技術

ORM 映射元數據

JPA API

查詢語言(JPQL)

使用 JPA 持久化對象的步驟

創建 EntityMangerFactory

通過 EntityManagerFactory 獲得 EntityManager 實例

開始事務

執行持久化操作

提交事務

關閉 EntityManager

關閉 EntityManagerFactory

// 創建 EntityManageFactory
String persistenceUnitName = "NewPersistenceUnit";
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName);
// 創建 EntityManage
EntityManager entityManager = entityManagerFactory.createEntityManager();
// 開始事務
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 執行持久化操作
Customer customer = new Customer();
customer.setAge(12);
customer.setEmail("tom@163.com");
customer.setLastName("tom");
entityManager.persist(customer);
// 提交事務
transaction.commit();
// 關閉 EntityManage
entityManager.close();
// 關閉 EntityManageFactory
entityManagerFactory.close();

persistence.xml

JPA 規范要求在類路徑的 META-INF 目錄下放置persistence.xml,文件的名稱是固定的。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="NewPersistenceUnit">
        <!--配置將使用哪個產品作為實現-->
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!--添加持久化類-->
        <class>com.kernel.jpa.helloworld.Customer</class>
        <properties>
            <!--連接數據庫的基本信息-->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="123456"/>
            <!--配置hibernate的基本屬性-->
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

JPA 的基本注解

@Entity

標記一個類為實體類,添加該注解后,會在數據庫中創建一個和類名相同的表。

@Transient

使用該注解忽略工具方法,不需要映射為數據表的一列。

@Temporal

設置 Date 類型的精度。

DATE:精確到年月日

TIME:精確到時分秒

TIMESTAMP:精確到年月日時分秒

@Table

當實體類與其映射的數據表名稱不一致時,需要使用該注解標注,該注解與 @Entity 標注并列使用,置于實體類注解之前。

name:數據庫的表名

catalog:數據庫目錄

schema:數據庫模式

@ID

該注解聲明一個實體類的屬性映射為數據庫的主鍵,一般我們將其標注在 getter 方法上。

@GeneratedValue

該注解用來設置主鍵的生成策略,通過 strategy 屬性指定

有四種策略:

IDENTITY:采用數據庫 ID 自增長的方式來自增主鍵字段,Oracle 不支持。

AUTO:JPA 自動選擇合適的策略,默認選項。

SEQUENCE:通過序列產生主鍵,通過 @SequenceGenerator 注解指定序列名,MySQL 不支持。

TABLE:通過表產生主鍵,框架借由表模擬序列產生主鍵,使用該策略可以使應用更易于數據庫移植。

@Cloumn

當實體類的屬性與其映射的數據表的列不同名時需要標注該注解。

name:數據表的列名。

unique:唯一約束。

nullable:是否可以為空。

length:列的長度。

columnDefinition

@Basic

表示基本注解,默認為沒有標注任何注解的 getter 方法添加該注解。

JPA API

Persistence

該類包含一個名為 createEntityManagerFactory 的 靜態方法 ,用來獲取 EntityManagerFactory。

EntityManagerFactory

EntityManagerFactory 接口主要用來創建 EntityManager 實例,提供了四個方法:

createManagerFactory() 用來創建 EntityManager。

createManagerFactory(Map map) Map 參數用來提供 EntityManager 的屬性。

isOpen() 檢查 EntityManagerFactory 是否處于打開狀態。

close() 關閉 EntityManagerFactory。

EntityManager

在 JPA 中,EntityManager 是完成持久化操作最核心的對象,實體作為一個普通的 Java 對象,只有在調用EntityManager 將其持久化后才會變成一個持久化對象。EntityManager 對象在一組實體類與底層數據源之間進行 O/R 映射的管理。它可以用來管理和更新、根據主鍵查找、還可以根據 JPQL 查詢實體。

實體的狀態:

新建狀態:新創建的對象,尚未擁有持久化主鍵。

持久化狀態:已經擁有持久化主鍵并和持久化建立了上下文環境。

游離狀態:已經擁有了持久化主鍵但是沒有和持久化建立上下文環境。

刪除狀態:已經擁有了持久化主鍵并和持久化建立了上下文環境,但是從數據庫中被刪除。

find(Class<T> entityClass, Object primayKey) 返回指定主鍵對應的實體類,如果這個實體存在與當前的持久化環境,則返回的是一個緩存對象,否則,會創建一個新的實體對象,如果沒有找到,返回 null。

getReference (Class<T> entityClass,Object primaryKey) 和 find 類似,只不過如果緩存中不存在當前實體,會創建一個實體類代理,但是不會立即加載數據庫中的信息,只有第一次使用時,才會加載信息,如果找不到對應的實體,拋出 EntityNotFoundException。

persist (Object entity):將創建的實體對象變成持久化狀態。

remove (Object entity):刪除實例。

merge (T entity):數據庫的插入和更新操作:

如果傳入的對象是一個臨時對象,即沒有 id 的對象,JPA 創建一個新的對象,并復制臨時對象的屬性到新對象中,將新對象執行持久化操作。

如果傳入的對象是一個游離對象,即存在 id 的對象,首先查詢緩存中是否存在 id 對象的持久化對象,如果存在,將游離對象的屬性拷貝到新創建的對象中,并執行更新操作;如果不存在,就查詢數據庫中是否存在 id 對應的記錄,如果存在,將游離對象的屬性拷貝到新創建的對象中,并執行更新操作;如果不存在,JPA 創建一個新的對象,并復制臨時對象的屬性到新對象中,將新對象執行持久化操作。

flush():同步持久化上下文環境,將持久化上下文環境中未保存實體的狀態信息保存到數據庫中。

setFulshMode(FlushModeType flushMode):設置持久化上下文的 Flush 模式:

FlushModeType.AUTO 為自動更新數據庫實體。

FlushModeType.COMMIT 為直到提交事務時才更新數據庫記錄。

getFlushMode() 獲取持久化上文的 Flush 模式。

refresh() 用數據庫實體記錄的值更新實體對象的狀態。

clear() 清除持久化上下文環境,斷開所有關聯的實體。

contains() 判斷一個實例是否屬于當前持久化上下文環境管理的實體。

isOpen() 查詢 EntityManager 是否處于打開狀態

getTransaction() 獲得一個事務。

close() 關閉 EntityManager 實例。

EntityTransaction

begin() 開啟事務。

commit() 提交事務。

rollback() 回滾事務。

setRollbackOnly() 使當前事務只能被撤消。

getRollbackOnly() 查看當前事務是否設置了只能撤消標志。

isActive() 查看當前事務是否是活動的,如果是,則不能調用 begin 方法,否則將拋出 IllegalStateException 異常;如果不是則不能調用commit、rollback、setRollbackOnly 及 getRollbackOnly 方法,否則將拋出 IllegalStateException 異常。

映射關聯關系

映射雙向一對多及多對一的關聯關系

雙向一對多關系中,必須存在一個關系維護端,在 JPA 規范中,要求 many 的一方作為關系的維護端(owner side),one 的一方作為被維護端(inverse side)。
可以在 one 方指定 @OneToMany 注釋并設置 mappedBy 屬性,以指定它是這一關聯中的被維護端,many 為維護端。
在 many 方指定 @ManyToOne 注釋,并使用 @JoinColumn 指定外鍵名稱。

使用 mappedBy 設置維護段的字段。

映射雙向一對一的關聯關系

基于外鍵的 1-1 關聯關系:在雙向的一對一關聯中,需要在關系被維護端(inverse side)中的 @OneToOne 注釋中指定 mappedBy,以指定是這一關聯中的被維護端。同時需要在關系維護端(owner side)建立外鍵列指向關系被維護端的主鍵列。

在維護端設置 unique 設置為 true。

如果延遲加載要起作用, 就必須設置一個代理對象。
Manager 其實可以不關聯一個 Department。
如果有 Department 關聯就設置為代理對象而延遲加載,如果不存在關聯的 Department 就設置 null,因為外鍵字段是定義在 Department 表中的,Hibernate 在不讀取 Department 表的情況是無法判斷是否有關聯有 Deparmtment,因此無法判斷設置 null 還是代理對象,而統一設置為代理對象,也無法滿足不關聯的情況,所以無法使用延遲加載,只有顯式讀取 Department。

映射雙向多對多的關聯關系

在雙向多對多關系中,我們必須指定一個關系維護端(owner side),可以通過 @ManyToMany 注釋中指定 mappedBy 屬性來標識其為關系維護端。

@ManyToMany@JoinTable(name="中間表名稱",
br/>@JoinTable(name="中間表名稱",
inversejoinColumns=@JoinColumn(name="對方類的外鍵",
br/>referencedColumnName="本類與外鍵對應的主鍵"),
inversejoinColumns=@JoinColumn(name="對方類的外鍵",
)

使用二級緩存

\<shared-cache-mode> 節點:若 JPA 實現支持二級緩存,該節點可以配置在當前的持久化單元中是否啟用二級緩存,可配置如下值:
ALL:所有的實體類都被緩存。
NONE:所有的實體類都不被緩存。
ENABLE_SELECTIVE:標識 @Cacheable(true) 注解的實體類將被緩存。
DISABLE_SELECTIVE:緩存除標識 @Cacheable(false) 以外的所有實體類。
UNSPECIFIED:默認值,JPA 產品默認值將被使用。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">

    <persistence-unit name="NewPersistenceUnit">
        <!--配置將使用哪個產品作為實現-->
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!--添加持久化類-->
        <class>com.kernel.jpa.helloworld.Customer</class>
        <class>com.kernel.jpa.helloworld.Order</class>
        <class>com.kernel.jpa.helloworld.Manager</class>
        <class>com.kernel.jpa.helloworld.Department</class>
        <!--配置二級緩存的策略-->
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
        <properties>
            <!--連接數據庫的基本信息-->
            <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql:///jpa"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="123456"/>
            <!--配置hibernate的基本屬性-->
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <!--二級緩存相關-->
            <property name="hibernate.cache.use_second_level_cache" value="true"/>
            <property name="hibernate.cache.region.factory_class" value="EnCacheRegionFactory"/>
            <property name="hibernate.cache.use_query_cache" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

JPQL

JPQL語言,即 Java Persistence Query Language 的簡稱。JPQL 是一種和 SQL 非常類似的中間性和對象化查詢語言,它最終會被編譯成針對不同底層數據庫的 SQL 查詢,從而屏蔽不同數據庫的差異。
JPQL語言的語句可以是 select 語句、update 語句或delete語句,它們都通過 Query 接口封裝執行。

javax.persistence.Query

Query接口封裝了執行數據庫查詢的相關方法。調用 EntityManager 的 createQuery、create NamedQuery 及 createNativeQuery 方法可以獲得查詢對象,進而可調用 Query 接口的相關方法來執行查詢操作。

Query接口的主要方法:
int executeUpdate() 用于執行update或delete語句。
List getResultList() 用于執行select語句并返回結果集實體列表。
Object getSingleResult() 用于執行只返回單個結果實體的select語句。
Query setFirstResult(int startPosition) 用于設置從哪個實體記錄開始返回查詢結果。
Query setMaxResults(int maxResult) 用于設置返回結果實體的最大數。與setFirstResult結合使用可實現分頁查詢。
Query setFlushMode(FlushModeType flushMode) 設置查詢對象的Flush模式。參數可以取2個枚舉值:FlushModeType.AUTO 為自動更新數據庫記錄,FlushMode Type.COMMIT 為直到提交事務時才更新數據庫記錄。

使用 Hibernate 的查詢緩存

String jpql = "FROM Customer c WHERE c.age > ?";
// 設置查詢緩存
Query query = entityManager.createQuery(jpql).setHint(QueryHints.HINT_CACHEABLE, true);
// 占位符的索引從1開始
query.setParameter(1, 2);
List<Customer> resultList = query.getResultList();
resultList = query.getResultList();

關聯查詢

JPQL 也支持和 SQL 中類似的關聯語法。如:
left out join / left join
inner join
left join / inner join fetch
其中,left join和left out join等義,都是允許符合條件的右邊表達式中的實體為空。

子查詢和 JPQL 函數

JPQL也支持子查詢,在 where 或 having 子句中可以包含另一個查詢。當子查詢返回多于 1 個結果集時,它常出現在 any、all、exist s表達式中用于集合匹配查詢。它們的用法與SQL語句基本相同。

JPQL提供了以下一些內建函數,包括字符串處理函數、算術函數和日期函數。
字符串處理函數主要有:
concat(String s1, String s2):字符串合并/連接函數。
substring(String s, int start, int length):取字串函數。
trim([leading|trailing|both,] [char c,] String s):從字符串中去掉首/尾指定的字符或空格。
lower(String s):將字符串轉換成小寫形式。
upper(String s):將字符串轉換成大寫形式。
length(String s):求字符串的長度。
locate(String s1, String s2[, int start]):從第一個字符串中查找第二個字符串(子串)出現的位置。若未找到則返回0。

整合 Spring

三種整合方式:
LocalEntityManagerFactoryBean:適用于那些僅使用 JPA 進行數據訪問的項目,該 FactoryBean 將根據JPA PersistenceProvider 自動檢測配置文件進行工作,一般從“META-INF/persistence.xml”讀取配置信息,這種方式最簡單,但不能設置 Spring 中定義的DataSource,且不支持 Spring 管理的全局事務
從JNDI中獲取:用于從 Java EE 服務器獲取指定的EntityManagerFactory,這種方式在進行 Spring 事務管理時一般要使用 JTA 事務管理
LocalContainerEntityManagerFactoryBean:適用于所有環境的 FactoryBean,能全面控制 EntityManagerFactory 配置,如指定 Spring 定義的 DataSource 等等。

<?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" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="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.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--配置自動掃描的包-->
    <context:component-scan base-package="com.kernel.spring.jpa"/>
    <!--配置C3P0數據源-->
    <context:property-placeholder location="classpath:db.properties"/>
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"/>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"/>
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <!--配置EntityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--配置JPA適配器-->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <!--配置實體類所在的包-->
        <property name="packagesToScan" value="com.kernel.spring.jpa.entities"/>
        <!--配置JPA的基本屬性-->
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>
    <!--配置JPA使用的事務管理器-->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <!--配置基于注解的事務配置-->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jpa
AI

通榆县| 柏乡县| 太原市| 兴安县| 金川县| 新昌县| 辽宁省| 凉山| 开封市| 克东县| 千阳县| 大宁县| 腾冲县| 永济市| 沾化县| 寻甸| 阿拉善右旗| 蒙自县| 张北县| 双鸭山市| 大田县| 贡嘎县| 延川县| 洛川县| 金川县| 原阳县| 海阳市| 安福县| 南康市| 浮梁县| 无极县| 丘北县| 鄱阳县| 札达县| 安远县| 墨江| 兖州市| 浙江省| 正安县| 宿迁市| 大埔县|