Jinx는 컴파일 타임에 JPA 애노테이션을 분석하여
**스키마 스냅샷(JSON)**을 생성하고,
스냅샷 간 차이를 비교해 DDL SQL을 자동으로 생성하는 도구입니다.
Liquibase YAML도 출력 포맷 중 하나로 지원하지만,
SQL이 주력이며 가장 많이 검증된 출력 결과입니다.
MySQL & PostgreSQL | JDK 21+ 필요 | 최신 버전: 0.1.4 | JPA 3.2.0 지원
Jinx는 데이터베이스 스키마 변경을
명시적이고, 검수 가능하며, 자동화 친화적으로 만들기 위해 존재합니다.
DDL을 직접 작성하지 않고 JPA 메타데이터에서 생성합니다.
오타, 누락된 컬럼, 잘못된 제약 조건이 운영 환경으로 가는 것을 막습니다.
Jinx는 사람이 읽을 수 있는 순수 SQL 파일을 생성합니다.
스키마 변경 역시 애플리케이션 코드처럼 리뷰와 승인 과정을 거칠 수 있습니다.
결과물이 SQL 파일이기 때문에
별도의 런타임 도구 없이 기존 CI/CD 흐름에 쉽게 포함할 수 있습니다.
실제 데이터베이스 연결도 필요하지 않습니다.
스키마 분석과 diff는 스냅샷 파일만으로 수행됩니다.
로컬이나 CI 환경에서 DB 없이도 마이그레이션을 생성·검증할 수 있습니다.
생성된 SQL 파일을 Git에 커밋하면
Git 자체가 스키마 변경 이력이 됩니다.
추가적인 마이그레이션 런타임 도입이 부담스럽다면,
Jinx + Git만으로도 충분히 추적 가능한 구조를 만들 수 있습니다.
Jinx는 애노테이션 프로세싱 기반으로
컴파일 타임에 스키마를 분석합니다.
런타임 리플렉션에 의존하지 않으며,
리플렉션 기반 JPA 표준 모델을 그대로 따르지 않습니다.
이는 의도적인 선택입니다.
- 결정적이고 재현 가능한 스키마 생성
- 런타임 메타데이터 요구사항 제거
- AOT 지향 빌드 파이프라인과의 높은 궁합
자바 생태계가 점점 리플렉션 사용을 줄이는 방향으로 가는 상황에서,
Jinx는 자연스럽게 장기적인 빌드 환경 변화에 대응합니다.
Jinx는 Hibernate와 같은 JPA 런타임을 대체하지 않습니다.
스키마 분석과 마이그레이션 생성에만 집중합니다.
DDL SQL은 Jinx의 1급 출력 포맷이며
가장 많은 테스트와 검증이 이루어집니다.
Liquibase를 이미 사용 중인 팀을 위해
호환 가능한 출력 포맷으로 제공됩니다.
Liquibase는 핵심 모델이 아니라
SQL 생성 결과를 변환한 표현 방식 중 하나입니다.
dependencies {
annotationProcessor("io.github.yyubin:jinx-processor:0.1.4")
implementation("io.github.yyubin:jinx-core:0.1.4")
}@Entity
public class Bird {
@Id @GeneratedValue
private Long id;
private String name;
private Long zooId;
}컴파일 시 자동으로 생성됩니다.
build/classes/java/main/jinx/
파일 이름 형식:
schema-<yyyyMMddHHmmss>.json
jinx db migrate \
-p build/classes/java/main/jinx \
-d mysql \
--out build/jinx \
--rollback \
--liquibase# PostgreSQL (Gradle 플러그인 경유 권장)
jinx db migrate \
-p build/classes/java/main/jinx \
-d postgresql \
--out build/jinx \
--rollback참고: CLI에서 PostgreSQL을 직접 사용하는 것은 현재 제한적으로 지원됩니다. PostgreSQL 프로젝트에는 Gradle 플러그인을 통해
dialect.set("postgresql")을 설정하는 방법을 권장합니다.
plugins {
id("io.github.yyubin.jinx") version "0.1.4"
}jinx {
profile.set("local")
naming {
maxLength.set(63)
strategy.set("SNAKE_CASE")
}
database {
dialect.set("mysql")
}
output {
format.set("sql")
directory.set("build/jinx")
}
}PostgreSQL을 사용하려면:
database {
dialect.set("postgresql") // 또는 "mysql"
}설정은 다음 순서로 적용됩니다 (위가 더 높은 우선순위):
Gradle DSL / -A 컴파일러 옵션 > jinx.yaml > 기본값
프로젝트 루트에 jinx.yaml을 생성합니다. 작업 디렉토리에서 상위 디렉토리로 순차 탐색하므로, 저장소 루트에 두면 모든 서브프로젝트에 적용됩니다.
profiles:
dev:
naming:
maxLength: 30
strategy: NO_OP
prod:
naming:
maxLength: 63
strategy: SNAKE_CASE프로파일 활성화 (우선순위 순):
- Gradle DSL:
profile.set("prod") - 환경변수:
JINX_PROFILE=prod - 기본값:
dev
제약 조건·인덱스명 생성 시 적용할 최대 길이입니다.
| 기본값 | 권장값 |
|---|---|
30 |
PostgreSQL: 63 / MySQL: 64 |
Java 필드명·클래스명을 DB 물리 컬럼명으로 변환하는 방식을 지정합니다.
| 값 | 동작 | 예시 |
|---|---|---|
NO_OP |
변환 없이 그대로 사용 (기본값) | myColumn → myColumn |
SNAKE_CASE |
camelCase → snake_case 변환 | myColumn → my_column |
jinx {
profile.set("prod")
naming {
maxLength.set(63)
strategy.set("SNAKE_CASE")
}
}Gradle DSL 값은 jinx.yaml보다 우선 적용됩니다. 플러그인이 -A 컴파일러 인자로 자동 변환해 전달합니다.
Gradle 플러그인 없이 Annotation Processor를 직접 사용하는 경우:
compileJava {
options.compilerArgs += [
'-Ajinx.naming.maxLength=63',
'-Ajinx.naming.strategy=SNAKE_CASE',
'-Ajinx.profile=prod'
]
}| 키 | 설명 |
|---|---|
jinx.naming.maxLength |
제약 조건·인덱스명 최대 길이 |
jinx.naming.strategy |
네이밍 전략 (NO_OP 또는 SNAKE_CASE) |
jinx.profile |
jinx.yaml 프로파일 지정 |
| 옵션 | 설명 |
|---|---|
db migrate |
스냅샷 diff 기반 SQL 생성 |
promote-baseline |
현재 스냅샷을 기준선으로 승격 |
-d, --dialect |
데이터베이스 방언 (mysql, postgresql) |
--rollback |
롤백 SQL 생성 |
--liquibase |
Liquibase YAML 출력 |
--force |
파괴적 변경 허용 |
여러 테이블을 한 번에 추가하거나 삭제할 때, Jinx는 외래 키 의존성을 기반으로 위상정렬을 수행해 올바른 실행 순서를 자동으로 결정합니다.
수동으로 순서를 지정할 필요가 없습니다. Jinx가 FK 그래프를 분석해 코드에서 엔티티가 등장하는 순서와 무관하게 올바른 CREATE/DROP 문을 생성합니다.
| 작업 | 순서 |
|---|---|
CREATE TABLE |
부모 테이블 → 자식 테이블 |
DROP TABLE |
자식 테이블(FK 보유) → 부모 테이블 |
지원하는 구조:
- 선형 체인:
A → B → C - 다이아몬드:
A → C,B → C - 조인 테이블:
AB → A,AB → B - 복수의 독립 트리
순환 FK가 감지되면 경고를 출력하고 원본 순서를 안전하게 유지합니다.
- 테이블 / 컬럼 / PK / 인덱스 / 제약 조건 diff
- FK 의존성 기반 테이블 순서 결정 — 외래 키 그래프를 분석해 CREATE/DROP 순서를 자동으로 결정
- 롤백 SQL 생성
- Liquibase YAML 출력
- MySQL 방언 (기본값)
- PostgreSQL 방언 — 큰따옴표 식별자, BIGSERIAL/SERIAL, SEQUENCE,
BOOLEAN,uuid,BYTEA,DOUBLE PRECISION,TIMESTAMP WITH TIME ZONE
https://github.com/yyubin/jinx-test
- 새로운 DB 방언 추가
- DDL / Liquibase 매핑 개선
- 테스트 및 문서 보강
PR과 이슈는 언제든 환영합니다.