使用 JPA 在 PostgreSQL 中保留 UUID
1.概述
當使用 PostgreSQL 建立健全的 Java 應用程式時,處理唯一識別碼是一項基本要求。 UUID(通用唯一識別碼)不依賴自動遞增的數位 ID,而是提供了一個很好的替代方案,特別是在分散式系統中。
隨著時間的推移,產生**UUID 作為主鍵在 Java 應用程式中已經變得相當普遍**。在本教程中,我們將探討如何使用 JPA(Java Persistence API)在 PostgreSQL 中持久保存 UUID,重點關注實際實作以及在應用程式中管理使用者的相關範例。
2.設定 PostgreSQL 和 JPA
在深入了解配置細節之前,讓我們確保我們的開發環境已準備就緒。首先,我們需要一個 PostgreSQL 資料庫。然後,我們將為我們的應用程式設定具有必要的 Maven 依賴項和 PostgreSQL 相關屬性的 Spring Boot 專案。
2.1. Maven 依賴項
要開始使用 PostgreSQL,我們將驅動程式依賴項新增到pom.xml檔案中:
<dependency>
 <groupId>org.postgresql</groupId>
 <artifactId>postgresql</artifactId>
 <scope>runtime</scope>
 </dependency>此依賴項新增了 PostgreSQL JDBC 驅動程序,使我們的應用程式能夠與資料庫連接和通訊。它確保了我們的 Java 應用程式和 PostgreSQL 之間的兼容性。
接下來,我們還需要加入spring-data-jpa依賴項:
<dependency>
 <groupId>org.springframework.data</groupId>
 <artifactId>spring-data-jpa</artifactId>
 </dependency>這種依賴關係引入了 Hibernate、Spring Data JPA 和其他實用程序,使我們能夠使用物件關聯映射 (ORM) 與關聯式資料庫進行互動。它還簡化了常見的資料庫操作,無需自訂 SQL 查詢。
2.2. PostgreSQL 配置
要配置資料來源,我們將必要的屬性新增到application.properties檔案:
spring.datasource.url=jdbc:postgresql://localhost:5432/user_management
 spring.datasource.username=username
 spring.datasource.password=password
 spring.jpa.hibernate.ddl-auto=update
 spring.jpa.show-sql=true此配置區塊透過指定 URL、名稱、身份驗證憑證和 Hibernate 設定等資料庫詳細信息,幫助我們的 Spring Boot 應用程式連接到 PostgreSQL 資料庫。
3.為 UUID 設定 JPA
現在我們的開發環境已經準備好了,讓我們專注於配置 JPA 以有效地處理 UUID。我們將在 PostgreSQL 中對應 UUID 欄位並將其與我們的 JPA 實體整合。
3.1. PostgreSQL 中的 UUID 欄
在 PostgreSQL 中, UUID類型原生支援 128 位元通用唯一標識符,這使其成為確保唯一主鍵的絕佳選擇,尤其是在分散式系統中。
考慮在應用程式中管理使用者的範例,讓我們建立一個名為users表,其中我們利用UUID作為主鍵:
CREATE TABLE users (
 id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
 username VARCHAR(50) NOT NULL,
 email VARCHAR(100) NOT NULL UNIQUE
 );這種結構確保每個使用者都有一個全域唯一的標識符,消除了不同系統之間密鑰衝突的風險。每當插入記錄時, gen_random_uuid()函數預設為id列產生一個新的隨機 UUID,從而簡化了分配唯一主鍵的任務。
3.2.實體類別
現在讓我們建立一個 JPA 實體來對應users表中的行:
@Entity
 @Table(name = "users")
 public class User {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(columnDefinition = "uuid", updatable = false, nullable = false)
 private UUID id;
 @Column(nullable = false)
 private String username;
 @Column(nullable = false, unique = true)
 private String email;
 // Getters and Setters
 }這裡, id欄位用@Id和@GeneratedValue註解,表示它是主鍵,它的值會自動產生為 UUID。我們也使用columnDefinition將此欄位明確聲明為uuid 。
username和email欄位對應到各自的列並標記為@Column 。 email欄位也被標記為unique以確保表中不允許重複的電子郵件條目。
3.3.儲存庫和服務類
接下來,讓我們實作一個與資料庫互動的儲存庫和一個服務層來封裝用於管理User實體的業務邏輯。
UserRepository將處理資料庫操作:
public interface UserRepository extends JpaRepository<User, UUID> {
 }
UserRepository擴展了JpaRepository ,為常見資料庫操作(例如儲存、尋找和刪除實體)提供內建方法。
UserService提供管理使用者的業務邏輯:
@Service
 public class UserService {
 @Autowired
 private UserRepository userRepository;
 public User createUser(String name, String email) {
 User user = new User();
 user.setName(name);
 user.setEmail(email);
 return userRepository.save(user);
 }
 public List<User> getAllUsers() {
 return userRepository.findAll();
 }
 public User getUserById(UUID id) {
 return userRepository.findById(id).orElse(null);
 }
 }UserService封裝了業務邏輯,與儲存庫互動以處理與使用者相關的操作,例如保存新使用者和透過 UUID 檢索現有使用者。
4.測試UUID持久性
我們將為UserRepository新增並執行測試,以確保在持久化和擷取具有 UUID 的使用者時功能正常。我們也會驗證已儲存的實體的id是否為有效的 UUID。
首先,我們新增一個測試來透過UserRepository儲存使用者:
@DataJpaTest
 public class UserRepositoryTest {
 @Autowired
 private UserRepository userRepository;
 @Test
 public void givenUserEntity_whenSaved_thenIdIsUUID() {
 // Create and save a User entity
 User user = new User();
 user.setName("Alice");
 user.setEmail("[email protected]");
 // Save the user to the database
 User savedUser = userRepository.save(user);
 // Verify the saved entity has a valid UUID
 assertThat(savedUser.getId()).isNotNull();
 assertThat(savedUser.getId()).isInstanceOf(UUID.class);
 }
 }接下來,讓我們在同一個類別中新增另一個測試來透過 ID 檢索使用者:
@Test
 public void givenSavedUser_whenFindById_thenUserIsRetrieved() {
 // Save a user
 User user = new User();
 user.setName("Jane Smith");
 user.setEmail("[email protected]");
 User savedUser = userRepository.save(user);
 // Retrieve the user by ID
 Optional<User> retrievedUser = userRepository.findById(savedUser.getId());
 // Verify the user is retrieved correctly
 assertThat(retrievedUser).isPresent();
 assertThat(retrievedUser.get().getId()).isEqualTo(savedUser.getId());
 assertThat(retrievedUser.get().getName()).isEqualTo("Jane Smith");
 assertThat(retrievedUser.get().getEmail()).isEqualTo("[email protected]");
 // Verify the Id is UUID
 assertThat(retrievedUser.get().getId()).isNotNull();
 assertThat(retrievedUser.get().getId()).isInstanceOf(UUID.class);
 }透過這些測試,我們確保我們的應用程式可以使用基於 UUID 的主鍵可靠地儲存和檢索用戶,從而確認 JPA 與 PostgreSQL 的 UUID 功能的整合。
5.結論
在本文中,我們介紹了使用 JPA 在 PostgreSQL 中持久保存 UUID 的基本步驟。
我們首先設定 PostgreSQL 並整合 JPA 以在應用程式和資料庫之間建立連接。接下來,我們透過在 PostgreSQL 中定義 UUID 欄位並將其對應到實體類別中作為主鍵來設定 JPA 以支援 UUID。
然後,我們示範如何使用 JPA 儲存庫有效地儲存和檢索 UUID。最後,我們透過測試 UUID 持久性來驗證實作。所有這些步驟可確保應用程式保持可擴展性和安全性,並遵循現代最佳實踐。
與往常一樣,該實作的原始程式碼可以在 GitHub 上取得。