Closed LeeMH closed 2 years ago
안녕하세요. 아래와 같이 사용하실 수 있습니다.
@Entity
@Table(
name = "test_user"
)
data class User(
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long? = null,
@Column(name = "parent_id")
val parentId: Long?,
@Column(name = "name")
val name: String,
)
data class Row(
val parentId: Long?,
val childId: Long?,
)
val rows = queryFactory.listQuery<Row> {
val parentUser = entity(User::class, "parentUser")
val childUser = entity(User::class, "childUser")
selectMulti(col(parentUser, User::id), col(childUser, User::id))
from(parentUser)
join(childUser, col(parentUser, User::id).equal(col(childUser, User::parentId)))
}
rows.forEach {
println(it)
}
하지만 이렇게 condition 기반의 조인을 할 경우 left join을 할 수 없습니다. 이는 Criteria API의 한계이고, 추후 kotlin-jdsl을 JPQL을 기반으로 변경하면 지원할 수 있고 변경 계획은 있지만 다른 업무로 인해 아직 많은 진척은 없는 상황입니다.
만약 변경 된다면 3.0으로 배포하여 많은 인터페이스가 바뀌게 될 예정입니다.
만약 left join이 꼭 필요하시다면 비지니스 모델에 따라 가능할지 모르지만 아래와 같은 Entity 모델을 추천 드립니다.
@Entity
@Table(
name = "test_user"
)
data class User(
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0,
@Column(name = "name")
val name: String,
@OneToMany(mappedBy = "parent", cascade = [CascadeType.ALL])
val children: Set<User>,
) {
@ManyToOne
@JoinColumn(name = "parent_id")
var parent: User? = null
init {
children.forEach { it.parent = this }
}
}
data class Row(
val parentName: String?,
val childName: String?,
)
val rows = queryFactory.listQuery<Row> {
val parentUser = entity(User::class, "parentUser")
val childUser = entity(User::class, "childUser")
selectMulti(col(parentUser, User::name), col(childUser, User::name))
from(parentUser)
join(parentUser, childUser, on(User::children), JoinType.LEFT)
orderBy(col(parentUser, User::name).asc())
}
rows.forEach {
println(it)
}
// Row(parentName=user1, childName=user2)
// Row(parentName=user2, childName=user3)
// Row(parentName=user3, childName=null)
@shouwn 친절한 답변 감사합니다. jdsl 고맙게 잘 사용하고 있습니다. left join만 가능하면 최고일듯 합니다!!!
SQL 베이스의 통계성 업무가 꼭 있어서, JPA(QueryDSL)와 myBatis 사이에서 고민이 jdsl로 사라졌으면 합니다.
감사합니다.
안녕하세요.
QueryDSL 대신 jdsl 로 간단하게 토이프로젝트 돌려보며 방향성을 잡아 나가고 있습니다.
동일 테이블에 대한 join 을 어떻게 해야 할지 이리저리 해보다 안되서 문의 드립니다.
User 테이블에는 상위 User의 정보를 저장하는 parent_id가 있습니다. User Entity에서는 연관관계 없이 사용하고 있습니다. User( id bigint, parent_id bigint, name varchar(100) )
표현하고 싶은 쿼리는 아래와 같습니다. 문서에 join > alias쪽을 보았으나, native sql 처럼 풀어나가는 방법이 없는것 같아 문의 드립니다. select u.id as my_id, p.id as parent_id from User u left join User p on u.parent_id = u.id