Java學習手冊:Hibernate/JPA 使用指南

Hibernate/JPA 使用指南

一、Hibernate 和 JPA 的核心概念

  • 實體(Entity) :實體是 JPA 中用于表示數據庫表的 Java 對象。通過在實體類上添加 @Entity 注解,JPA 可以將實體類映射到數據庫表。例如,定義一個 User 實體類:
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "username")private String username;@Column(name = "password")private String password;// 省略 getter 和 setter 方法
}
  • 持久化上下文(Persistence Context) :持久化上下文是 JPA 中用于管理實體對象的容器。它通過實體管理器(EntityManager)來管理實體的生命周期,包括實體的創建、讀取、更新和刪除操作。
  • EntityManager :是 JPA 中用于操作實體的核心接口。通過 EntityManager,開發者可以執行查詢、插入、更新和刪除操作。例如:
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;public class UserDao {private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("myPersistenceUnit");private EntityManager entityManager = entityManagerFactory.createEntityManager();public User findUser(Long id) {return entityManager.find(User.class, id);}public void saveUser(User user) {entityManager.getTransaction().begin();entityManager.persist(user);entityManager.getTransaction().commit();}
}
  • 事務管理(Transaction Management) :JPA 中的事務管理通過 EntityTransaction 接口實現。事務管理確保數據庫操作的原子性、一致性、隔離性和持久性。在上述代碼示例中,通過 entityManager.getTransaction() 獲取事務對象,并調用其 begin()commit() 方法來控制事務的開始和提交。

二、Hibernate 和 JPA 的配置與初始化

  • 配置文件 :在使用 Hibernate 實現 JPA 時,通常會涉及到以下幾個主要的配置文件:
    • hibernate.cfg.xml :這是 Hibernate 的主要配置文件,負責定義會話工廠的相關配置,包括數據庫連接信息、方言、事務類型等。以下是一個示例配置:
<hibernate-configuration><session-factory><property name="connection.driver_class">org.h2.Driver</property><property name="connection.url">jdbc:h2:mem:test</property><property name="connection.username">sa</property><property name="connection.password"></property><property name="dialect">org.hibernate.dialect.H2Dialect</property><property name="show_sql">true</property><property name="hbm2ddl.auto">update</property><property name="hibernate.c3p0.max_size">10</property><property name="hibernate.c3p0.min_size">1</property><property name="hibernate.c3p0.timeout">1800</property><property name="hibernate.c3p0.max_statements">50</property></session-factory>
</hibernate-configuration>
* **`persistence.xml`** :作為 JPA 規范的一部分,此文件定義了持久化單元的信息,包括 JPA 提供者、實體類列表、數據庫連接池等。以下是一個示例配置:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"version="2.0"><persistence-unit name="myPersistenceUnit" transaction-type="RESOURCE_LOCAL"><class>com.example.model.User</class><properties><property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/><property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC"/><property name="javax.persistence.jdbc.user" value="root"/><property name="javax.persistence.jdbc.password" value="password"/><property name="hibernate.hbm2ddl.auto" value="update"/><property name="hibernate.show_sql" value="true"/></properties></persistence-unit>
</persistence>
  • 初始化 EntityManagerFactory :通過配置文件或代碼方式創建 EntityManagerFactory。以下是一個基于 Spring 的配置示例:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import javax.sql.DataSource;
import java.util.Properties;@Configuration
public class JpaConfig {@Autowiredprivate DataSource dataSource;@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() {LocalContainerEntityManagerFactoryBean emFactory = new LocalContainerEntityManagerFactoryBean();emFactory.setDataSource(dataSource);emFactory.setPackagesToScan("com.example.model");emFactory.setJpaVendorAdapter(new HibernateJpaVendorAdapter());Properties jpaProperties = new Properties();jpaProperties.setProperty("hibernate.hbm2ddl.auto", "update");jpaProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");jpaProperties.setProperty("hibernate.show_sql", "true");emFactory.setJpaProperties(jpaProperties);return emFactory;}
}

三、基本操作

  • 查詢操作 :可以通過 EntityManager 的 find() 方法根據主鍵查詢實體對象,也可以使用 JPQL 進行復雜查詢。例如:
// 根據主鍵查詢
User user = entityManager.find(User.class, 1L);// 使用 JPQL 查詢
String jpql = "SELECT u FROM User u WHERE u.username = :username";
List<User> users = entityManager.createQuery(jpql, User.class).setParameter("username", "john_doe").getResultList();
  • 插入操作 :使用 EntityManager 的 persist() 方法將實體對象持久化到數據庫。例如:
User newUser = new User();
newUser.setUsername("john_doe");
newUser.setPassword("password123");
entityManager.getTransaction().begin();
entityManager.persist(newUser);
entityManager.getTransaction().commit();
  • 更新操作 :從數據庫中查詢出實體對象后,修改其屬性值,然后調用 merge() 方法將修改后的對象合并到持久化上下文中。例如:
User user = entityManager.find(User.class, 1L);
user.setUsername("john_doe_updated");
user = entityManager.merge(user);
  • 刪除操作 :使用 EntityManager 的 remove() 方法從數據庫中刪除實體對象。例如:
User user = entityManager.find(User.class, 1L);
entityManager.getTransaction().begin();entityManager.remove(user);entityManager.getTransaction().commit();

四、事務管理

在 JPA 中,事務管理通過 EntityTransaction 接口實現。以下是一個完整的事務管理示例:

EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();try {transaction.begin();// 執行數據庫操作User user = new User();user.setUsername("john_doe");user.setPassword("password123");entityManager.persist(user);transaction.commit();
} catch (Exception e) {if (transaction.isActive()) {transaction.rollback();}
} finally {entityManager.close();
}

五、對象關系映射

  • 一對一映射 :例如,一個用戶對應一個詳細信息:
@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@OneToOne(mappedBy = "user", cascade = CascadeType.ALL)private UserInfo userInfo;// 省略 getter 和 setter 方法
}@Entity
public class UserInfo {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String email;private String phone;@OneToOne@JoinColumn(name = "user_id")private User user;// 省略 getter 和 setter 方法
}
  • 一對多映射 :例如,一個部門對應多個員工:
@Entity
public class Department {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@OneToMany(mappedBy = "department", cascade = CascadeType.ALL)private List<Employee> employees = new ArrayList<>();// 省略 getter 和 setter 方法
}@Entity
public class Employee {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String name;@ManyToOne@JoinColumn(name = "department_id")private Department department;// 省略 getter 和 setter 方法
}
  • 多對多映射 :例如,用戶和角色之間的多對多關系:
@Entity
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String username;private String password;@ManyToMany(mappedBy = "users")private List<Role> roles = new ArrayList<>();// 省略 getter 和 setter 方法
}@Entity
public class Role {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private String roleName;@ManyToMany@JoinTable(name = "user_role",joinColumns = @JoinColumn(name = "role_id"),inverseJoinColumns = @JoinColumn(name = "user_id"))private List<User> users = new ArrayList<>();// 省略 getter 和 setter 方法
}

六、性能優化

  • 緩存策略 :Hibernate 提供了一級緩存和二級緩存。一級緩存是 Session 級別的緩存,二級緩存是 SessionFactory 級別的緩存。可以通過配置啟用二級緩存,如使用 EHCache:
<cache usage="read-write" region="user-region"/>
  • 批量操作 :對于大數據量的插入、更新和刪除操作,可以使用批量操作來提高性能。例如:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
String hql = "UPDATE Employee SET salary = :salary WHERE department_id IN (:departmentIds)";
Query query = session.createQuery(hql);
query.setParameter("salary", 5000);
query.setParameterList("departmentIds", Arrays.asList(1, 2, 3));
int updatedCount = query.executeUpdate();
tx.commit();
session.close();

七、與 Spring 框架的集成

  • 引入依賴 :在 Spring Boot 項目的 pom.xml 文件中添加 Spring Data JPA 和數據庫驅動的依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
  • 配置文件 :在 application.properties 文件中配置數據庫連接信息:
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
  • Repository 接口 :創建一個 Repository 接口,繼承 JpaRepository 接口以獲得基本的 CRUD 功能:
import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User, Long> {
}
  • Service 層 :創建一個 Service 類,使用 @Transactional 注解管理事務,并通過 @Autowired 注入 UserRepository
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactionalpublic User saveUser(User user) {return userRepository.save(user);}public User getUserById(Long id) {return userRepository.findById(id).orElse(null);}
}
  • Controller 層 :創建一個 Controller 類,通過 @Autowired 注入 UserService,并定義 RESTful API 接口:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;@PostMappingpublic User createUser(@RequestBody User user) {return userService.saveUser(user);}@GetMapping("/{id}")public User getUser(@PathVariable Long id) {return userService.getUserById(id);}
}

八、總結

Hibernate 是 JPA 的一個實現,它提供了豐富的功能和靈活的配置選項。通過合理配置 Hibernate 和 JPA,可以實現高效的數據庫操作,提高開發效率和代碼質量。在實際項目中,結合 Spring 框架可以進一步簡化開發過程,提高應用的可維護性和可擴展性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/79851.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/79851.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/79851.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

字符串匹配 之 拓展 KMP算法(Z算法)

文章目錄 習題2223.構造字符串的總得分和3031.將單詞恢復初始狀態所需的最短時間 II 靈神代碼模版 區別與KMP算法 KMP算法可用于求解在線性時間復雜度0(n)內求解模式串p在主串s中匹配的未知當然&#xff0c;由于在KMP算法中&#xff0c;預處理求解出了next數組&#xff0c;也就…

安全為上,在系統威脅建模中使用量化分析

*注&#xff1a;Open FAIR? 知識體系是一種開放和獨立的信息風險分析方法。它為理解、分析和度量信息風險提供了分類和方法。Open FAIR作為領先的風險分析方法論&#xff0c;已得到越來越多的大型組織認可。 在數字化風險與日俱增的今天&#xff0c;企業安全決策正面臨雙重挑戰…

游戲引擎學習第259天:OpenGL和軟件渲染器清理

回顧并為今天的內容做好鋪墊 今天&#xff0c;我們將對游戲的分析器進行升級。在之前的修復中&#xff0c;我們解決了分析器的一些敏感問題&#xff0c;例如它無法跨代碼重新加載進行分析&#xff0c;以及一些復雜的小問題。現在&#xff0c;我們的分析器看起來已經很穩定了。…

訊睿CMS模版常用標簽參數匯總

一、模板調用標簽 1、首頁 網站名稱&#xff1a;{SITE_NAME} 標題&#xff1a;{$meta_title}&#xff08;列表頁通用&#xff09; Keywords&#xff1a;{$meta_keywords} Description&#xff1a;{$meta_description}2、列表頁 迅睿cms調用本欄目基礎信息標簽代碼 當前欄目…

【C#】Buffer.BlockCopy的使用

Buffer.BlockCopy 是 C# 中的一個方法&#xff0c;用于在數組之間高效地復制字節塊。它主要用于操作字節數組&#xff08;byte[]&#xff09;&#xff0c;但也可以用于其他類型的數組&#xff0c;因為它直接基于內存操作。 以下是關于 Buffer.BlockCopy 的詳細說明和使用示例&…

記一次pdf轉Word的技術經歷

一、發現問題 前幾天在打開一個pdf文件時&#xff0c;遇到了一些問題&#xff0c;在Win10下使用WPS PDF、萬興PDF、Adobe Acrobat、Chrome瀏覽器打開都是正常顯示的&#xff1b;但是在macOS 10.13中使用系統自帶的預覽程序和Chrome瀏覽器&#xff08;由于macOS版本比較老了&am…

在Laravel 12中實現4A日志審計

以下是在Laravel 12中實現4A&#xff08;認證、授權、賬戶管理、審計&#xff09;日志審計并將日志存儲到MongoDB的完整方案&#xff08;包含性能優化和安全增強措施&#xff09;&#xff1a; 一、環境配置 安裝MongoDB擴展包 composer require jenssegers/mongodb配置.env …

鏈表高級操作與算法

鏈表是數據結構中的基礎&#xff0c;但也是面試和實際開發中的重點考察對象。今天我們將深入探討鏈表的高級操作和常見算法&#xff0c;讓你能夠輕松應對各種鏈表問題。 1. 鏈表翻轉 - 最經典的鏈表問題 鏈表翻轉是面試中的常見題目&#xff0c;也是理解鏈表指針操作的絕佳練…

架構思維:構建高并發讀服務_使用懶加載架構實現高性能讀服務

文章目錄 一、引言二、讀服務的功能性需求三、兩大基本設計原則1. 架構盡量不要分層2. 代碼盡可能簡單 四、實戰方案&#xff1a;懶加載架構及其四大挑戰五、改進思路六、總結與思考題 一、引言 在任何后臺系統設計中&#xff0c;「讀多寫少」的業務場景占據主流&#xff1a;瀏…

在運行 Hadoop 作業時,遇到“No such file or directory”,如何在windows里打包在虛擬機里運行

最近在學習Hadoop集群map reduce分布運算過程中&#xff0c;經多方面排查可能是電腦本身配置的原因導致每次運行都會報“No such file or directory”的錯誤&#xff0c;最后我是通過打包文件到虛擬機里運行得到結果&#xff0c;具體步驟如下&#xff1a; 前提是要保證maven已經…

軟考-軟件設計師中級備考 11、計算機網絡

1、計算機網絡的分類 按分布范圍分類 局域網&#xff08;LAN&#xff09;&#xff1a;覆蓋范圍通常在幾百米到幾千米以內&#xff0c;一般用于連接一個建筑物內或一個園區內的計算機設備&#xff0c;如學校的校園網、企業的辦公樓網絡等。其特點是傳輸速率高、延遲低、誤碼率低…

【C#】.net core6.0無法訪問到控制器方法,直接404。由于自己的不仔細,出現個低級錯誤,這讓DeepSeek看出來了,是什么錯誤呢,來瞧瞧

&#x1f339;歡迎來到《小5講堂》&#x1f339; &#x1f339;這是《C#》系列文章&#xff0c;每篇文章將以博主理解的角度展開講解。&#x1f339; &#x1f339;溫馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不對之處望指正&#xff01;&#…

當LLM遇上Agent:AI三大流派的“復仇者聯盟”

你一定聽說過ChatGPT和DeepSeek&#xff0c;也知道它們背后的LLM&#xff08;大語言模型&#xff09;有多牛——能寫詩、寫代碼、甚至假裝人類。但如果你以為這就是AI的極限&#xff0c;那你就too young too simple了&#xff01; 最近&#xff0c;**Agent&#xff08;智能體&a…

Spring Boot多模塊劃分設計

在Spring Boot多模塊項目中&#xff0c;模塊劃分主要有兩種思路&#xff1a;??技術分層劃分??和??業務功能劃分??。兩種方式各有優缺點&#xff0c;需要根據項目規模、團隊結構和業務特點來選擇。 ??1. 技術分層劃分&#xff08;橫向拆分&#xff09;?? 結構示例&…

兩次解析格式化字符串 + 使用SQLAlchemy的relationship執行任意命令 -- link-shortener b01lersCTF 2025

題目描述: A fast and reliable link shortener service, with a new feature to add private links! 我們走一遍邏輯 注冊 app.route("/register", methods[GET, POST]) def register(): """ 用戶注冊路由&#xff0c;處理用戶注冊請求&#xff…

后端id類型為long類型時,返回給前端瀏覽器四舍五入,導致id精度缺失問題

背景 今天在代碼里&#xff0c;掉了別人寫的接口&#xff0c;有個id的字段是long類型的&#xff0c;我這邊加點參數返回給前端&#xff0c;然后前端根據id修改&#xff0c;結果修改的數據記錄有&#xff0c;但是沒起作用&#xff0c;后來發現根據他傳給我的id在后臺數據庫查不…

Scartch038(四季變換)

知識回顧 1.了解和簡單使用音樂和視頻偵測模塊 2.使用克隆體做出波紋特效 3.取色器妙用偵測背景顏色 前言 我國幅員遼闊,不同地方的四季會有不同的美麗景色,這節課我帶你使用程序做一個體現北方四季變化的程序 之前的程序基本都是好玩的,這節課做一個能夠賞心悅目的程序。…

JVM happens-before 原則有哪些?

理解Java Memory Model (JMM) 中的 happens-before 原則對于編寫并發程序有很大幫助。 Happens-before 關系是 JMM 用來描述兩個操作之間的內存可見性以及執行順序的抽象概念。如果一個操作 A happens-before 另一個操作 B (記作 A hb B)&#xff0c;那么 JMM 向你保證&#x…

從 Eclipse Papyrus / XText 轉向.NET —— SCADE MBD技術的演化

從KPN[1]的萌芽開始&#xff0c;到SCADE的推出[2]&#xff0c;再到Scade 6的技術更迭[3]&#xff0c;SCADE 基于模型的開發技術已經歷許多。現在&#xff0c;Scade One 已開啟全新的探索 —— 從 Eclipse Papyrus / XText 轉向.NET 8跨平臺應用。 [1]: KPN, Kahn進程網絡 (197…

osquery在網絡安全入侵場景中的應用實戰(二)

背景 上次寫了osquery在網絡安全入侵場景中的應用實戰(一)結果還不錯,這次篇目二再增加一些場景。osquery主要解決的時員工被入侵之后電腦該如何溯源取證的問題。通常EDR會有日志,但是不會上報全量的日志。發現機器有惡意文件需要上級取證的時候,往往是比較麻煩的,會有這…