JPA概念以及相關知識點
JPA : 物件關係對映ORM(Hibernate)的規範(持久化)
OMR是什麼?? --> 物件關係對映Object Relational Mapping
Hibernate --> ORM框架(實現了ORM規範)加快了操作資料庫的速度 -- 其中單表操作沒有太多優勢。
Hibernate和JPA的關係? --> JPA是持久化規範,而Hibernate是其實現
JPA(Hibernate)和JDBC區別??
JPA(Hibernate)對JDBC的封裝,開發效率高,效能低(不好控制),相容所有資料庫,好的快取機制,直接面向持久物件操作(缺點:不能干涉SQL生成)
JDBC
建表策略(配置自動生成表) -- 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