Spring Boot 接入 PostgreSQL
这一课你将能做到
- 在实验 profile 里配置
jdbc:postgresql://… 与驱动,启动时连上本地 codeforge_pg
- 用与本站类似的实体 / Mapper 风格完成一次按
slug 查询
- 列出换库时 schema、布尔、JSONB、分页四点注意,且不改动生产 MySQL 配置
为什么要学
只会 psql 不够:真实项目里 SQL 多半经 Spring Boot 发出。接入 PG 的关键是 JDBC URL + 驱动 + 方言细节;分层(Controller → Service → Mapper)可保持与本站 MySQL 版一致。
本站默认 mysql-connector-j 与 jdbc:mysql://…。本课用 独立 profile(如 pg-dev)做实验,避免误伤生产数据源。持久层示例按 MyBatis-Flex 风格(与仓库一致),也点到 JPA 方言一行配置。
先建立图像
application-pg-dev.yml
url: jdbc:postgresql://127.0.0.1:5432/codeforge_pg
driver: org.postgresql.Driver
│
▼
Hikari 连接池
│
▼
Mapper / JDBC ──SQL──► PostgreSQL
│
▼
实体 Track(Boolean、Long、String…)
| 项 | MySQL(本站) | PostgreSQL(实验) |
|---|
| URL 前缀 | jdbc:mysql:// | jdbc:postgresql:// |
| 驱动 | com.mysql.cj.jdbc.Driver | org.postgresql.Driver |
| 默认端口 | 3306 | 5432 |
| 布尔 | 常 TINYINT(1) | BOOLEAN |
| 分页 | LIMIT | LIMIT(Flex 可生成) |
跟着做
步骤 1:加依赖(实验模块或 profile)
在练习用模块的 pom.xml 增加(版本由 Spring Boot BOM 管理时可省略 <version>):
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
不要删掉生产用的 MySQL 驱动;两套并存,靠 profile 选用。
步骤 2:写 application-pg-dev.yml
spring:
datasource:
url: jdbc:postgresql://127.0.0.1:5432/codeforge_pg?currentSchema=app
username: codeforge
password: ${DB_PASSWORD:devpass}
driver-class-name: org.postgresql.Driver
currentSchema=app 让未加前缀的表名落到 app(若你的表在 app 下)。也可用 SQL 写 app.cf_track。
# 概念对照——保持 MySQL
# url: jdbc:mysql://localhost:3306/codeforge?...
# driver-class-name: com.mysql.cj.jdbc.Driver
步骤 3:确认库表已就绪
psql 中应有 app.cf_track(pg-ddl)。若空,插入至少一行。
步骤 4:实体与查询
@Data
@Table("cf_track")
public class Track {
@Id(keyType = KeyType.Auto)
private Long id;
private String slug;
private String title;
/** 对应 PG BOOLEAN;勿用 Integer 硬扛 */
private Boolean isMember;
}
// SELECT id, slug, title, is_member
// FROM cf_track WHERE slug = ?
Track findBySlug(String slug);
用单元测试或临时 CommandLineRunner 打印结果。启动:
# 概念:激活实验 profile
java -jar your-app.jar --spring.profiles.active=pg-dev
应连上 PG;失败时看 URL、容器端口、schema。
步骤 5:JSONB 与类型处理(认知)
- 简单做法:实体用
String 存 JSON 文本 + TypeHandler
- 或
Map / 自定义处理器映射 JSONB
先保证标量列跑通,再加 JSONB 字段,避免一次踩太多坑。
步骤 6:可选 JPA 方言
spring.jpa.database-platform: org.hibernate.dialect.PostgreSQLDialect
复杂报表仍建议 MyBatis 风格显式 SQL;CRUD 原型可用 JPA。
讲清楚要点
- 因为 驱动与协议不同,所以 换库不是改一个 host,而是 URL + 驱动 + SQL 方言。
- profile 隔离:
pg-dev 只用于实验;默认 profile 继续 MySQL。
- schema 要显式:
currentSchema 或限定名,避免表建在 public 却查 app。
- 自增映射:
BIGSERIAL / IDENTITY 与 KeyType.Auto 需验证插入后回填 id。
- 布尔与时间:
Boolean ↔ BOOLEAN;时间优先 timestamptz ↔ Instant/OffsetDateTime。
- 分页:
LIMIT/OFFSET 两边都常见;注意深分页性能,与引擎无关的老问题。
你可能会懵的地方
-
依赖加了仍说找不到驱动?
看运行的是否真是该模块、profile 是否生效、是否打进运行时 classpath。
-
表存在但 relation does not exist?
search_path / currentSchema 不对。\dt app.* 核对。
-
MyBatis 关键字冲突?
少数函数名差异用数据库厂商的 SQL 或抽象。先写简单 SELECT。
-
能不能双数据源同时连 MySQL 与 PG?
可以,但配置复杂,入门勿做。本课单数据源切换即可。
-
生产切 PG 要改哪些?
迁移脚本方言、类型、监控、备份;远不止 yml 一行。见选型课与迁移课。
错法对照
| 错法 | 问题 | 正解 |
|---|
直接改默认 application.yml 为 PG | 本站主线挂掉 | application-pg-dev.yml |
URL 仍写 jdbc:mysql | 连错协议 | jdbc:postgresql:// |
布尔用 Integer 映射 | 怪异转换 | Boolean |
| 忽略 schema | 找不到表 | currentSchema=app 或限定名 |
| 未启动 Docker PG 就启 Spring | 连接拒绝 | 先 docker ps 再启动应用 |
自测三问
currentSchema=app 解决什么问题?还有哪种写法能达到类似效果?
- 为什么强调 profile 而不是覆盖生产数据源?
- PG
BOOLEAN 在 Java 实体里更合理的类型是什么?
小结一句话
换驱动与 JDBC URL 即可让 Spring Boot 连上 PostgreSQL;用独立 profile 实验,分层与本站 MySQL 版保持同构。
官方延伸