diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 60fdb03..2c413ab 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -56,25 +56,23 @@ updates: update-types: ["version-update:semver-major"] - dependency-name: "gradle" update-types: ["version-update:semver-major"] - # The starter family itself ships separate release lines for SB3 - # (0.4.x) and SB4 (0.5.x+). A major bump of the easy-paging - # starter here would carry the SB3 demos into SB4 territory and - # break them (PR #40 was the first time we saw this in the wild - # — dependabot bumped to 0.5.0 across the SB3 demos and CI went - # red on all 4). Hold easy-paging majors so the SB3 demos stay - # on the 0.4.x line that matches their Spring Boot pin. + # devslab-kr libraries follow the Spring-major-aligned versioning + # policy: library major matches the Spring Boot major it targets + # (https://github.com/devslab-kr/.github/blob/main/.github/VERSIONING.md). + # So `semver-major` does the right thing for the SB3 demos here: + # easy-paging 3.x stays on 3.x, ssrf-guard 3.x stays on 3.x. A + # future easy-paging 4.x / ssrf-guard 4.x release (SB4) is a + # major bump and gets held — exactly the behaviour we want for + # SB3-pinned demos. # - # Because the starter is pre-1.0, 0.4 → 0.5 reads to Dependabot - # as a *minor* bump but is actually the SB3 → SB4 release-line - # jump. The semver-major ignore alone isn't enough — PR #50 - # (2026-05-23) snuck through it. Pin "< 0.5" explicitly via the - # versions: filter so 0.4.x patches still flow but 0.5+ doesn't. + # (Pre-renumber, easy-paging was on 0.4.x / 0.5.x and Dependabot + # read 0.4 → 0.5 as a *minor*, sneaking past the major ignore + # — see PR #50, 2026-05-23. The renumber to aligned majors made + # the explicit `versions: [">= 0.5"]` filter unnecessary.) - dependency-name: "kr.devslab:easy-paging-spring-boot-starter" - versions: [">= 0.5"] + update-types: ["version-update:semver-major"] - dependency-name: "kr.devslab:easy-paging-spring-boot-starter-reactive" - versions: [">= 0.5"] - # Same shape applies to ssrf-guard's hypothetical SB4-only major - # release, if/when it ships — guard against it in advance. + update-types: ["version-update:semver-major"] - dependency-name: "kr.devslab:ssrf-guard" update-types: ["version-update:semver-major"] - dependency-name: "kr.devslab:ssrf-guard-*" diff --git a/README.ko.md b/README.ko.md index b501395..19894c0 100644 --- a/README.ko.md +++ b/README.ko.md @@ -16,10 +16,10 @@ | 데모 | 보여주는 것 | Maven Central 좌표 | | --- | --- | --- | -| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot 4 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | `@KeysetPaginate` 커서(keyset) 페이지네이션 — composite `(time, id)` 키, 쓰기 중에도 안정, `OFFSET`/`COUNT(*)` 없음 | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | 동일 스타터를 **실제 PostgreSQL**과 — `bootRun`은 Docker Compose, 테스트는 Testcontainers + `@ServiceConnection`, 로컬 DB 설치 불필요 | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive 스택 — **WebFlux + R2DBC**, `R2dbcOffsetPagingSupport` 사용. MVC 데모와 동일한 JSON 봉투를 `Mono>`로 서빙 | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | +| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot 4 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | `@KeysetPaginate` 커서(keyset) 페이지네이션 — composite `(time, id)` 키, 쓰기 중에도 안정, `OFFSET`/`COUNT(*)` 없음 | [`kr.devslab:easy-paging-spring-boot-starter:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | 동일 스타터를 **실제 PostgreSQL**과 — `bootRun`은 Docker Compose, 테스트는 Testcontainers + `@ServiceConnection`, 로컬 DB 설치 불필요 | [`kr.devslab:easy-paging-spring-boot-starter:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive 스택 — **WebFlux + R2DBC**, `R2dbcOffsetPagingSupport` 사용. MVC 데모와 동일한 JSON 봉투를 `Mono>`로 서빙 | [`kr.devslab:easy-paging-spring-boot-starter-reactive:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | ### easy-paging — Spring Boot 3 maintenance (`0.4.x` 라인) @@ -27,10 +27,10 @@ Spring Boot 3.3–3.5 사용 중인 앱용. 스타터의 [`0.4.x` 브랜치](htt | 데모 | 보여주는 것 | Maven Central 좌표 | | --- | --- | --- | -| [`easy-paging-demo`](easy-paging-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot 3 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | `@KeysetPaginate` 커서 페이지네이션 | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | 실제 PostgreSQL 사용 | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive 스택 — WebFlux + R2DBC | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | +| [`easy-paging-demo`](easy-paging-demo/) | `@AutoPaginate` 어노테이션 기반 offset 페이지네이션 (Spring Boot 3 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | `@KeysetPaginate` 커서 페이지네이션 | [`kr.devslab:easy-paging-spring-boot-starter:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | 실제 PostgreSQL 사용 | [`kr.devslab:easy-paging-spring-boot-starter:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive 스택 — WebFlux + R2DBC | [`kr.devslab:easy-paging-spring-boot-starter-reactive:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | ### ssrf-guard diff --git a/README.md b/README.md index 092953f..36ca142 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,10 @@ Latest active line. Use these if your app is on Spring Boot 4+. | Demo | Showcases | Maven Central coordinates | | --- | --- | --- | -| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 4 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` — composite `(time, id)` key, stable under writes, no `OFFSET`/`COUNT(*)` | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | Same starter against **real PostgreSQL** — Docker Compose for `bootRun`, Testcontainers + `@ServiceConnection` for tests, no local DB install | [`kr.devslab:easy-paging-spring-boot-starter:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive stack — **WebFlux + R2DBC** via `R2dbcOffsetPagingSupport`. Same JSON envelope as the MVC demos, served as `Mono>` | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.5.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | +| [`easy-paging-sb4-demo`](easy-paging-sb4-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 4 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-sb4-keyset-demo`](easy-paging-sb4-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` — composite `(time, id)` key, stable under writes, no `OFFSET`/`COUNT(*)` | [`kr.devslab:easy-paging-spring-boot-starter:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-sb4-postgres-demo`](easy-paging-sb4-postgres-demo/) | Same starter against **real PostgreSQL** — Docker Compose for `bootRun`, Testcontainers + `@ServiceConnection` for tests, no local DB install | [`kr.devslab:easy-paging-spring-boot-starter:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-sb4-reactive-demo`](easy-paging-sb4-reactive-demo/) | Reactive stack — **WebFlux + R2DBC** via `R2dbcOffsetPagingSupport`. Same JSON envelope as the MVC demos, served as `Mono>` | [`kr.devslab:easy-paging-spring-boot-starter-reactive:4.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | ### easy-paging — Spring Boot 3 maintenance (`0.4.x` line) @@ -27,10 +27,10 @@ For apps still on Spring Boot 3.3–3.5. The starter's [`0.4.x` branch](https:// | Demo | Showcases | Maven Central coordinates | | --- | --- | --- | -| [`easy-paging-demo`](easy-paging-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 3 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | Same starter against real PostgreSQL | [`kr.devslab:easy-paging-spring-boot-starter:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | -| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive stack — WebFlux + R2DBC | [`kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | +| [`easy-paging-demo`](easy-paging-demo/) | Annotation-driven offset pagination with `@AutoPaginate` (Spring Boot 3 + MyBatis + H2) | [`kr.devslab:easy-paging-spring-boot-starter:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-keyset-demo`](easy-paging-keyset-demo/) | Cursor (keyset) pagination with `@KeysetPaginate` | [`kr.devslab:easy-paging-spring-boot-starter:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-postgres-demo`](easy-paging-postgres-demo/) | Same starter against real PostgreSQL | [`kr.devslab:easy-paging-spring-boot-starter:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter) | +| [`easy-paging-reactive-demo`](easy-paging-reactive-demo/) | Reactive stack — WebFlux + R2DBC | [`kr.devslab:easy-paging-spring-boot-starter-reactive:3.0.0`](https://central.sonatype.com/artifact/kr.devslab/easy-paging-spring-boot-starter-reactive) | ### ssrf-guard diff --git a/easy-paging-demo/README.ko.md b/easy-paging-demo/README.ko.md index 6a4fba6..1cc2293 100644 --- a/easy-paging-demo/README.ko.md +++ b/easy-paging-demo/README.ko.md @@ -71,7 +71,7 @@ curl 'http://localhost:8080/reports?page=999&size=20' | jq '.page, .empty' | 파일 | 왜 | | --- | --- | -| `build.gradle.kts` | `spring-boot-starter-web` 외 추가하는 의존성은 `kr.devslab:easy-paging-spring-boot-starter:0.4.0` 하나뿐 | +| `build.gradle.kts` | `spring-boot-starter-web` 외 추가하는 의존성은 `kr.devslab:easy-paging-spring-boot-starter:3.0.0` 하나뿐 | | `report/ReportController.java` | 전체 페이지네이션 계약은 `@AutoPaginate(maxSize = 50)` 어노테이션 + `PageResponse` 반환 타입 | | `report/ReportMapper.java` + `resources/mapper/ReportMapper.xml` | 평범한 `SELECT` — `LIMIT`, `OFFSET`, `COUNT` 모두 없음. 런타임에 aspect가 주입 | | `resources/application.yml` | `easy-paging` 전역 cap + 기본값 | diff --git a/easy-paging-demo/README.md b/easy-paging-demo/README.md index 51fcf3d..6bc5a4b 100644 --- a/easy-paging-demo/README.md +++ b/easy-paging-demo/README.md @@ -71,7 +71,7 @@ The interesting parts, in order: | File | Why | | --- | --- | -| `build.gradle.kts` | the only dependency the demo adds beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:0.4.0` | +| `build.gradle.kts` | the only dependency the demo adds beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:3.0.0` | | `report/ReportController.java` | the entire pagination contract is the `@AutoPaginate(maxSize = 50)` annotation and the `PageResponse` return type | | `report/ReportMapper.java` + `resources/mapper/ReportMapper.xml` | plain `SELECT` — no `LIMIT`, no `OFFSET`, no `COUNT`. The aspect injects all of that at runtime | | `resources/application.yml` | `easy-paging` global caps and defaults | diff --git a/easy-paging-demo/build.gradle.kts b/easy-paging-demo/build.gradle.kts index 0730124..1b891e1 100644 --- a/easy-paging-demo/build.gradle.kts +++ b/easy-paging-demo/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") // The library this demo showcases. Bumped by Dependabot on new releases. - implementation("kr.devslab:easy-paging-spring-boot-starter:0.4.0") + implementation("kr.devslab:easy-paging-spring-boot-starter:3.0.0") // H2 in-memory database — keeps the demo self-contained (no external DB). runtimeOnly("com.h2database:h2") diff --git a/easy-paging-keyset-demo/README.ko.md b/easy-paging-keyset-demo/README.ko.md index 5285146..bc1b416 100644 --- a/easy-paging-keyset-demo/README.ko.md +++ b/easy-paging-keyset-demo/README.ko.md @@ -87,7 +87,7 @@ EASY_PAGING_CURSOR_SECRET='a-long-random-string-from-your-secrets-manager' ./gra | 파일 | 왜 | | --- | --- | -| `build.gradle.kts` | `spring-boot-starter-web` 외 추가 의존성은 `kr.devslab:easy-paging-spring-boot-starter:0.4.0` (offset 데모와 동일) | +| `build.gradle.kts` | `spring-boot-starter-web` 외 추가 의존성은 `kr.devslab:easy-paging-spring-boot-starter:3.0.0` (offset 데모와 동일) | | `location/LocationController.java` | 계약: `@KeysetPaginate(keys = {"time", "id"}, ...)` + 스타터가 자동 resolve하는 `KeysetRequest` 파라미터 | | `location/LocationService.java` | **size + 1** 트릭 (매퍼가 한 행 더 가져와서 `KeysetPage.build`가 `hasNext`를 정확히 설정) + 다음 커서가 되는 `keyExtractor` 람다 | | `location/LocationMapper.java` + `resources/mapper/LocationMapper.xml` | 복합 키 seek predicate — `time < ? OR (time = ? AND id < ?)`. 타임스탬프가 겹쳐도 walk를 안정적으로 만드는 핵심 | diff --git a/easy-paging-keyset-demo/README.md b/easy-paging-keyset-demo/README.md index 75448d4..f48bee4 100644 --- a/easy-paging-keyset-demo/README.md +++ b/easy-paging-keyset-demo/README.md @@ -87,7 +87,7 @@ Signed cursors look the same in normal use, but become `.` and an | File | Why | | --- | --- | -| `build.gradle.kts` | the only dependency added beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:0.4.0` (same as the offset demo) | +| `build.gradle.kts` | the only dependency added beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:3.0.0` (same as the offset demo) | | `location/LocationController.java` | the contract: `@KeysetPaginate(keys = {"time", "id"}, ...)` plus a `KeysetRequest` parameter resolved automatically by the starter | | `location/LocationService.java` | shows the **size + 1** trick (mapper fetches one extra row so `KeysetPage.build` can set `hasNext` correctly) and the `keyExtractor` lambda that becomes the next cursor | | `location/LocationMapper.java` + `resources/mapper/LocationMapper.xml` | the composite-key seek predicate — `time < ? OR (time = ? AND id < ?)` is what makes the walk stable when timestamps collide | diff --git a/easy-paging-keyset-demo/build.gradle.kts b/easy-paging-keyset-demo/build.gradle.kts index 030ffbd..9c8cd9a 100644 --- a/easy-paging-keyset-demo/build.gradle.kts +++ b/easy-paging-keyset-demo/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") // The library this demo showcases. Bumped by Dependabot on new releases. - implementation("kr.devslab:easy-paging-spring-boot-starter:0.4.0") + implementation("kr.devslab:easy-paging-spring-boot-starter:3.0.0") // H2 in-memory database — keeps the demo self-contained (no external DB). // Keyset pagination doesn't need a "real" DB to demonstrate; the SQL pattern diff --git a/easy-paging-postgres-demo/build.gradle.kts b/easy-paging-postgres-demo/build.gradle.kts index de3f2c0..9f39a63 100644 --- a/easy-paging-postgres-demo/build.gradle.kts +++ b/easy-paging-postgres-demo/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") // The library this demo showcases. Bumped by Dependabot on new releases. - implementation("kr.devslab:easy-paging-spring-boot-starter:0.4.0") + implementation("kr.devslab:easy-paging-spring-boot-starter:3.0.0") // Real PostgreSQL JDBC driver — the whole point of this demo over the H2 one // is "does the starter actually work against a production DB?". (Spoiler: yes, diff --git a/easy-paging-reactive-demo/build.gradle.kts b/easy-paging-reactive-demo/build.gradle.kts index ae82f39..d175345 100644 --- a/easy-paging-reactive-demo/build.gradle.kts +++ b/easy-paging-reactive-demo/build.gradle.kts @@ -30,7 +30,7 @@ dependencies { // the core starter (kr.devslab:easy-paging-spring-boot-starter) transitively // via `api(project(":core"))` so PageResponse/Pageable/etc. are available // without an explicit dependency on it. - implementation("kr.devslab:easy-paging-spring-boot-starter-reactive:0.4.0") + implementation("kr.devslab:easy-paging-spring-boot-starter-reactive:3.0.0") // Real PostgreSQL R2DBC driver. runtimeOnly("org.postgresql:r2dbc-postgresql") diff --git a/easy-paging-sb4-demo/README.ko.md b/easy-paging-sb4-demo/README.ko.md index 8375448..78bd70c 100644 --- a/easy-paging-sb4-demo/README.ko.md +++ b/easy-paging-sb4-demo/README.ko.md @@ -73,7 +73,7 @@ curl 'http://localhost:8080/reports?page=999&size=20' | jq '.page, .empty' | 파일 | 왜 | | --- | --- | -| `build.gradle.kts` | `spring-boot-starter-web` 외 추가하는 의존성은 `kr.devslab:easy-paging-spring-boot-starter:0.5.0` 하나뿐 | +| `build.gradle.kts` | `spring-boot-starter-web` 외 추가하는 의존성은 `kr.devslab:easy-paging-spring-boot-starter:4.0.0` 하나뿐 | | `report/ReportController.java` | 전체 페이지네이션 계약은 `@AutoPaginate(maxSize = 50)` 어노테이션 + `PageResponse` 반환 타입 | | `report/ReportMapper.java` + `resources/mapper/ReportMapper.xml` | 평범한 `SELECT` — `LIMIT`, `OFFSET`, `COUNT` 모두 없음. 런타임에 aspect가 주입 | | `resources/application.yml` | `easy-paging` 전역 cap + 기본값 | diff --git a/easy-paging-sb4-demo/README.md b/easy-paging-sb4-demo/README.md index b7038cd..987faf3 100644 --- a/easy-paging-sb4-demo/README.md +++ b/easy-paging-sb4-demo/README.md @@ -73,7 +73,7 @@ The interesting parts, in order: | File | Why | | --- | --- | -| `build.gradle.kts` | the only dependency the demo adds beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:0.5.0` | +| `build.gradle.kts` | the only dependency the demo adds beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:4.0.0` | | `report/ReportController.java` | the entire pagination contract is the `@AutoPaginate(maxSize = 50)` annotation and the `PageResponse` return type | | `report/ReportMapper.java` + `resources/mapper/ReportMapper.xml` | plain `SELECT` — no `LIMIT`, no `OFFSET`, no `COUNT`. The aspect injects all of that at runtime | | `resources/application.yml` | `easy-paging` global caps and defaults | diff --git a/easy-paging-sb4-demo/build.gradle.kts b/easy-paging-sb4-demo/build.gradle.kts index 506e5d3..d0b0886 100644 --- a/easy-paging-sb4-demo/build.gradle.kts +++ b/easy-paging-sb4-demo/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") // The library this demo showcases. Bumped by Dependabot on new releases. - implementation("kr.devslab:easy-paging-spring-boot-starter:0.5.0") + implementation("kr.devslab:easy-paging-spring-boot-starter:4.0.0") // H2 in-memory database — keeps the demo self-contained (no external DB). runtimeOnly("com.h2database:h2") diff --git a/easy-paging-sb4-keyset-demo/README.ko.md b/easy-paging-sb4-keyset-demo/README.ko.md index b298b7e..618e806 100644 --- a/easy-paging-sb4-keyset-demo/README.ko.md +++ b/easy-paging-sb4-keyset-demo/README.ko.md @@ -89,7 +89,7 @@ EASY_PAGING_CURSOR_SECRET='a-long-random-string-from-your-secrets-manager' ./gra | 파일 | 왜 | | --- | --- | -| `build.gradle.kts` | `spring-boot-starter-web` 외 추가 의존성은 `kr.devslab:easy-paging-spring-boot-starter:0.5.0` (offset 데모와 동일) | +| `build.gradle.kts` | `spring-boot-starter-web` 외 추가 의존성은 `kr.devslab:easy-paging-spring-boot-starter:4.0.0` (offset 데모와 동일) | | `location/LocationController.java` | 계약: `@KeysetPaginate(keys = {"time", "id"}, ...)` + 스타터가 자동 resolve하는 `KeysetRequest` 파라미터 | | `location/LocationService.java` | **size + 1** 트릭 (매퍼가 한 행 더 가져와서 `KeysetPage.build`가 `hasNext`를 정확히 설정) + 다음 커서가 되는 `keyExtractor` 람다 | | `location/LocationMapper.java` + `resources/mapper/LocationMapper.xml` | 복합 키 seek predicate — `time < ? OR (time = ? AND id < ?)`. 타임스탬프가 겹쳐도 walk를 안정적으로 만드는 핵심 | diff --git a/easy-paging-sb4-keyset-demo/README.md b/easy-paging-sb4-keyset-demo/README.md index 370ca00..ca059d9 100644 --- a/easy-paging-sb4-keyset-demo/README.md +++ b/easy-paging-sb4-keyset-demo/README.md @@ -89,7 +89,7 @@ Signed cursors look the same in normal use, but become `.` and an | File | Why | | --- | --- | -| `build.gradle.kts` | the only dependency added beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:0.5.0` (same as the offset demo) | +| `build.gradle.kts` | the only dependency added beyond `spring-boot-starter-web` is `kr.devslab:easy-paging-spring-boot-starter:4.0.0` (same as the offset demo) | | `location/LocationController.java` | the contract: `@KeysetPaginate(keys = {"time", "id"}, ...)` plus a `KeysetRequest` parameter resolved automatically by the starter | | `location/LocationService.java` | shows the **size + 1** trick (mapper fetches one extra row so `KeysetPage.build` can set `hasNext` correctly) and the `keyExtractor` lambda that becomes the next cursor | | `location/LocationMapper.java` + `resources/mapper/LocationMapper.xml` | the composite-key seek predicate — `time < ? OR (time = ? AND id < ?)` is what makes the walk stable when timestamps collide | diff --git a/easy-paging-sb4-keyset-demo/build.gradle.kts b/easy-paging-sb4-keyset-demo/build.gradle.kts index 088d5d7..8f66b2b 100644 --- a/easy-paging-sb4-keyset-demo/build.gradle.kts +++ b/easy-paging-sb4-keyset-demo/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") // The library this demo showcases. Bumped by Dependabot on new releases. - implementation("kr.devslab:easy-paging-spring-boot-starter:0.5.0") + implementation("kr.devslab:easy-paging-spring-boot-starter:4.0.0") // H2 in-memory database — keeps the demo self-contained (no external DB). // Keyset pagination doesn't need a "real" DB to demonstrate; the SQL pattern diff --git a/easy-paging-sb4-postgres-demo/build.gradle.kts b/easy-paging-sb4-postgres-demo/build.gradle.kts index 840781e..627125d 100644 --- a/easy-paging-sb4-postgres-demo/build.gradle.kts +++ b/easy-paging-sb4-postgres-demo/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("org.springframework.boot:spring-boot-starter-web") // The library this demo showcases. Bumped by Dependabot on new releases. - implementation("kr.devslab:easy-paging-spring-boot-starter:0.5.0") + implementation("kr.devslab:easy-paging-spring-boot-starter:4.0.0") // Real PostgreSQL JDBC driver — the whole point of this demo over the H2 one // is "does the starter actually work against a production DB?". (Spoiler: yes, diff --git a/easy-paging-sb4-reactive-demo/build.gradle.kts b/easy-paging-sb4-reactive-demo/build.gradle.kts index 5f76247..8886027 100644 --- a/easy-paging-sb4-reactive-demo/build.gradle.kts +++ b/easy-paging-sb4-reactive-demo/build.gradle.kts @@ -30,7 +30,7 @@ dependencies { // the core starter (kr.devslab:easy-paging-spring-boot-starter) transitively // via `api(project(":core"))` so PageResponse/Pageable/etc. are available // without an explicit dependency on it. - implementation("kr.devslab:easy-paging-spring-boot-starter-reactive:0.5.0") + implementation("kr.devslab:easy-paging-spring-boot-starter-reactive:4.0.0") // Real PostgreSQL R2DBC driver. runtimeOnly("org.postgresql:r2dbc-postgresql")