最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

1. 簡(jiǎn)介

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

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

2. 常用注解

2.1 @Entity

標(biāo)注當(dāng)前類(lèi)為實(shí)體類(lèi),將映射到指定的數(shù)據(jù)庫(kù)表中

@Entity
public class Users {
		
}

2.2 @Table

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

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

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

2.3.1 @Id

用于將實(shí)體類(lèi)的屬性映射為主鍵

2.3.2 @GeneratedValue

指定主鍵生成策略

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

  private GenerationType() {
  }
}

2.3.3 @SequenceGenerator

2.3.4 @Column

當(dāng)實(shí)體類(lèi)屬性名和數(shù)據(jù)庫(kù)列名不一致時(shí)必須要使用此注解

@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

表示當(dāng)前屬性無(wú)需映射到數(shù)據(jù)庫(kù)中

2.5 @Temproal

主要針對(duì) Date 類(lèi)型的屬性使用,可以通過(guò)該注解指定時(shí)間的精度

@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

類(lèi)似與 hibernate 的 SessionFactory

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

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

4.1 find(Class entityClass, Object primaryKey)

類(lèi)似于 hibernate 中 session 的 get()

find 如果沒(méi)有查詢(xún)到會(huì)返回 null

4.2 getReference(Class entityClass, Object primaryKey)

類(lèi)似與 hibernate 中 session 的 load()
只有當(dāng)真正獲取對(duì)象中的屬性時(shí),才會(huì)去執(zhí)行查詢(xún)的 sql 語(yǔ)句,getReference() 只是返回了一個(gè)代理對(duì)象

getReference 如果沒(méi)有查詢(xún)到不會(huì)返回 null , 會(huì)拋出 EntityNotFoundException

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

4.3 persist

類(lèi)似與 hibernate 中 session 的 save()

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

4.4 remove

類(lèi)似與 hibernate 中 session 的 delete()

注意:該方法只能刪除持久化對(duì)象,而不能刪除游離狀態(tài)的對(duì)象(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)

類(lèi)似與 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()

類(lèi)似與 hibernate 中 session 的 flush()

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

4.6 refresh()

類(lèi)似與 hibernate 中 session 的 refresh()

刷新所有實(shí)體的屬性值

5. EntityTransaction

EntityManager.getTransaction()

5.1 begin

5.2 commit

5.3 rollback

6. 映射關(guān)系

6.1 單向一對(duì)多

以用戶(hù)和訂單之間的關(guān)系為例,一個(gè)用戶(hù)有多個(gè)訂單,一個(gè)訂單只屬于一個(gè)用戶(hù)
對(duì)于一對(duì)多關(guān)系的 insert,無(wú)論是先插入多的一方還是一的一方都會(huì)產(chǎn)生額外的 update 語(yǔ)句,因?yàn)槎嗟囊欢嗽?insert 時(shí)不會(huì)插入外鍵的列

/**
 * 訂單和用戶(hù)是多對(duì)一的關(guān)系
 */
@Entity
@Table(name="t_order")
public class Order {
	// lazy為懶加載,默認(rèn)為eager立即查詢(xún)
	@ManyToOne(fetch=FetchType.Lazy)
	// @JoinColumn標(biāo)注字段是一個(gè)類(lèi),userId為該類(lèi)的主鍵
	@JoinColumn(name="user_id")
	private Users user;
}

6.2 單向多對(duì)一

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

/**
 * 訂單和用戶(hù)是多對(duì)一的關(guān)系
 */
@Entity
@Table(name="t_order")
public class Order {
	// lazy為懶加載,默認(rèn)為eager立即查詢(xún)
	@ManyToOne(fetch=FetchType.Lazy)
	// @JoinColumn標(biāo)注字段是一個(gè)類(lèi),userId為該類(lèi)的主鍵
	@JoinColumn(name="user_id")
	private Users user;
}

6.3 雙向多對(duì)一

以用戶(hù)和訂單之間的關(guān)系為例,一個(gè)用戶(hù)有多個(gè)訂單,一個(gè)訂單只屬于一個(gè)用戶(hù)
雙向多對(duì)一就是以上兩個(gè)的結(jié)合,同時(shí)使用 @OneToMany 和 @ManyToOne

/**
 * 用戶(hù)和訂單是一對(duì)多的關(guān)系
 */
@Entity
@Table(name="t_users")
public class User {
	// 如果兩側(cè)都要描述關(guān)聯(lián)關(guān)系的話,維護(hù)關(guān)聯(lián)關(guān)系的任務(wù)要交給多的一方
	// 使用 @OneToMany 了 mappedBy 的代表不維護(hù)關(guān)聯(lián)關(guān)系,也就是不會(huì)產(chǎn)生額外的update語(yǔ)句
	// @OneToMany 和 @JoinColumn 不能同時(shí)使用會(huì)報(bào)錯(cuò)
	@OneToMany(mappedBy="user")
	private Set<Orders> orders;
}

/**
 * 訂單和用戶(hù)是多對(duì)一的關(guān)系
 */
@Entity
@Table(name="t_orders")
public class Order {
	// lazy為懶加載,默認(rèn)為eager立即查詢(xún)
	@ManyToOne(fetch=FetchType.Lazy)
	// @JoinColumn標(biāo)注字段是一個(gè)類(lèi),userId為該類(lèi)的主鍵
	@JoinColumn(name="user_id")
	private Users user;
}

在這里插入圖片描述

6.4 雙向一對(duì)一

以學(xué)校和校長(zhǎng)之間的關(guān)系為例,一個(gè)學(xué)校只有一個(gè)校長(zhǎng),一個(gè)校長(zhǎng)也只屬于一個(gè)學(xué)校
一方使用 @OneToMany + @JoinColumn,另一方使用 @OneToOne(mappedBy=“xx”)
具體由哪一方維護(hù)關(guān)聯(lián)關(guān)系都可以,這里我們以學(xué)校一端維護(hù)關(guān)聯(lián)關(guān)系為例
保存時(shí)先保存不維護(hù)關(guān)聯(lián)關(guān)系的一方(也就是使用@OneToOne(mappedBy=“xx”)的一方),否則會(huì)產(chǎn)生額外的 update 語(yǔ)句

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

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

6.5 雙向多對(duì)多

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

/**
 * 學(xué)生
 */
@Entity
@Table(name="t_student")
public class Student {
	@GeneratedValue
	@Id
	private Long student_id;
	
	// 要使用 set 集合接收
	// 默認(rèn)為lazy懶加載
	@ManyToMany
	// name 為中間表的表名
	@JoinTable(name="t_student_choose_course",
			// name 為與中間表與當(dāng)前表所關(guān)聯(lián)的字段的名稱(chēng),referencedColumnName 為當(dāng)前表中與中間表關(guān)聯(lián)的字段的名稱(chēng)
			joinColumns={@JoinColumn(name="student_id", referencedColumnName="student_id")},
			// name 為與中間表與多對(duì)多另一方表所關(guān)聯(lián)的字段的名稱(chēng),referencedColumnName 為多對(duì)多另一方與中間表關(guān)聯(lián)的字段的名稱(chēng)
			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 集合接收
	// 默認(rèn)為lazy懶加載
	@ManyToMany(mappedBy="courses")
	private Set<Student> students;
}

7. 二級(jí)緩存

開(kāi)啟了二級(jí)緩存之后,緩存是可以跨越 EntityManager 的,
默認(rèn)是一級(jí)緩存也就是在一個(gè) EntityManager 中是有緩存的
二級(jí)緩存可以實(shí)現(xiàn),關(guān)閉了 EntityManager 之后緩存不會(huì)被清除
使用 @Cacheable(true) 開(kāi)啟二級(jí)緩存

8. JPQL

8.1 查詢(xún)接口

8.1.1 createQuery

	public void testCreateQuery(){
		// 這里我們使用了一個(gè) new Student,因?yàn)槲覀兪遣樵?xún) Student 中的部分屬性,如果不適用 new Student 查詢(xún)返回的結(jié)果就不是 Student 類(lèi)型而是一個(gè) Object[] 類(lèi)型的 List
		// 也可以在實(shí)體類(lèi)中創(chuàng)建對(duì)應(yīng)的構(gòu)造器,然后使用如下這種 new Student 的方式,來(lái)把返回結(jié)果封裝為Student 對(duì)象
		String jpql = "SELECT new Student(s.name, s.age) FROM t_student s WHERE s.student_id > ?";
		// setParameter 時(shí)下標(biāo)是從1開(kāi)始的
		List result = entityManager.createQuery(jpql).setParameter(1, 1).getResultList();
	}

8.1.2 createNamedQuery

需要在類(lèi)上使用 @NamedQuery 注解,事先聲明 sql 語(yǔ)句

@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ù)庫(kù)中執(zhí)行的sql語(yǔ)句
		String sql = "SELECT age FROM t_student WHERE student_id = ?";
		Query query = entityManager.createNativeQuery(sql).setParameter(1, 18);
		Object result = query.getSingleResult();
	}

8.2 關(guān)聯(lián)查詢(xún)

存在一對(duì)多關(guān)系時(shí),當(dāng)我們查詢(xún)一的一端時(shí),默認(rèn)多的一端是懶加載。此時(shí)我們?nèi)绻胍淮涡圆樵?xún)出所有的數(shù)據(jù)就需要使用關(guān)聯(lián)查詢(xún)

注意: 下面 sql 中的重點(diǎn)就是要加上 fetch u.orders,表示要查詢(xún)出用戶(hù)所關(guān)聯(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();
	}

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

相關(guān)文章

  • SpringBoot項(xiàng)目多層級(jí)多環(huán)境yml設(shè)計(jì)詳解

    SpringBoot項(xiàng)目多層級(jí)多環(huán)境yml設(shè)計(jì)詳解

    這篇文章主要為大家介紹了SpringBoot項(xiàng)目多層級(jí)多環(huán)境yml設(shè)計(jì)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • java猜數(shù)字小游戲案例

    java猜數(shù)字小游戲案例

    這篇文章主要為大家詳細(xì)介紹了java猜數(shù)字小游戲案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-10-10
  • SpringBoot項(xiàng)目實(shí)現(xiàn)分布式日志鏈路追蹤

    SpringBoot項(xiàng)目實(shí)現(xiàn)分布式日志鏈路追蹤

    這篇文章主要給大家介紹了Spring Boot項(xiàng)目如何實(shí)現(xiàn)分布式日志鏈路追蹤,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Spring框架 XML配置事務(wù)控制的步驟操作

    Spring框架 XML配置事務(wù)控制的步驟操作

    這篇文章主要介紹了Spring框架 XML配置事務(wù)控制的步驟操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java自定義枚舉轉(zhuǎn)換器示例

    java自定義枚舉轉(zhuǎn)換器示例

    這篇文章主要介紹了java自定義枚舉轉(zhuǎn)換器示例,需要的朋友可以參考下
    2014-05-05
  • Java超詳細(xì)講解如何生成隨機(jī)整數(shù)

    Java超詳細(xì)講解如何生成隨機(jī)整數(shù)

    在?Java?中,生成隨機(jī)數(shù)的場(chǎng)景有很多,所以本文我們就來(lái)盤(pán)點(diǎn)一下?幾種生成隨機(jī)數(shù)的方式,以及它們之間的區(qū)別和每種生成方式所對(duì)應(yīng)的場(chǎng)景
    2022-05-05
  • SpringBoot分頁(yè)的實(shí)現(xiàn)與long型id精度丟失問(wèn)題的解決方案介紹

    SpringBoot分頁(yè)的實(shí)現(xiàn)與long型id精度丟失問(wèn)題的解決方案介紹

    在以后的開(kāi)發(fā)中,當(dāng)全局唯一id的生成策略生成很長(zhǎng)的Long型數(shù)值id之后會(huì)超過(guò)JS對(duì)Long型數(shù)據(jù)處理的能力范圍,可能發(fā)生精度丟失而造成后端方法失效,我們要學(xué)會(huì)解決。分頁(yè)功能雖然簡(jiǎn)單但是非常重要,對(duì)于剛接觸項(xiàng)目的人一定要重點(diǎn)注意
    2022-10-10
  • Java中的MapStruct用法詳解

    Java中的MapStruct用法詳解

    這篇文章主要介紹了Java中的MapStruct用法詳解,MapStuct的使用非常簡(jiǎn)單,把對(duì)應(yīng)的jar包引入即可,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • XFire構(gòu)建web service客戶(hù)端的五種方式

    XFire構(gòu)建web service客戶(hù)端的五種方式

    本篇文章主要介紹了XFire構(gòu)建web service客戶(hù)端的五種方式。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01
  • 新手小白學(xué)JAVA IDEA下載使用手冊(cè)全集

    新手小白學(xué)JAVA IDEA下載使用手冊(cè)全集

    IDEA的每一個(gè)方面都是為了最大限度地提高開(kāi)發(fā)人員的工作效率而設(shè)計(jì)的,它的智能編碼輔助和人機(jī)工程學(xué)設(shè)計(jì)會(huì)讓開(kāi)發(fā)過(guò)程變得愉悅且高效,今天給大家分享新手小白學(xué)JAVA IDEA下載使用手冊(cè)全集,對(duì)idea新手使用相關(guān)知識(shí)感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2021-05-05

最新評(píng)論

外汇| 玛纳斯县| 兰考县| 东明县| 呈贡县| 黄骅市| 秦安县| 右玉县| 漠河县| 陇川县| 灯塔市| 汾西县| 赤壁市| 镇原县| 永德县| 深州市| 上蔡县| 绥江县| 搜索| 芷江| 佛坪县| 昭平县| 资兴市| 金寨县| 桂阳县| 舟山市| 淮北市| 乌兰察布市| 屯留县| 泾源县| 津市市| 鹤岗市| 玉林市| 台南县| 南城县| 高雄市| 会昌县| 会宁县| 瑞金市| 台中县| 沛县|