搜尋
首頁Javajava教程SpringBoot JPA常用註解如何使用

    1.簡介

    Jpa 是一套ORM 的規範
    hibernate 不就是一個ORM 框架也提供了對於JPA 的實作

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

    2.常用註解

    #2.1 @ Entity

    標註目前類別為實體類,將對應到指定的資料庫表中

    @Entity
    public class Users {
    		
    }

    2.2 @Table

    一般與@Entity 註解一起使用,如果資料庫表名和類別名稱一致時不使用@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 {
      /**
       * 通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植
       */
      TABLE,
      /**
       * 通过序列产生主键,通过 @SequenceGenerator 注解指定序列名
       * MySql 不支持这种方式
       * Oracle 支持
       */
      SEQUENCE,
      /**
       * 采用数据库 ID自增长的方式来自增主键字段
       * Oracle 不支持这种方式;
       */
      IDENTITY,
      /**
       * 缺省值,JPA 根据数据库自动选择
       */
      AUTO;
    
      private GenerationType() {
      }
    }
    2.3.3 @SequenceGenerator
    2.3.4 @Column

    #當實體類別屬性名稱和資料庫列名不一致時必須要使用此註解

    @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

    表示目前屬性無需對應到資料庫中

    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 實體的四種狀態

    新狀態: 新建立尚未擁有持久性主鍵持久化狀態: 已經擁有持久性主鍵並和持久化建立了上下文關係遊離狀態: 擁有持久性主鍵,但沒有和持久化建立上下文關係刪除狀態: 擁有持久性主鍵,並且和持久化建立了上下文關係,但是從資料庫中刪除了

    4.1 find(Class entityClass, Object primaryKey)

    類似於hibernate 中session 的get()

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

    4.2 getReference(Class entityClass, Object primaryKey)

    類似與hibernate 中session 的load()
    只有當真正取得物件中的屬性時,才會去執行查詢的sql 語句,getReference() 只是傳回了一個代理物件

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

    注意:使用此方法可能出現懶載入異常的情況,也就是我們還沒去取得實體類別中的屬性值,結果EntityManager 就已經被關閉了

    ##4.3 persist

    ##類似與hibernate 中session 的save()

    注意:執行方法時傳入的物件無法為主鍵設定值會拋出例外

    4.4 remove

    類似與hibernate 中session 的delete()

    注意:此方法只能刪除持久化對象,而無法刪除遊離狀態的物件(hibernate 可以)

    <pre class='brush:php;toolbar:false;'> /** * 删除游离态(失败) */ public void testRemove(){ Users user = new Users(); Users.setUserId(1); entityManager.remove(customer); } /** * 删除持久化状态(成功) */ public void testRemove(){ Users user = entityManager.find(Users.class, 1); entityManager.remove(user); }</pre>4.5 merge(T entity)

    #類似與hibernate 中session 的saveOrUpdate()

    #

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

    SpringBoot JPA常用註解如何使用

    4.6 flush()

    類似與hibernate 中session 的flush()

    將上下文中所有未儲存的實體儲存到資料庫中

    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 {
    	// 如果两侧都要描述关联关系的话,维护关联关系的任务要交给多的一方
    	// 使用 @OneToMany 了 mappedBy 的代表不维护关联关系,也就是不会产生额外的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;
    }
    SpringBoot JPA常用註解如何使用

    ####

    6.4 双向一对一

    以学校和校长之间的关系为例,一个学校只有一个校长,一个校长也只属于一个学校
    一方使用 @OneToMany + @JoinColumn,另一方使用 @OneToOne(mappedBy=“xx”)
    具体由哪一方维护关联关系都可以,这里我们以学校一端维护关联关系为例
    保存时先保存不维护关联关系的一方(也就是使用@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 {
    	// 不维护关联关系要使用 mappedBy
    	@OneToOne(mappedBy="schoolMaster")
    	private School school;
    }

    6.5 双向多对多

    以学生和课程之间的关系为例,一个学生可以选多门课,一个课程也有多个学生,多对多需要一个中间表,也就是选课表
    维护关联关系的一方需要使用 @JoinTable
    关联关系也是只有一方维护即可,这里我们由学生表进行维护

    /**
     * 学生
     */
    @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 为与中间表与当前表所关联的字段的名称,referencedColumnName 为当前表中与中间表关联的字段的名称
    			joinColumns={@JoinColumn(name="student_id", referencedColumnName="student_id")},
    			// name 为与中间表与多对多另一方表所关联的字段的名称,referencedColumnName 为多对多另一方与中间表关联的字段的名称
    			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 中是有缓存的
    二级缓存可以实现,关闭了 EntityManager 之后缓存不会被清除
    使用 @Cacheable(true) 开启二级缓存

    8. JPQL

    8.1 查询接口

    8.1.1 createQuery
    	public void testCreateQuery(){
    		// 这里我们使用了一个 new Student,因为我们是查询 Student 中的部分属性,如果不适用 new Student 查询返回的结果就不是 Student 类型而是一个 Object[] 类型的 List
    		// 也可以在实体类中创建对应的构造器,然后使用如下这种 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的意思是只能在数据库中执行的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 关联查询

    存在一对多关系时,当我们查询一的一端时,默认多的一端是懒加载。此时我们如果想要一次性查询出所有的数据就需要使用关联查询

    注意: 下面 sql 中的重点就是要加上 fetch u.orders,表示要查询出用户所关联的所有订单

    	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常用註解如何使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述
    本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
    如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

    本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

    如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

    本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

    如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

    本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

    如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

    本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

    Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

    Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

    See all articles

    熱AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智慧驅動的應用程序,用於創建逼真的裸體照片

    AI Clothes Remover

    AI Clothes Remover

    用於從照片中去除衣服的線上人工智慧工具。

    Undress AI Tool

    Undress AI Tool

    免費脫衣圖片

    Clothoff.io

    Clothoff.io

    AI脫衣器

    AI Hentai Generator

    AI Hentai Generator

    免費產生 AI 無盡。

    熱門文章

    R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳圖形設置
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您聽不到任何人,如何修復音頻
    3 週前By尊渡假赌尊渡假赌尊渡假赌
    WWE 2K25:如何解鎖Myrise中的所有內容
    4 週前By尊渡假赌尊渡假赌尊渡假赌

    熱工具

    SAP NetWeaver Server Adapter for Eclipse

    SAP NetWeaver Server Adapter for Eclipse

    將Eclipse與SAP NetWeaver應用伺服器整合。

    禪工作室 13.0.1

    禪工作室 13.0.1

    強大的PHP整合開發環境

    SecLists

    SecLists

    SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

    Dreamweaver CS6

    Dreamweaver CS6

    視覺化網頁開發工具

    MantisBT

    MantisBT

    Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。