1. 程式人生 > >JPA概念以及相關知識點

JPA概念以及相關知識點

JPA : 物件關係對映ORM(Hibernate)的規範(持久化)
OMR是什麼??  --> 物件關係對映Object Relational Mapping
Hibernate --> ORM框架(實現了ORM規範)加快了操作資料庫的速度  -- 其中單表操作沒有太多優勢。
Hibernate和JPA的關係?   --> JPA是持久化規範,而Hibernate是其實現

JPA(Hibernate)和JDBC區別??
   JPA(Hibernate)對JDBC的封裝,開發效率高,效能低(不好控制),相容所有資料庫,好的快取機制,直接面向持久物件操作(缺點:不能干涉SQL生成)
  JDBC

操作資料庫最底層,效能最高,使用複雜(重複程式碼太多),沒有提供資料的快取,需要自己實現,移植資料庫很麻煩,改動比較多【主鍵的生成方式不同(mysql使用自增,oracle使用序列),分頁的sql語句也是不同(mysql使用limit,oracle使用ROWNUM)】

建表策略(配置自動生成表)  -- hibernate.hbm2ddl.auto配置選型

create-drop --> 先刪除表,再建立表,再刪除表(必須儲存關閉EntityManagerFactory)  【開發一般不用】 
create
--> 先刪除表,再建立表,不會再刪除表    【測試的時候使用】 
update

--> 修改(如果沒有表會建立,如果表裡面沒有屬性,對映資訊存在,會增加這個列)  【測試和web專案中使用】 
validate
--> 驗證(只驗證domain中有的部分) 表不存在,會丟擲異常,bean類對映資訊少屬性,表比對映定義的列要多,不會報錯,反之丟擲異常    【用在系統已經上線或者客戶給定了資料庫的情況下】

四大物件

Persistence : 工具類,建立EntityManagerFactory(解析xml) 
EntityManagerFactory  
: 建立EntityManager,( 重:連線池,sql,二級快取,domain關係等,執行緒安全) 
EntityManager

: 實體管理物件 ( 輕:連線,一級快取,執行緒不安全,一個請求[執行緒]一個EntityManager) 
    一級快取命中:同一個EntityManagerFactory,同一個EntityManager,同一個OID 
   OID:物件的全限定名#id的值 
Transaction
: 事務物件(EntityManager拿到的事務是同一個)

主鍵生成策略      [  @GeneratedValue  ]

identity:自增(型別必需是數字型別,資料庫必需支援自增策略) MySQL, SQL Server, DB2, Derby, Sybase, PostgreSQL 
sequence
:序列(型別必需是數字型別,資料庫必需支援序列策略) Oracle、PostgreSQL、DB2 
auto
:根據方言自動識別是自增還是序列  [@GeneratedValue預設是auto] 
table
:使用表模擬序列(效能有點差,因為相容各種資料庫)

JPA物件狀態

臨時狀態:new語句剛創建出來的 
持久化狀態
:和EntityManager物件發生關係(在一級快取中) 
遊離狀態
:持久化物件與EntityManager解除關係(從快取中移除, entityManager.close();之後) 
刪除狀態
:JPA特有狀態,執行remove方法時(計劃刪除,事務提交時被真的刪除)

髒資料更新:一個持久狀態物件在事務管理內,如果改變原來的資料(非主鍵),此時出現髒資料,在事務提交的時候自動發出update語句去修改[如果是臨時物件就需要merge去修改哦]

n-to-n錯誤(identifier of an instance of com.zhengqing.domain.Teacher was altered from 1 to 2) --> 持久化物件的OID不允許被修改

nosession錯誤 --> 提前關閉了entityManager,但還是使用它去訪問資料庫(懶載入物件)

持久化物件(bean層)定義規則:

①類不能定義為final類 
②屬性必須是包裝型別 
③有無參構造方法

域物件關係

依賴關係:表現層(controller)依賴業務層(service),業務層依賴持久化層(dao/repository) 
關聯關係
:  --> https://blog.csdn.net/qq_38225558/article/details/84109136
  多重性:一對一,多對一,一對多,多對多   
          一對一:共享主鍵,唯一外來鍵(擴充套件性更強) 
          多對一,一對多:外來鍵(外來鍵在哪邊,哪邊就是多方) 
          多對多:中間表 
  導航性:單向與雙向(注意:資料庫中無法表示導航性) 
聚合關係
:雙向的多對一,一對多 
組合關係
:強聚合(部分與整體不可分割) 
泛化關係
:繼承

快取
   一級快取(entityManager):同一個entityManagerFactory,同一個entityManager,同一個oid
   二級快取(entityManagerFactory):同一個entityManagerFactory,不同entityManager,同一個oid

二級快取 
   如何使用二級快取??
   ①導包  pom.xml中

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
    <version>4.3.8.Final</version>
</dependency>

②配置

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="com.zhengqing.jpa" transaction-type="RESOURCE_LOCAL">
        <!-- ALL:所有的實體類都被快取 -->
        <!-- NONE:所有的實體類都不被快取. -->
        <!-- ENABLE_SELECTIVE:標識 @Cacheable(true) 註解的實體類將被快取 -->
        <!-- DISABLE_SELECTIVE:快取除標識 @Cacheable(false) 以外的所有實體類 -->
        <!-- UNSPECIFIED:預設值,JPA 產品預設值將被使用 -->
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
        <properties>
            ...
            ...
            <!-- 配置二級快取 -->
            <!-- 開啟二級快取 -->
            <property name="hibernate.cache.use_second_level_cache" value="true" />
            <!-- 開啟查詢快取 -->
            <property name="hibernate.cache.use_query_cache" value="true" />
            <!-- 支援二級快取的工廠 -->                                                  <!--  這裡注意:如果是配置檔案中拷貝過來的話要修改!!!-->
            <property name=" hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" />
        </properties>
    </persistence-unit>
</persistence>

③加註解 @Cacheable  

④使用快取

什麼是延時(懶)載入?
   使用相應的物件的時候,它才會到資料庫中去獲取這個值

什麼是級聯?
  級聯增刪改(ALL) --> orphanRemoval=true
  組合關係必須用 --> cascade = CascadeType.ALL, orphanRemoval = true