SpringData+JPA基礎、Spring/Springboot整合

JPA教程(基礎API、Spring整合、Springboot整合)

JPA springdata 整合jpa 根據類創建表 無則建有則更 接口增刪改查操作 類比springdata整合mongdb和es等

實例代碼和資料

**一、**常見註解

註解 只有在spring或springboot環境下才可以在屬性上加註解,否則強制getXX方法上加

@Entity			標誌實體
@Table			別名,默認爲實體名
@Id				必不可少 否則報錯 指定主鍵
@GeneratedValue(strategy,generator) mysql支持identity、oracle支持sequence、auto默認自動選擇、table通過表生成
@Column 標註的 columnDefinition 屬性: 表示該字段在數據庫中的實際類型 Date屬性無法自動,String默認對應varchar
@Transient 		忽略映射	 自定義的getXX方法加上此註解  Spring環境下如果找不到對應屬性會自動忽略
@Basic 		表示一個簡單的屬性到數據庫表的字段的映射,對於沒有任何標註的 getXxxx() 方法,默認即爲@Basic
@Basic(fetch = FetchType.LAZY,optional = false)	懶加載、不允許爲空
@Temporal(TemporalType.TIMESTAMP) 指定日期在數據庫的類型 如date--年月日,timestamp年月日時分秒

映射關係相關注解 注意區分單向和雙向映射

@JoinColumn(name="CUSTOMER_ID") 外鍵方
@ManyToOne(fetch=FetchType.LAZY) mappedby不和上面註解一起用	默認EAGER左外連接,懶加載獲取時才查兩次
@ManyToMany
@OneToOne

**二、**實體的狀態:

  • 新建狀態: 新創建的對象,尚未擁有持久性主鍵。 new沒ID
  • 遊離狀態:擁有持久化主鍵,但是沒有與持久化建立上下文環境new 有ID
  • 持久化狀態:已經擁有持久性主鍵並和持久化建立了上下文環境
  • 刪除狀態: 擁有持久化主鍵,已經和持久化建立上下文環境,但是從數據庫中刪除

**三、**使用JPA持久化對象的步驟

1,創建 persistence.xml, 在這個文件中配置持久化單元
需要指定跟哪個數據庫進行交互;
需要指定 JPA 使用哪個持久化的框架以及配置該框架的基本屬性
2,創建實體類, 使用 annotation 來描述實體類跟數據庫表之間的映射關係.
使用 JPA API 完成數據增加、刪除、修改和查詢操作
3,創建 EntityManagerFactory可指定屬性如數據表替換或更新、sql的打印;
4,創建 EntityManager (對應 Hibernate 中的Session),也可指定屬性
5,開啓事務,持久化操作,關閉事務

**四、**JPA常用API

  • 1,創建EntityManagerFactory,兩個重載構造

  • 2,創建管理器EntityManage,兩個重載構造

  • 3,事務EntityTransaction:begin commit rollback isActive

  • 4,EntityManager的基本操作

    find/getReference 	前者不存在null,後者存在ok,不存在報錯   用到對象才調用select語句查詢
    persist不能有id,更新可先查最後提交事務 或 再次調用方法
    remove 只能操作持久化對象,遊離對象不可
    merge 臨時對象沒ID創建--複製屬性新對象--insert		3條語句(主鍵查更+insert)
          遊離對象有ID創建--緩存存在--複製屬性新對象--update   2條sql   1條查數據庫,緩存了,1條更
          遊離對象有ID創建--緩存不存在--數據庫存在select--update		2條(先select數據庫,再update)
          遊離對象有ID創建--緩存不存在--數據庫不存在select--複製屬性新對象--insert  4條(先select數	  據庫,主鍵查更+insert)
    flush	同步上下文環境,將未保存實體同步數據庫,兩種模式 auto、commit
    refresh  更新數據庫實體
    clear 清除上下文環境
    contains 判斷實例是否被上下文環境管理
    isOpen  管理器是否打開
    getTran 事務
    close
    
    createQuery (String qlString):創建一個查詢對象。
    createNamedQuery (String name):根據命名的查詢語句塊創建查詢對象。參數爲命名的查詢語句。
    createNativeQuery (String sqlString):使用標準 SQL語句創建查詢對象。參數爲標準SQL語句字符串。
    createNativeQuery (String sqls, String resultSetMapping):使用標準SQL語句創建查詢對象,並指定返回結果集 Map的 名稱。
    

五、一對一、一對多、多對多:單向、雙向

注意:@JoinColumn可選,會默認設置映射對象xx_id,若默認命名和該對象屬性重複,則直接以映射對象名生成外鍵。只是可取別名

單向

單向使用一邊註解即可,無需mappby,多的一方獲取少的一方默認是左外連接,區別於SpringData默認接口查詢方法是懶加載

雙向必須通過mappedBy指定關係維護端

雙向
##雙向一對多:  (顧客、訂單爲例)
	1=被維護端@OneToMany(fetch=FetchType.LAZY,cascade={CascadeType.REMOVE},mappedBy="customer")
	n=關係維護端@JoinColumn(name="CUSTOMER_ID")		//可選 因爲必須通過mapperby指定關係,否則生成表數錯誤 如果兩者都沒,就會在兩邊都建立外鍵造成刪除不了表,執行以下sql纔可刪除	
	set @@foreign_key_checks=OFF;臨時關閉約束	
	SET FOREIGN_KEY_CHECKS=0;關閉約束
	 @ManyToOne(fetch=FetchType.LAZY)
	*保存
	1)建議先保存1的一方	顧客表採用表主鍵策略,訂單id自增	5條語句:查更+3條insert
	2)先保存n的一方  7條sql:2條oder insert+2條主鍵查更+1條customer insert+2條order update
	*不能先刪除1的一端,有外鍵約束,設置級聯可連帶刪除n的一端
	*在1的一方設置懶加載策略,即兩次查詢,否則默認左外連接
	*默認查1的一方即是會左外連接連帶查出n的一方的,只是可以設置加載策略爲懶加載
##雙向一對一:(經理、部門爲例)
	1=@OneToOne(fetch=FetchType.LAZY)
	1=@OneToOne(mappedBy="mgr") 必須有mapperby 否則兩邊都生成外鍵無法刪除
	1)先保存沒有外鍵的一方,2條sql
	2)先保存外鍵一方,3條其中最後一條更新
	*加載策略可查出來優化 如部門類設置懶加載,經理默認,查部門,3條sql:先查部門,再經理,懶加載部門第二條
	*先查經理默認左外連接 1條sql
	
##雙向多對多:(商品類目、商品爲例)
	n=@JoinTable(name="ITEM_CATEGORY",
		joinColumns={@JoinColumn(name="ITEM_ID", referencedColumnName="ID")},
		inverseJoinColumns={@JoinColumn(name="CATEGORY_ID", referencedColumnName="ID")})
	@ManyToMany
	n=@ManyToMany(mappedBy="categories")
	*一定要有維護關係且只能通過mapperby指定,不能通過@JoinColumn指定,使用一個或多個@JoinColumn都將生成表個數錯誤 都是4張
	*多對多保存數據8條sql:2+2+4條橋表
	*多對多查數據,兩邊查都一樣的sql語句,默認就是懶加載,區別於上兩種默認左外連接

六、二級緩存

ALL:所有的實體類都被緩存

NONE所有的實體類都不被緩存.

ENABLE_SELECTIVE:標識 @Cacheable(true) 註解的實體類將被緩存

DISABLE_SELECTIVE:緩存除標識 @Cacheable(false) 以外的所有實體類

UNSPECIFIED:默認值,JPA 產品默認值將被使用

默認一級緩存同一個管理器內 相同sql只查一次 類比mybatis緩存同一session
開啓二級緩存 不同管理器相同sql也只查一次  類比mybatis緩存不同session  前提是配置合理

七、Query接口的方法

getSingleResult getResultList setHint緩存

1,createQuery 全部屬性、部分屬性、where、orderby、groupby、外連接、子查詢、多表、內建函數等 對象
2,createNamedQuery query定義在實體中 無需select 對象
3,createNativeQuery setHint 標準sql
4,createNativeQuery 帶結果集參數 標準sql

八、JPA操作數據的幾種方式

  1. 繼承接口默認的方式,不夠通過通過Query接口自定義JPQL

  2. 使用JPA API 管理器操作

  3. 自定義JPQL語言sql的編寫查刪改 JPQL對實體操作不支持insert,對本地sql可以

  4. 自定義repository@PersistenceContext+管理器操作

    注意:增刪改必須加@Modify註解,修改刪除只能返回int或void,且必須在調用方法處聲明事務(SpringData提供默認接口方式不用,Spring環境中調用客戶端管理器操作也要事務)


SpringData相關

一、Repository接口

無任何方法,需按照規定自定義方法
使用方式:1,繼承接口 2,註解@RepositoryDefinition(domainClass=Person.class,idClass=Integer.class)+自定義方法

二、@NoRepositoryBean註解

​ 過濾創建bean 無法注入 註解標識作爲中間接口,不創建代理,如JpaRepo、CrudRepo等

三、CurdRepository、PagingAndSortingRepository、JpaRepository、JpaSpecificationExecutor(分頁+篩選條件)等的使用

自定義JPQL

  • ?1 第一個參數
  • :name+@Param(不加默認相同名字)第一個參數
  • ?#{[0]}第一個參數
  • :#{#productInfo.productId} 參數爲封裝對象
  • *#{#entityName}取實體
@Query("select t from #{#entityName} t where t.attribute = ?1")
List<T> findAllByAttribute(String attribute);

@Query("select u from User u where u.firstname = ?1 and u.firstname=?#{[0]} and u.emailAddress = ?#{principal.emailAddress}")
List<User> findByFirstnameAndCurrentUserWithCustomQuery(String firstname);

@Query("select u from User u where u.lastname like %:#{[0]}% and u.lastname like %:lastname%")
List<User> findByLastnameWithSpelExpression(@Param("lastname") String lastname);

@Query("select u from User u where u.firstname like %?#{escape([0])}% escape ?#{escapeCharacter()}")
List<User> findContainingEscaped(String namePart);

5.3.7使用SpEL表達式

官方文檔https://docs.spring.io/spring-data/jpa/docs/2.1.10.RELEASE/reference/html/#jpa.modifying-queries對象參數https://spring.io/blog/2014/07/15/spel-support-in-spring-data-jpa-query-definitions

@Query("select u from User u where u.age = ?#{[0]}")
List<User> findUsersByAge(int age);

@Query("select u from User u where u.firstname = :#{#customer.firstname}")
List<User> findUsersByCustomersFirstname(@Param("customer") Customer customer);

由於JPA、lombok引起的CleanUp問題
https://blog.csdn.net/qq_22327273/article/details/88578187?tdsourcetag=s_pctim_aiomsg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章