Danh mục:
Tài liệu này tổng hợp các thiết lập hữu ích và mẹo khi sử dụng R2DBC kết hợp với PostgreSQL trong Spring Boot.
Thiết lập Dependencies (Gradle)
plugins {
id("org.springframework.boot") version "3.2.5"
id("io.spring.dependency-management") version "1.1.4"
kotlin("jvm") version "1.9.23"
}
// ...
dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-r2dbc")
implementation("io.r2dbc:r2dbc-postgresql")
// runtimeOnly("org.postgresql:postgresql") // Cần nếu dùng Flyway hoặc công cụ JDBC
}
Cấu hình application.yml mẫu
spring:
r2dbc:
url: r2dbc:postgresql://localhost:5432/dummy
username: devuser
password: devpass
pool:
enabled: true
initial-size: 5
max-size: 20
max-idle-time: 30s
max-create-connection-time: 5s
validation-query: SELECT 1
properties:
connectTimeout: PT15S
ssl: false
maxCreateConnectionTime: PT3S
maxAcquireTime: PT10S
maxLifeTime: PT300S
Ví dụ sử dụng R2dbcEntityTemplate
Criteria API
val criteria = Criteria.where("name").like("%test%") template.select<DummyEntity>() .matching(Query.query(criteria)) .all() .collectList()
Truy vấn phức hợp
val query = Query .query(Criteria.where("name").like("%test%")) .limit(10) .sort(Sort.by("id").descending()) template.select<DummyEntity>() .matching(query) .all()
Binding tham số trực tiếp với DatabaseClient
template.databaseClient
.sql("SELECT * FROM dummy WHERE name like %:name%")
.bind("name", "test")
.map { row -> row.get("name", String::class.java) }
.first()
Kích hoạt Log truy vấn
logging:
level:
org.springframework.r2dbc.core: DEBUG
io.r2dbc.spi: DEBUG # Bỏ ghi chú nếu muốn xem query và query-param
io.r2dbc.postgresql.QUERY: DEBUG
io.r2dbc.postgresql.PARAM: DEBUG
Testcontainers + Liên kết SQL khởi tạo PostgreSQL
object TestPostgresContainer { @Container val container = PostgreSQLContainer("postgres:15").apply { withDatabaseName("dummy_db") withUsername("devuser") withPassword("devpass") withInitScript("sql/init.sql") // đường dẫn: src/test/resources/sql/init.sql start() } }
class TestPostgresInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> { override fun initialize(context: ConfigurableApplicationContext) { val c = TestPostgresContainer.container val props = mapOf( "spring.r2dbc.url" to "r2dbc:postgresql://:/", "spring.r2dbc.username" to c.username, "spring.r2dbc.password" to c.password, "spring.datasource.url" to c.jdbcUrl, "spring.datasource.username" to c.username, "spring.datasource.password" to c.password ) context.environment.propertySources.addFirst(MapPropertySource("testcontainers", props)) } }
Thiết lập Docker Compose cho PostgreSQL & pgAdmin
file docker-compose.yml
version: '3.8' services: postgres: image: postgres:15 container_name: r2dbc_postgres restart: unless-stopped ports: - "25432:5432" environment: POSTGRES_USER: devuser POSTGRES_PASSWORD: devpass POSTGRES_DB: dummy volumes: - postgres_data:/var/lib/postgresql/data - ./initdb:/docker-entrypoint-initdb.d pgadmin: image: dpage/pgadmin4 container_name: pgadmin restart: unless-stopped ports: - "38080:80" environment: PGADMIN_DEFAULT_EMAIL: admin@local.com PGADMIN_DEFAULT_PASSWORD: admin123 PGADMIN_CONFIG_SERVER_MODE: 'False' volumes: - pgadmin_data:/var/lib/pgadmin - ./pgadmin/servers.json:/pgadmin4/servers.json - ./pgadmin/.pgpass:/pgadmin4/.pgpass depends_on: - postgres volumes: postgres_data: pgadmin_data:
file .pgpass (Đặt trong thư mục pgadmin)
postgres:5432:dummy:devuser:devpass
file servers.json (Đặt trong thư mục pgadmin)
{
"Servers": {
"1": {
"Name": "dummy-db",
"Group": "Servers",
"Host": "postgres",
"Port": 5432,
"MaintenanceDB": "dummy",
"Username": "devuser",
"SSLMode": "prefer",
"PassFile": ".pgpass"
}
}
}
Các lưu ý khác
Phiên bản
r2dbc-postgresql thường được quản lý tự động bởi Spring Boot BOM. Nếu không tự động tải được, bạn có thể chỉ định phiên bản cụ thể từ Maven Central.Nguồn bài viết ryukato.github.io