在使用 PostgreSQL 构建强大的 Java应用程序时,处理唯一标识符是一项基本要求。UUID(通用唯一标识符)提供了一种绝佳的替代方案,而不是依赖自动递增的数字 ID ,尤其是在分布式系统中。
随着时间的推移, 在 Java 应用程序中生成 UUID 作为主键已经变得非常普遍。在本教程中,我们将探讨如何使用 JPA(Java 持久性 API)在 PostgreSQL 中持久化 UUID,重点介绍实际实现,并提供一个在应用程序中管理用户的相关示例。
在本文中,我们介绍了使用 JPA 在 PostgreSQL 中保留 UUID 的基本步骤。
我们首先设置 PostgreSQL 并集成 JPA,以在应用程序和数据库之间建立连接。接下来,我们通过在 PostgreSQL 中定义 UUID 列并将其映射到实体类中作为主键,为 UUID 支持配置 JPA。
然后,我们演示了如何使用 JPA 存储库高效地存储和检索 UUID。最后,我们通过测试 UUID 持久性来验证实现。所有这些步骤确保应用程序保持可扩展性和安全性,并遵循现代最佳实践。
设置 PostgreSQL 和 JPA
在深入了解配置细节之前,让我们确保我们的开发环境已准备就绪。首先,我们需要一个 PostgreSQL 数据库。然后,我们将使用应用程序所需的 Maven 依赖项和 PostgreSQL 相关属性设置我们的 Spring Boot 项目。
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 查询。
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 数据库。
为 UUID 配置 JPA
现在我们的开发环境已经准备就绪,让我们专注于配置 JPA 以有效地处理 UUID。我们将在 PostgreSQL 中映射 UUID 列并将其与我们的 JPA 实体集成。
PostgreSQL 中的 UUID 列
在 PostgreSQL 中,UUID类型原生支持 128 位通用唯一标识符,使其成为确保主键唯一性的绝佳选择,尤其是在分布式系统中。
考虑在应用程序中管理用户的示例,让我们创建一个名为用户的表,其中我们利用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 ,从而简化了分配唯一主键的任务。
实体类
现在让我们创建一个 JPA 实体来映射用户表中的行:
@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。
用户名和电子邮件字段映射到各自的列并标记为@Column。电子邮件字段也被标记为唯一 ,以确保表中不允许重复的电子邮件条目。
存储库和服务类
接下来,让我们实现一个存储库来与数据库交互,以及一个服务层来封装用于管理用户实体的业务逻辑。
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 检索现有用户。
测试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("alice@example.com"); // 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("jane.smith@example.com"); 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("jane.smith@example.com"); // Verify the Id is UUID assertThat(retrievedUser.get().getId()).isNotNull(); assertThat(retrievedUser.get().getId()).isInstanceOf(UUID.class); }
|
通过这些测试,我们确保我们的应用程序可以使用基于 UUID 的主键可靠地存储和检索用户,从而确认 JPA 与 PostgreSQL 的 UUID 功能的集成。