Kotlin JDSL์ JPQL์ conditional expression์ ํํํ๊ธฐ ์ํด Predicate
์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค.
Logical operators
๋
ผ๋ฆฌ ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, ๋ค์ ํจ์๋ค์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ง์ฝ and()
์ or()
๋ก ๋์ด์จ Predicate
๊ฐ ๋ชจ๋ null ์ด๊ฑฐ๋ ๋น์ด ์์ผ๋ฉด, and()
์ ๊ฒฝ์ฐ์๋ 1 = 1
๋ก or()
์ ๊ฒฝ์ฐ์๋ 0 = 1
๋ก ํด์๋ฉ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ ๋ค์ด๋๋ฏน ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค ๋ ์กฐ์ฌํด์ผ ํฉ๋๋ค.
path(Employee::name).eq("Employee01").and(path(Employee::nickname).eq("E01"))
and(path(Employee::name).eq("Employee01"), path(Employee::nickname).eq("E01"))
path(Employee::name).eq("Employee01").or(path(Employee::nickname).eq("E01"))
or(path(Employee::name).eq("Employee01"), path(Employee::nickname).eq("E01"))
not(path(Employee::name).eq("Employee01"))
Parentheses
ํ์ฅ ํจ์๊ฐ ์๋ ์ผ๋ฐ ํจ์๋ฅผ ํธ์ถํ๋ ๊ฒ์ผ๋ก ๋
ผ๋ฆฌ ์ฐ์ฐ์์ ์ฐ์ฐ ์์๋ฅผ ์ํ ์๊ดํธ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค. ํ์ฅ ํจ์์ ๊ฒฝ์ฐ ์ฐ์ฐ ์์๊ฐ ๋ชจํธํด์ ์๊ดํธ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค.
// ์ผ๋ฐ ํจ์: (Employee.name = 'Employee01' AND Employee.nickname = 'E01') or (Employee.name = 'Employee02' AND Employee.nickname = 'E02')
or(
path(Employee::name).eq("Employee01").and(path(Employee::nickname).eq("E01")),
path(Employee::name).eq("Employee02").and(path(Employee::nickname).eq("E02")),
)
// ํ์ฅ ํจ์: Employee.name = 'Employee01' AND Employee.nickname = 'E01' or Employee.name = 'Employee02' AND Employee.nickname = 'E02'
path(Employee::name).eq("Employee01").and(path(Employee::nickname).eq("E01")).or(path(Employee::name).eq("Employee02").and(path(Employee::nickname).eq("E02")))
Comparison operators
๋น๊ต ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, ๋ค์ ํจ์๋ค์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
>= (greaterThanOrEqualTo or ge)
<= (lessThanOrEqualTo or le)
path(Book::price).equal(BigDecimal.valueOf(100))
path(Book::price).eq(BigDecimal.valueOf(100))
path(Book::price).notEqual(BigDecimal.valueOf(100))
path(Book::price).ne(BigDecimal.valueOf(100))
path(Book::price).greaterThan(BigDecimal.valueOf(100))
path(Book::price).gt(BigDecimal.valueOf(100))
path(Book::price).greaterThanOrEqualTo(BigDecimal.valueOf(100))
path(Book::price).ge(BigDecimal.valueOf(100))
path(Book::price).lessThan(BigDecimal.valueOf(100))
path(Book::price).lt(BigDecimal.valueOf(100))
path(Book::price).lessThanOrEqualTo(BigDecimal.valueOf(100))
path(Book::price).le(BigDecimal.valueOf(100))
All or Any
ํจ์ ์ด๋ฆ ๋ง์ง๋ง์ all
๊ณผ any
๋ฅผ ๋ถ์ด๋ ๊ฒ์ผ๋ก subquery์ ๋ํ All๊ณผ Any ์ฐ์ฐ์ ํ ์ ์์ต๋๋ค.
val query = jpql {
val annualSalaries = select(
path(FullTimeEmployee::annualSalary)(EmployeeSalary::value),
).from(
entity(FullTimeEmployee::class),
join(FullTimeEmployee::departments),
).where(
path(EmployeeDepartment::departmentId).eq(3L),
).asSubquery()
select(
path(FullTimeEmployee::employeeId),
).from(
entity(FullTimeEmployee::class),
).where(
path(FullTimeEmployee::annualSalary)(EmployeeSalary::value).gtAll(annualSalaries),
)
}
Null
null ๋น๊ต ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, isNull()
๊ณผ isNotNull()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
path(Employee::nickname).isNull()
path(Employee::nickname).isNotNull()
Like
like ๋น๊ต ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, like()
์ notLike()
๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
path(Employee::nickname).like("E%")
path(Employee::nickname).like("E_", escape = '_')
path(Employee::nickname).notLike("E%")
path(Employee::nickname).notLike("E_", escape = '_')
Between
between ๋น๊ต ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, between()
๊ณผ notBetween()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
path(Employee::price).between(BigDecimal.valueOf(100), BigDecimal.valueOf(200))
path(Employee::price).notBetween(BigDecimal.valueOf(100), BigDecimal.valueOf(200))
In
in ๋น๊ต ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, in()
๊ณผ notIn()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
path(Employee::price).`in`(BigDecimal.valueOf(100), BigDecimal.valueOf(200))
path(Employee::price).notIn(BigDecimal.valueOf(100), BigDecimal.valueOf(200))
Exists
exists ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, exists()
์ notExists()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
exists(subquery)
notExists(subquery)
Empty
empty ์ฐ์ฐ์ ๋ง๋ค๊ธฐ ์ํด, isEmpty()
์ isNotEmpty()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
path(Employee::departments).isEmpty()
path(Employee::departments).isNotEmpty()
Database function
DB ํจ์๋ ์ฌ์ฉ์ ์ ์ ํจ์๋ฅผ ๋ง๋ค๊ธฐ ์ํด, KClass<Boolean>
๊ณผ ํจ๊ป function()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
function(Boolean::class, "myFunction", path(Book::isbn))
์ฌ์ฉํ๋ ค๋ ํจ์์ ๋ํ ์ ๋ณด๋ฅผ JPA Provider์ ๋ฑ๋กํด์ผ ํ ์๋ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, Hibernate๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค๋ฉด FunctionContributor
๋ฅผ ๋ฐ๋์ ๋ฑ๋กํด์ผ ํฉ๋๋ค.
Custom predicate
์ปค์คํ
predicate๋ฅผ ๋ง๋ค๊ธฐ ์ํด, customPredicate()
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
customPredicate("{0} MEMBER OF {1}", value(author), path(Book::authors))
๋ง์ฝ customPredicate()
์ ๋ง์ด ์ฌ์ฉํ๋ค๋ฉด ๋๋ง์ DSL์ ๋ง๋๋ ๊ฒ์ ๊ณ ๋ คํด๋ณด์ธ์.