> 技术文档 > Spring Boot 集成 PostgreSQL 超详细指南(含完整代码)_springboot postgresql

Spring Boot 集成 PostgreSQL 超详细指南(含完整代码)_springboot postgresql


Spring Boot 集成 PostgreSQL 超详细指南(含完整代码)

  • 一、环境准备与项目搭建
    • 1.1 前置条件
    • 1.2 创建Spring Boot项目
  • 二、核心配置与依赖
    • 2.1 添加Maven依赖
    • 2.2 配置数据库连接
  • 三、核心功能实现(用户管理示例)
    • 3.1 创建实体类(User)
    • 3.2 创建Repository接口
    • 3.3 创建Service层
    • 3.4 创建Controller层
  • 四、PostgreSQL特色功能集成
    • 4.1 JSONB类型存储与查询
      • (1)存储JSONB数据
      • (2)查询JSONB字段
    • 4.2 时序数据存储(TimescaleDB扩展)
      • (1)安装TimescaleDB扩展
      • (2)创建时序表
      • (3)使用TimeScaleRepository
  • 五、生产环境优化
    • 5.1 连接池调优
    • 5.2 事务管理优化
    • 5.3 数据库迁移(Flyway)
      • (1)添加Flyway依赖
      • (2)配置Flyway
      • (3)创建迁移脚本
  • 六、常见问题与解决方案
    • 6.1 连接失败:无法连接到PostgreSQL
    • 6.2 JSONB字段查询报错
    • 6.3 事务回滚不生效
  • 七、总结

一、环境准备与项目搭建

1.1 前置条件

  • JDK 17+(推荐JDK 21)
  • Maven 3.8+ 或 Gradle 8.0+
  • PostgreSQL 14+(本地或云数据库)
  • IDE:IntelliJ IDEA(推荐)或 Eclipse

1.2 创建Spring Boot项目

通过 Spring Initializr 生成项目,选择以下依赖:

  • Spring Web(Web开发)
  • Spring Data JPA(ORM框架)
  • PostgreSQL Driver(数据库驱动)
  • Lombok(简化实体类代码,可选)

二、核心配置与依赖

2.1 添加Maven依赖

在pom.xml中添加以下配置(Gradle用户参考build.gradle):

<dependencies>  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>  <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <scope>runtime</scope> </dependency>  <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>  <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency></dependencies>

2.2 配置数据库连接

在src/main/resources/application.properties中配置PostgreSQL连接信息:

# 数据库基本信息spring.datasource.url=jdbc:postgresql://localhost:5432/mydb?currentSchema=public&sslmode=disablespring.datasource.username=postgresspring.datasource.password=your_passwordspring.datasource.driver-class-name=org.postgresql.Driver# JPA/Hibernate配置spring.jpa.hibernate.ddl-auto=update # 开发环境自动更新表结构(生产环境建议用validate)spring.jpa.show-sql=true  # 打印SQL日志(生产环境关闭)spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialectspring.jpa.properties.hibernate.format_sql=true # 格式化SQL输出# 连接池配置(HikariCP默认)spring.datasource.hikari.maximum-pool-size=20spring.datasource.hikari.minimum-idle=5spring.datasource.hikari.connection-timeout=30000spring.datasource.hikari.idle-timeout=600000

关键参数说明:

  • ddl-auto:开发环境用update(自动同步实体类与表结构),生产环境用validate(仅验证不修改)。
  • sslmode:本地开发可禁用(disable),生产环境建议启用(require或verify-ca)。

三、核心功能实现(用户管理示例)

3.1 创建实体类(User)

使用JPA注解映射PostgreSQL表,支持JSONB类型(PostgreSQL特色):

import jakarta.persistence.*;import lombok.AllArgsConstructor;import lombok.Builder;import lombok.Data;import lombok.NoArgsConstructor;import org.hibernate.annotations.Type;@Entity@Table(name = \"t_user\") // 对应PostgreSQL表名@Data@Builder@NoArgsConstructor@AllArgsConstructorpublic class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键 private Long id; @Column(nullable = false, unique = true) // 非空且唯一 private String username; @Column(nullable = false) private String password; @Column(columnDefinition = \"TEXT\") // 文本类型(适用于长文本) private String bio; // JSONB类型字段(存储结构化数据,如地址) @Type(type = \"jsonb\") // 需要hibernate-types依赖(见下文) @Column(columnDefinition = \"JSONB\") private Address address; // 嵌套实体(级联保存) @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = \"contact_info_id\", referencedColumnName = \"id\") private ContactInfo contactInfo;}// 地址实体(JSONB存储)@Data@AllArgsConstructor@NoArgsConstructorpublic class Address { private String city; private String street; private String zipcode;}// 联系信息实体(级联保存)@Data@AllArgsConstructor@NoArgsConstructorpublic class ContactInfo { private String email; private String phone;}

注意:使用@Type(type = “jsonb”)需添加hibernate-types依赖(处理JSONB类型):

<dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-52</artifactId> <version>2.24.0</version></dependency>

3.2 创建Repository接口

继承JpaRepository实现CRUD操作:

import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;@Repositorypublic interface UserRepository extends JpaRepository<User, Long> { // 自定义查询:根据用户名查找用户(忽略大小写) User findByUsernameIgnoreCase(String username); // 分页查询(Spring Data JPA自动实现) Page<User> findAll(Pageable pageable);}

3.3 创建Service层

处理业务逻辑,使用@Transactional管理事务:

import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;@Servicepublic class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } // 创建用户 @Transactional public User createUser(User user) { return userRepository.save(user); } // 根据ID查询用户 public User getUserById(Long id) { return userRepository.findById(id) .orElseThrow(() -> new RuntimeException(\"用户不存在\")); } // 分页查询所有用户 public Page<User> getAllUsers(Pageable pageable) { return userRepository.findAll(pageable); } // 更新用户信息 @Transactional public User updateUser(Long id, User updatedUser) { User existingUser = getUserById(id); existingUser.setUsername(updatedUser.getUsername()); existingUser.setPassword(updatedUser.getPassword()); existingUser.setBio(updatedUser.getBio()); existingUser.setAddress(updatedUser.getAddress()); existingUser.setContactInfo(updatedUser.getContactInfo()); return userRepository.save(existingUser); } // 删除用户 @Transactional public void deleteUser(Long id) { userRepository.deleteById(id); }}

3.4 创建Controller层

暴露RESTful API:

import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping(\"/api/users\")public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } // 创建用户 @PostMapping @ResponseStatus(HttpStatus.CREATED) public User createUser(@RequestBody User user) { return userService.createUser(user); } // 根据ID查询用户 @GetMapping(\"/{id}\") public User getUserById(@PathVariable Long id) { return userService.getUserById(id); } // 分页查询(页码从0开始,每页10条) @GetMapping public Page<User> getUsers( @RequestParam(defaultValue = \"0\") int page, @RequestParam(defaultValue = \"10\") int size) { return userService.getAllUsers(PageRequest.of(page, size)); } // 更新用户 @PutMapping(\"/{id}\") public User updateUser(@PathVariable Long id, @RequestBody User updatedUser) { return userService.updateUser(id, updatedUser); } // 删除用户 @DeleteMapping(\"/{id}\") @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteUser(@PathVariable Long id) { userService.deleteUser(id); }}

四、PostgreSQL特色功能集成

4.1 JSONB类型存储与查询

PostgreSQL的JSONB类型支持高效存储和查询JSON数据。以下是扩展操作:

(1)存储JSONB数据

上述User实体中的address字段已通过@Type(type = “jsonb”)映射为JSONB类型。保存时直接传入Address对象即可。

(2)查询JSONB字段

在UserRepository中添加自定义查询方法(使用JPQL或原生SQL):

// JPQL查询(需Hibernate 5.2+支持JSONB)@Query(\"SELECT u FROM User u WHERE u.address.city = :city\")List<User> findByAddressCity(@Param(\"city\") String city);// 原生SQL查询(复杂JSONB操作)@Query(value = \"SELECT * FROM t_user WHERE address ->> \'zipcode\' = :zipcode\", nativeQuery = true)List<User> findByZipcode(@Param(\"zipcode\") String zipcode);

4.2 时序数据存储(TimescaleDB扩展)

PostgreSQL的时序数据扩展timescaledb可用于存储IoT、监控等时序数据。集成步骤:

(1)安装TimescaleDB扩展

在PostgreSQL中执行:

CREATE EXTENSION IF NOT EXISTS timescaledb;

(2)创建时序表

@Entity@Table(name = \"t_sensor_data\")@org.hibernate.annotations.Table(appliesTo = \"t_sensor_data\", options = \"timescaledb.table_type=continuous_aggregate\")@Datapublic class SensorData { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false) private Double temperature; @Column(nullable = false) private Double humidity; @Column(nullable = false) private Instant timestamp; // 时间戳字段(必须)}

(3)使用TimeScaleRepository

public interface SensorDataRepository extends JpaRepository<SensorData, Long>, TimeScaleRepository<SensorData> { // 按时间范围查询 List<SensorData> findByTimestampBetween(Instant start, Instant end);}

五、生产环境优化

5.1 连接池调优

使用HikariCP(Spring Boot默认),在application.properties中调整参数:

spring.datasource.hikari.maximum-pool-size=20 # 最大连接数(根据CPU核心数调整)spring.datasource.hikari.minimum-idle=5 # 最小空闲连接数spring.datasource.hikari.idle-timeout=30000 # 空闲连接超时时间(30秒)spring.datasource.hikari.connection-timeout=10000 # 连接超时时间(10秒)spring.datasource.hikari.max-lifetime=1800000 # 连接最大生命周期(30分钟)

5.2 事务管理优化

  • 细粒度事务:避免在@Transactional方法中调用远程服务(如HTTP请求),防止事务过长。
  • 隔离级别:根据业务需求设置隔离级别(默认READ_COMMITTED):
@Transactional(isolation = Isolation.SERIALIZABLE) // 最高隔离级别(避免脏读、幻读)public void criticalOperation() { // 业务逻辑}

5.3 数据库迁移(Flyway)

使用Flyway管理数据库版本,避免手动执行SQL脚本。

(1)添加Flyway依赖

<dependency> <groupId>org.flywaydb</groupId> <artifactId>flyway-core</artifactId></dependency>

(2)配置Flyway

在application.properties中:

spring.flyway.enabled=true  # 启用Flywayspring.flyway.locations=classpath:db/migration # SQL脚本路径spring.flyway.schemas=public # 目标模式spring.flyway.sql-migration-prefix=V # 迁移脚本前缀(V表示版本控制)

(3)创建迁移脚本

在src/main/resources/db/migration目录下创建V1__create_user_table.sql:

-- 创建用户表CREATE TABLE IF NOT EXISTS t_user ( id SERIAL PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password VARCHAR(100) NOT NULL, bio TEXT, address JSONB, contact_info_id BIGINT, CONSTRAINT fk_contact_info FOREIGN KEY (contact_info_id) REFERENCES t_contact_info(id));-- 创建联系信息表CREATE TABLE IF NOT EXISTS t_contact_info ( id SERIAL PRIMARY KEY, email VARCHAR(100) UNIQUE, phone VARCHAR(20));

六、常见问题与解决方案

6.1 连接失败:无法连接到PostgreSQL

  • 检查端口:确保PostgreSQL监听端口(默认5432)开放,且未被防火墙拦截。
  • 验证用户名密码:确认application.properties中的username和password与数据库一致。
  • 启用远程访问:修改postgresql.conf中的listen_addresses = ‘*’,并更新pg_hba.conf允许远程连接。

6.2 JSONB字段查询报错

  • 确保Hibernate版本:使用hibernate-types-52或更高版本支持JSONB。
  • 正确映射类型:实体类中使用@Type(type = “jsonb”),并在数据库中定义columnDefinition = “JSONB”。

6.3 事务回滚不生效

  • 检查异常类型:默认仅回滚RuntimeException和Error,如需回滚检查异常,添加rollbackFor = Exception.class:
@Transactional(rollbackFor = Exception.class)public void updateOrder() throws Exception { // 业务逻辑(可能抛出检查异常)}

七、总结

通过本指南,已完成Spring Boot与PostgreSQL的深度集成,覆盖了:

  • 基础配置与依赖管理
  • 实体类映射(含JSONB类型)
  • CRUD操作与事务管理
  • 生产环境优化(连接池、迁移工具)
  • PostgreSQL特色功能(JSONB、时序数据)
    实际开发中,可根据业务需求扩展以下功能:
  • 缓存集成:使用Redis缓存高频查询数据。
  • 分布式事务:通过Seata实现跨服务事务。
  • 监控告警:集成Prometheus+Grafana监控数据库性能。
    注:生产环境需关闭show-sql,并配置SSL加密连接。