JPAExpressions)JPAExpressions 유틸리티 클래스를 사용하여 SELECT, WHERE, HAVING 절 등에서 서브쿼리를 작성할 수 있습니다.
주요 사용 사례:
특정 그룹 평균 나이보다 많은 아이돌 조회 (WHERE 절):
// 르세라핌 평균 나이보다 많은 아이돌 조회
List<Idol> result = factory.selectFrom(idol)
.where(idol.age.gt(
JPAExpressions.select(idol.age.avg()).from(idol)
.where(idol.group.groupName.eq("르세라핌"))
)).fetch();
그룹이 존재하지 않는 아이돌 조회 (NOT EXISTS):
List<Idol> result = factory.selectFrom(idol)
.where(JPAExpressions.select(group.id)
.from(group)
.where(group.id.eq(idol.group.id))
.notExists()
).fetch();
특정 연도에 앨범을 2개 이상 발매한 그룹 조회 (IN + HAVING):
// 2022년에 앨범을 2개 이상 발매한 그룹 ID 조회 서브쿼리
JPQLQuery<Long> subQuery = JPAExpressions
.select(subAlbum.group.id).from(subAlbum)
.where(subAlbum.releaseYear.eq(2022))
.groupBy(subAlbum.group.id)
.having(subAlbum.count().goe(2L));
// 메인 쿼리에서 해당 그룹들 조회
List<Group> result = factory.selectFrom(group)
.where(group.id.in(subQuery))
.fetch();
BooleanBuilder & OrderSpecifier)동적 조건 (BooleanBuilder):
BooleanBuilder 객체에 if 문을 사용하여 조건이 존재할 경우에만 .and() 메서드로 쿼리 조건을 추가합니다.BooleanBuilder builder = new BooleanBuilder();
if (name != null) builder.and(idol.idolName.eq(name));
if (minAge != null) builder.and(idol.age.goe(minAge));
List<Idol> result = factory.selectFrom(idol).where(builder).fetch();
동적 정렬 (OrderSpecifier):
switch 문이나 if 문을 사용하여 정렬 기준(sortBy)과 방향(ascending)에 따라 적절한 OrderSpecifier를 생성합니다.OrderSpecifier<?> specifier = switch (sortBy) {
case "age" -> ascending ? idol.age.asc() : idol.age.desc();
case "idolName" -> ascending ? idol.idolName.asc() : idol.idolName.desc();
default -> idol.id.asc(); // 기본 정렬
};
List<Idol> result = factory.selectFrom(idol).orderBy(specifier).fetch();
트랜잭션: 데이터베이스의 상태를 변화시키는 하나의 논리적 작업 단위입니다. All or Nothing 원칙에 따라 작업 내의 모든 연산이 성공하거나, 하나라도 실패하면 모든 변경 사항이 되돌려져야(롤백) 합니다.
주요 명령어:
COMMIT: 모든 작업을 최종적으로 데이터베이스에 영구 저장합니다.ROLLBACK: 작업 중 발생한 모든 변경 사항을 취소하고 트랜잭션 이전 상태로 되돌립니다.SAVEPOINT: 트랜잭션 내에 중간 저장 지점을 만들어, 전체가 아닌 특정 지점까지만 롤백할 수 있게 합니다.ACID (트랜잭션 4대 특성): 데이터베이스 트랜잭션의 안정성을 보장하는 4가지 성질입니다.
| 특성 | 설명 |
|---|---|
| 원자성 (Atomicity) | 트랜잭션의 연산은 모두 반영되거나, 아니면 모두 반영되지 않아야 한다. |
| 일관성 (Consistency) | 트랜잭션 실행 후에도 데이터베이스는 항상 일관된 상태를 유지해야 한다. |
| 격리성 (Isolation) | 둘 이상의 트랜잭션이 동시에 실행될 때, 서로의 작업에 영향을 주지 않아야 한다. |
| 지속성 (Durability) | 성공적으로 완료된(COMMIT된) 트랜잭션의 결과는 영구적으로 저장되어야 한다. |
DCL (Data Control Language): 데이터베이스 객체에 대한 접근 권한을 부여(GRANT)하거나 회수(REVOKE)하는 명령어입니다.
권한의 종류:
CREATE SESSION), 테이블 생성(CREATE TABLE) 등 시스템 차원의 권한.SELECT), 수정(UPDATE) 등 특정 객체에 대한 권한.ROLE: 여러 권한들을 하나로 묶어 관리하는 '권한 꾸러미'입니다. 사용자에게 직접 권한을 부여하는 대신, 직책(e.g., 개발자, 마케터)에 맞는 ROLE을 부여하여 권한 관리를 효율적이고 체계적으로 할 수 있습니다.
-- 1. ROLE 생성
CREATE ROLE DEV_ROLE;
-- 2. ROLE에 권한들 부여
GRANT CREATE SESSION, CREATE TABLE TO DEV_ROLE;
GRANT SELECT, INSERT ON EMPLOYEES TO DEV_ROLE;
-- 3. 사용자에게 ROLE 부여
GRANT DEV_ROLE TO DEV01;
JPAExpressions로 타입-세이프한 서브쿼리를, BooleanBuilder와 OrderSpecifier로 동적 쿼리 및 정렬을 효과적으로 구현할 수 있습니다.COMMIT과 ROLLBACK으로 제어됩니다.GRANT, REVOKE)은 데이터 접근 권한을 제어하는 언어이며, 여러 권한을 묶은 ROLE을 활용하면 다수 사용자의 권한을 효율적으로 관리할 수 있습니다.