欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解SpringBoot?JPA常用注解的使用方法

 更新時間:2023年03月27日 10:08:11   作者:zhiguo.zheng  
這篇文章主要介紹了SpringBoot?JPA常用注解的使用方法,spring?boot作為當前主流的技術,來看看常用的注解怎么用,如果有錯誤的地方還請指正,需要的朋友可以參考下

1. 簡介

Jpa 是一套ORM 的規(guī)范
hibernate 不就是一個 ORM 框架也提供了對于 JPA 的實現(xiàn)

JPA(Java Persistence API):java 持久化 API

2. 常用注解

2.1 @Entity

標注當前類為實體類,將映射到指定的數(shù)據(jù)庫表中

@Entity
public class Users {
		
}

2.2 @Table

一般與 @Entity 注解一起使用,如果數(shù)據(jù)庫表名和類名一致時不使用 @Table 注解也是可以的,
否則需要使用 @Table 注解來指定表名

@Entity
@Table(name="t_users")
public class Users {
		
}

2.3 @Id 、@GeneratedValue、@SequenceGenerator、@Column

2.3.1 @Id

用于將實體類的屬性映射為主鍵

2.3.2 @GeneratedValue

指定主鍵生成策略

package javax.persistence;
/**
 * 策略類型
 */
public enum GenerationType {
  /**
   * 通過表產生主鍵,框架借由表模擬序列產生主鍵,使用該策略可以使應用更易于數(shù)據(jù)庫移植
   */
  TABLE,
  /**
   * 通過序列產生主鍵,通過 @SequenceGenerator 注解指定序列名
   * MySql 不支持這種方式
   * Oracle 支持
   */
  SEQUENCE,
  /**
   * 采用數(shù)據(jù)庫 ID自增長的方式來自增主鍵字段
   * Oracle 不支持這種方式;
   */
  IDENTITY,
  /**
   * 缺省值,JPA 根據(jù)數(shù)據(jù)庫自動選擇
   */
  AUTO;

  private GenerationType() {
  }
}

2.3.3 @SequenceGenerator

2.3.4 @Column

當實體類屬性名和數(shù)據(jù)庫列名不一致時必須要使用此注解

@Entity
@Table(name="t_users")
public class Users {

  @Id
  @Column(name = "user_id")
  @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq")
  @SequenceGenerator(name = "user_seq", sequenceName = "user_seq")
  private Long userId;
		
}

2.4 @Transient

表示當前屬性無需映射到數(shù)據(jù)庫中

2.5 @Temproal

主要針對 Date 類型的屬性使用,可以通過該注解指定時間的精度

@Entity
@Table(name="t_users")
public class Users {

  @Temporal(TemporalType.DATE) 
  private Date time1;
  
  @Temporal(TemporalType.TIME)
  private Date time2;
  
  @Temporal(TemporalType.TIMESTAMP)
  private Date time3;
}

3. EntityManagerFactory

類似與 hibernate 的 SessionFactory

4. EntityManager 實體的四種狀態(tài)

新建狀態(tài): 新創(chuàng)建還未擁有持久性主鍵持久化狀態(tài): 已經(jīng)擁有持久性主鍵并和持久化建立了上下文關系游離狀態(tài): 擁有持久性主鍵,但沒有和持久化建立上下文關系刪除狀態(tài): 擁有持久性主鍵,并且和持久化建立了上下文關系,但是從數(shù)據(jù)庫中刪除了

4.1 find(Class entityClass, Object primaryKey)

類似于 hibernate 中 session 的 get()

find 如果沒有查詢到會返回 null

4.2 getReference(Class entityClass, Object primaryKey)

類似與 hibernate 中 session 的 load()
只有當真正獲取對象中的屬性時,才會去執(zhí)行查詢的 sql 語句,getReference() 只是返回了一個代理對象

getReference 如果沒有查詢到不會返回 null , 會拋出 EntityNotFoundException

注意:使用此方法可能出現(xiàn)懶加載異常的情況,也就是我們還沒有去獲取實體類中的屬性值,結果 EntityManager 就已經(jīng)被關閉了

4.3 persist

類似與 hibernate 中 session 的 save()

注意:執(zhí)行方法時傳入的對象不能為主鍵設置值會拋出異常

4.4 remove

類似與 hibernate 中 session 的 delete()

注意:該方法只能刪除持久化對象,而不能刪除游離狀態(tài)的對象(hibernate 可以)

	/**
	 * 刪除游離態(tài)(失?。?
	 */
	public void testRemove(){
		Users user = new Users();
		Users.setUserId(1);
		entityManager.remove(customer);
	}
	
	/**
	 * 刪除持久化狀態(tài)(成功)
	 */
	public void testRemove(){
		Users user = entityManager.find(Users.class, 1);
		entityManager.remove(user);
	}

4.5 merge(T entity)

類似與 hibernate 中 session 的 saveOrUpdate()

	// 新建狀態(tài)
	public void testMerge	(){
		Users user= new Users();
		// 省略一系列的set
		// user.set.....
		Users newUser = entityManager.merge(user);
		// user.getUserId() == null  ==> true
		// newUser.getUserId() == null ==> false
	}

在這里插入圖片描述

4.6 flush()

類似與 hibernate 中 session 的 flush()

將上下文中所有未保存的實體保存到數(shù)據(jù)庫中

4.6 refresh()

類似與 hibernate 中 session 的 refresh()

刷新所有實體的屬性值

5. EntityTransaction

EntityManager.getTransaction()

5.1 begin

5.2 commit

5.3 rollback

6. 映射關系

6.1 單向一對多

以用戶和訂單之間的關系為例,一個用戶有多個訂單,一個訂單只屬于一個用戶
對于一對多關系的 insert,無論是先插入多的一方還是一的一方都會產生額外的 update 語句,因為多的一端在 insert 時不會插入外鍵的列

/**
 * 訂單和用戶是多對一的關系
 */
@Entity
@Table(name="t_order")
public class Order {
	// lazy為懶加載,默認為eager立即查詢
	@ManyToOne(fetch=FetchType.Lazy)
	// @JoinColumn標注字段是一個類,userId為該類的主鍵
	@JoinColumn(name="user_id")
	private Users user;
}

6.2 單向多對一

以用戶和訂單之間的關系為例,一個用戶有多個訂單,一個訂單只屬于一個用戶
對于多對一關系的 insert,最好先保存一的一端然后在保存多的一端。
如果先保存多的一端再保存一的一端,為了維護外鍵的關系,需要對多的一端進行額外的update的操作

/**
 * 訂單和用戶是多對一的關系
 */
@Entity
@Table(name="t_order")
public class Order {
	// lazy為懶加載,默認為eager立即查詢
	@ManyToOne(fetch=FetchType.Lazy)
	// @JoinColumn標注字段是一個類,userId為該類的主鍵
	@JoinColumn(name="user_id")
	private Users user;
}

6.3 雙向多對一

以用戶和訂單之間的關系為例,一個用戶有多個訂單,一個訂單只屬于一個用戶
雙向多對一就是以上兩個的結合,同時使用 @OneToMany 和 @ManyToOne

/**
 * 用戶和訂單是一對多的關系
 */
@Entity
@Table(name="t_users")
public class User {
	// 如果兩側都要描述關聯(lián)關系的話,維護關聯(lián)關系的任務要交給多的一方
	// 使用 @OneToMany 了 mappedBy 的代表不維護關聯(lián)關系,也就是不會產生額外的update語句
	// @OneToMany 和 @JoinColumn 不能同時使用會報錯
	@OneToMany(mappedBy="user")
	private Set<Orders> orders;
}

/**
 * 訂單和用戶是多對一的關系
 */
@Entity
@Table(name="t_orders")
public class Order {
	// lazy為懶加載,默認為eager立即查詢
	@ManyToOne(fetch=FetchType.Lazy)
	// @JoinColumn標注字段是一個類,userId為該類的主鍵
	@JoinColumn(name="user_id")
	private Users user;
}

在這里插入圖片描述

6.4 雙向一對一

以學校和校長之間的關系為例,一個學校只有一個校長,一個校長也只屬于一個學校
一方使用 @OneToMany + @JoinColumn,另一方使用 @OneToOne(mappedBy=“xx”)
具體由哪一方維護關聯(lián)關系都可以,這里我們以學校一端維護關聯(lián)關系為例
保存時先保存不維護關聯(lián)關系的一方(也就是使用@OneToOne(mappedBy=“xx”)的一方),否則會產生額外的 update 語句

/**
 * 學校
 */
@Entity
@Table(name="t_school")
public class School {
	// 默認為eager立即查詢
	@OneToOne
	// 添加唯一約束
	@JoinColumn(name="school_master_id", unique = true)
	private SchoolMaster schoolMaster;
}

/**
 * 校長
 */
@Entity
@Table(name="t_school_master")
public class SchoolMaster {
	// 不維護關聯(lián)關系要使用 mappedBy
	@OneToOne(mappedBy="schoolMaster")
	private School school;
}

6.5 雙向多對多

以學生和課程之間的關系為例,一個學生可以選多門課,一個課程也有多個學生,多對多需要一個中間表,也就是選課表
維護關聯(lián)關系的一方需要使用 @JoinTable
關聯(lián)關系也是只有一方維護即可,這里我們由學生表進行維護

/**
 * 學生
 */
@Entity
@Table(name="t_student")
public class Student {
	@GeneratedValue
	@Id
	private Long student_id;
	
	// 要使用 set 集合接收
	// 默認為lazy懶加載
	@ManyToMany
	// name 為中間表的表名
	@JoinTable(name="t_student_choose_course",
			// name 為與中間表與當前表所關聯(lián)的字段的名稱,referencedColumnName 為當前表中與中間表關聯(lián)的字段的名稱
			joinColumns={@JoinColumn(name="student_id", referencedColumnName="student_id")},
			// name 為與中間表與多對多另一方表所關聯(lián)的字段的名稱,referencedColumnName 為多對多另一方與中間表關聯(lián)的字段的名稱
			inverseJoinColumns={@JoinColumn(name="course_id", referencedColumnName="course_id")})
	private Set<Course> courses;
}

/**
 * 課程
 */
@Entity
@Table(name="t_course")
public class Course {
	@GeneratedValue
	@Id
	private Long course_id;
	
	// 要使用 set 集合接收
	// 默認為lazy懶加載
	@ManyToMany(mappedBy="courses")
	private Set<Student> students;
}

7. 二級緩存

開啟了二級緩存之后,緩存是可以跨越 EntityManager 的,
默認是一級緩存也就是在一個 EntityManager 中是有緩存的
二級緩存可以實現(xiàn),關閉了 EntityManager 之后緩存不會被清除
使用 @Cacheable(true) 開啟二級緩存

8. JPQL

8.1 查詢接口

8.1.1 createQuery

	public void testCreateQuery(){
		// 這里我們使用了一個 new Student,因為我們是查詢 Student 中的部分屬性,如果不適用 new Student 查詢返回的結果就不是 Student 類型而是一個 Object[] 類型的 List
		// 也可以在實體類中創(chuàng)建對應的構造器,然后使用如下這種 new Student 的方式,來把返回結果封裝為Student 對象
		String jpql = "SELECT new Student(s.name, s.age) FROM t_student s WHERE s.student_id > ?";
		// setParameter 時下標是從1開始的
		List result = entityManager.createQuery(jpql).setParameter(1, 1).getResultList();
	}

8.1.2 createNamedQuery

需要在類上使用 @NamedQuery 注解,事先聲明 sql 語句

@NamedQuery(name="testNamedQuery", query="select * from t_student WHERE student_id = ?")
@Entity
@Table(name="t_student")
public class Student {
	@GeneratedValue
	@Id
	private Long student_id;
	
	@Column
	private String name;
	
	@Column
	private int age;
}
	public void testCreateNamedQuery(){
		Query query = entityManager.createNamedQuery("testNamedQuery").setParameter(1, 3);
		Student student = (Student) query.getSingleResult();
	}

8.1.3 createNativeQuery

	public void testCreateNativeQuery(){
		// 本地sql的意思是只能在數(shù)據(jù)庫中執(zhí)行的sql語句
		String sql = "SELECT age FROM t_student WHERE student_id = ?";
		Query query = entityManager.createNativeQuery(sql).setParameter(1, 18);
		Object result = query.getSingleResult();
	}

8.2 關聯(lián)查詢

存在一對多關系時,當我們查詢一的一端時,默認多的一端是懶加載。此時我們如果想要一次性查詢出所有的數(shù)據(jù)就需要使用關聯(lián)查詢

注意: 下面 sql 中的重點就是要加上 fetch u.orders,表示要查詢出用戶所關聯(lián)的所有訂單

	public void testLeftOuterJoinFetch(){
		String jpql = "FROM t_users u LEFT OUTER JOIN FETCH u.orders WHERE u.id = ?";
		
		Users user = (Users) entityManager.createQuery(jpql).setParameter(1, 123).getSingleResult();
	}

到此這篇關于詳解SpringBoot JPA常用注解的使用方法的文章就介紹到這了,更多相關SpringBoot JPA使用方法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • springcloud-gateway整合jwt+jcasbin實現(xiàn)權限控制的詳細過程

    springcloud-gateway整合jwt+jcasbin實現(xiàn)權限控制的詳細過程

    這篇文章主要介紹了springcloud-gateway整合jwt+jcasbin實現(xiàn)權限控制,基于springboot+springcloud+nacos的簡單分布式項目,項目交互采用openFeign框架,單獨提取出來成為一個獨立的model,需要的朋友可以參考下
    2023-02-02
  • Spring Data JPA例子代碼[基于Spring Boot、Mysql]

    Spring Data JPA例子代碼[基于Spring Boot、Mysql]

    這篇文章主要介紹了Spring Data JPA例子代碼[基于Spring Boot、Mysql],小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • HashMap 和 HashSet的區(qū)別

    HashMap 和 HashSet的區(qū)別

    本文主要介紹HashMap 和 HashSet的區(qū)別,這里整理了詳細的資料來說名兩者的區(qū)別,并說明如何使用該方法,有需要的小伙伴可以參考下
    2016-09-09
  • 如何自動生成Mybatis的Mapper文件詳解

    如何自動生成Mybatis的Mapper文件詳解

    這篇文章主要給大家介紹了關于如何自動生成Mybatis的Mapper文件的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Mybatis具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • SpringCloudAlibaba整合Feign實現(xiàn)遠程HTTP調用的簡單示例

    SpringCloudAlibaba整合Feign實現(xiàn)遠程HTTP調用的簡單示例

    這篇文章主要介紹了SpringCloudAlibaba 整合 Feign 實現(xiàn)遠程 HTTP 調用,文章中使用的是OpenFeign,是Spring社區(qū)開發(fā)的組件,需要的朋友可以參考下
    2021-09-09
  • Java中的Semaphore如何使用

    Java中的Semaphore如何使用

    Semaphore實際上是一種共享鎖,因為它允許多個線程并發(fā)獲取共享的資源,在Semaphore對象創(chuàng)建時必須設置可用令牌的初始數(shù)量permits,用于控制并發(fā)時同時獲取資源權限的線程數(shù)量,這篇文章主要介紹了Java中的Semaphore如何使用,需要的朋友可以參考下
    2022-06-06
  • 淺析Java Web錯誤/異常處理頁面

    淺析Java Web錯誤/異常處理頁面

    這篇文章主要和大家一起對Java Web錯誤/異常處理頁面進行分析研究,感興趣的小伙伴們可以參考一下
    2016-03-03
  • Mac安裝Maven的幾種方法小結

    Mac安裝Maven的幾種方法小結

    本文主要介紹了Mac安裝Maven的幾種方法小結,主要包括通過Homebrew安裝Maven,通過SDKMAN安裝Maven和通過官方網(wǎng)站下載安裝包安裝Maven,感興趣的可以了解一下
    2024-01-01
  • SSM框架整合之junit測試的方法

    SSM框架整合之junit測試的方法

    本篇文章主要介紹了SSM框架整合之junit測試的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • 淺談Java 將圖片打包到jar中的路徑問題

    淺談Java 將圖片打包到jar中的路徑問題

    下面小編就為大家分享一篇淺談Java 將圖片打包到jar中的路徑問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02

最新評論