Skip to content

Commit 221d774

Browse files
committed
[BOOK-163] feat: �infra tag 중간테이블 기능개발 (#52)
1 parent fb6fd8d commit 221d774

File tree

11 files changed

+224
-9
lines changed

11 files changed

+224
-9
lines changed

infra/src/main/kotlin/org/yapp/infra/book/entity/BookEntity.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,31 @@ import jakarta.persistence.Id
66
import jakarta.persistence.Table
77
import org.hibernate.annotations.JdbcTypeCode
88
import org.hibernate.annotations.SQLDelete
9+
import org.hibernate.annotations.SQLRestriction
910
import org.yapp.domain.book.Book
1011
import org.yapp.infra.common.BaseTimeEntity
1112
import java.sql.Types
13+
import java.util.UUID
1214

1315
@Entity
1416
@Table(name = "books")
1517
@SQLDelete(sql = "UPDATE books SET deleted_at = NOW() WHERE isbn = ?")
18+
@SQLRestriction("deleted_at IS NULL")
1619
class BookEntity private constructor(
1720
@Id
1821
@JdbcTypeCode(Types.VARCHAR)
19-
@Column(length = 13, updatable = false, nullable = false)
22+
@Column(length = 36, updatable = false, nullable = false)
23+
val id: UUID,
24+
25+
@Column(length = 13, updatable = false, nullable = false, unique = true)
2026
val isbn: String,
2127

2228
title: String,
2329
author: String,
2430
publisher: String,
2531
publicationYear: Int? = null,
2632
coverImageUrl: String,
27-
description: String? = null
28-
33+
description: String? = null,
2934
) : BaseTimeEntity() {
3035

3136
@Column(nullable = false, length = 255)
@@ -52,7 +57,9 @@ class BookEntity private constructor(
5257
var description: String? = description
5358
protected set
5459

60+
5561
fun toDomain(): Book = Book.reconstruct(
62+
id = Book.Id.newInstance(this.id),
5663
isbn = Book.Isbn.newInstance(this.isbn),
5764
title = title,
5865
author = author,
@@ -67,21 +74,22 @@ class BookEntity private constructor(
6774

6875
companion object {
6976
fun fromDomain(book: Book): BookEntity = BookEntity(
77+
id = book.id.value,
7078
isbn = book.isbn.value,
7179
title = book.title,
7280
author = book.author,
7381
publisher = book.publisher,
7482
publicationYear = book.publicationYear,
7583
coverImageUrl = book.coverImageUrl,
76-
description = book.description
84+
description = book.description,
7785
)
7886
}
7987

8088
override fun equals(other: Any?): Boolean {
8189
if (this === other) return true
8290
if (other !is BookEntity) return false
83-
return isbn == other.isbn
91+
return id == other.id
8492
}
8593

86-
override fun hashCode(): Int = isbn.hashCode()
94+
override fun hashCode(): Int = id.hashCode()
8795
}

infra/src/main/kotlin/org/yapp/infra/book/repository/JpaBookRepository.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,9 @@ import org.yapp.infra.book.entity.BookEntity
66
/**
77
* JPA repository for BookEntity.
88
*/
9-
interface JpaBookRepository : JpaRepository<BookEntity, String> {
9+
import java.util.UUID
10+
11+
interface JpaBookRepository : JpaRepository<BookEntity, UUID> {
12+
fun findByIsbn(isbn: String): BookEntity?
13+
fun existsByIsbn(isbn: String): Boolean
1014
}

infra/src/main/kotlin/org/yapp/infra/book/repository/impl/BookRepositoryImpl.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,28 @@ import org.yapp.domain.book.Book
66
import org.yapp.domain.book.BookRepository
77
import org.yapp.infra.book.entity.BookEntity
88
import org.yapp.infra.book.repository.JpaBookRepository
9+
import java.util.UUID
910

1011
@Repository
1112
class BookRepositoryImpl(
1213
private val jpaBookRepository: JpaBookRepository
1314
) : BookRepository {
14-
override fun findById(id: String): Book? {
15+
override fun findById(id: UUID): Book? {
1516
return jpaBookRepository.findByIdOrNull(id)?.toDomain()
1617
}
1718

18-
override fun existsById(id: String): Boolean {
19+
override fun existsById(id: UUID): Boolean {
1920
return jpaBookRepository.existsById(id)
2021
}
2122

23+
override fun findByIsbn(isbn: String): Book? {
24+
return jpaBookRepository.findByIsbn(isbn)?.toDomain()
25+
}
26+
27+
override fun existsByIsbn(isbn: String): Boolean {
28+
return jpaBookRepository.existsByIsbn(isbn)
29+
}
30+
2231
override fun save(book: Book): Book {
2332
val savedEntity = jpaBookRepository.saveAndFlush(BookEntity.fromDomain(book))
2433
return savedEntity.toDomain()
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package org.yapp.infra.readingrecordtag.entity
2+
3+
import jakarta.persistence.Column
4+
import jakarta.persistence.Entity
5+
import jakarta.persistence.Id
6+
import jakarta.persistence.Table
7+
import org.hibernate.annotations.JdbcTypeCode
8+
import org.hibernate.annotations.SQLDelete
9+
import org.hibernate.annotations.SQLRestriction
10+
import org.yapp.domain.readingrecordtag.ReadingRecordTag
11+
import org.yapp.infra.common.BaseTimeEntity
12+
import java.sql.Types
13+
import java.util.UUID
14+
15+
@Entity
16+
@Table(name = "reading_record_tags")
17+
@SQLDelete(sql = "UPDATE reading_record_tags SET deleted_at = NOW() WHERE id = ?")
18+
@SQLRestriction("deleted_at IS NULL")
19+
class ReadingRecordTagEntity(
20+
@Id
21+
@JdbcTypeCode(Types.VARCHAR)
22+
@Column(length = 36, updatable = false, nullable = false)
23+
val id: UUID,
24+
25+
@Column(name = "reading_record_id", nullable = false, length = 36)
26+
@JdbcTypeCode(Types.VARCHAR)
27+
val readingRecordId: UUID,
28+
29+
@Column(name = "tag_id", nullable = false, length = 36)
30+
@JdbcTypeCode(Types.VARCHAR)
31+
val tagId: UUID
32+
) : BaseTimeEntity() {
33+
34+
fun toDomain(): ReadingRecordTag {
35+
return ReadingRecordTag.reconstruct(
36+
id = ReadingRecordTag.Id.newInstance(this.id),
37+
readingRecordId = org.yapp.domain.readingrecord.ReadingRecord.Id.newInstance(this.readingRecordId),
38+
tagId = org.yapp.domain.tag.Tag.Id.newInstance(this.tagId),
39+
createdAt = this.createdAt,
40+
updatedAt = this.updatedAt,
41+
deletedAt = this.deletedAt
42+
)
43+
}
44+
45+
companion object {
46+
fun fromDomain(readingRecordTag: ReadingRecordTag): ReadingRecordTagEntity {
47+
return ReadingRecordTagEntity(
48+
id = readingRecordTag.id.value,
49+
readingRecordId = readingRecordTag.readingRecordId.value,
50+
tagId = readingRecordTag.tagId.value
51+
)
52+
}
53+
}
54+
55+
override fun equals(other: Any?): Boolean {
56+
if (this === other) return true
57+
if (other !is ReadingRecordTagEntity) return false
58+
return id == other.id
59+
}
60+
61+
override fun hashCode(): Int = id.hashCode()
62+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.yapp.infra.readingrecordtag.repository
2+
3+
import org.springframework.data.jpa.repository.JpaRepository
4+
import org.yapp.infra.readingrecordtag.entity.ReadingRecordTagEntity
5+
import java.util.UUID
6+
7+
interface JpaReadingRecordTagRepository : JpaRepository<ReadingRecordTagEntity, UUID> {
8+
fun findByReadingRecordId(readingRecordId: UUID): List<ReadingRecordTagEntity>
9+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.yapp.infra.readingrecordtag.repository
2+
3+
import org.springframework.stereotype.Repository
4+
import org.yapp.domain.readingrecordtag.ReadingRecordTag
5+
import org.yapp.domain.readingrecordtag.ReadingRecordTagRepository
6+
import org.yapp.infra.readingrecordtag.entity.ReadingRecordTagEntity
7+
8+
@Repository
9+
class ReadingRecordTagRepositoryImpl(
10+
private val jpaReadingRecordTagRepository: JpaReadingRecordTagRepository
11+
) : ReadingRecordTagRepository {
12+
override fun saveAll(readingRecordTags: List<ReadingRecordTag>): List<ReadingRecordTag> {
13+
val entities = readingRecordTags.map { ReadingRecordTagEntity.fromDomain(it) }
14+
return jpaReadingRecordTagRepository.saveAll(entities).map { it.toDomain() }
15+
}
16+
17+
override fun findByReadingRecordId(readingRecordId: java.util.UUID): List<ReadingRecordTag> {
18+
return jpaReadingRecordTagRepository.findByReadingRecordId(readingRecordId).map { it.toDomain() }
19+
}
20+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package org.yapp.infra.tag.entity
2+
3+
import jakarta.persistence.Column
4+
import jakarta.persistence.Entity
5+
import jakarta.persistence.Id
6+
import jakarta.persistence.Table
7+
import org.hibernate.annotations.JdbcTypeCode
8+
import org.hibernate.annotations.SQLDelete
9+
import org.hibernate.annotations.SQLRestriction
10+
import org.yapp.domain.tag.Tag
11+
import org.yapp.infra.common.BaseTimeEntity
12+
import java.sql.Types
13+
import java.util.UUID
14+
15+
@Entity
16+
@Table(name = "tags")
17+
@SQLDelete(sql = "UPDATE tags SET deleted_at = NOW() WHERE id = ?")
18+
@SQLRestriction("deleted_at IS NULL")
19+
class TagEntity(
20+
@Id
21+
@JdbcTypeCode(Types.VARCHAR)
22+
@Column(length = 36, updatable = false, nullable = false)
23+
val id: UUID,
24+
25+
@Column(nullable = false, length = 10, unique = true)
26+
val name: String
27+
) : BaseTimeEntity() {
28+
29+
fun toDomain(): Tag {
30+
return Tag.reconstruct(
31+
id = Tag.Id.newInstance(this.id),
32+
name = this.name,
33+
createdAt = this.createdAt,
34+
updatedAt = this.updatedAt,
35+
deletedAt = this.deletedAt
36+
)
37+
}
38+
39+
companion object {
40+
fun fromDomain(tag: Tag): TagEntity {
41+
return TagEntity(
42+
id = tag.id.value,
43+
name = tag.name
44+
)
45+
}
46+
}
47+
48+
override fun equals(other: Any?): Boolean {
49+
if (this === other) return true
50+
if (other !is TagEntity) return false
51+
return id == other.id
52+
}
53+
54+
override fun hashCode(): Int = id.hashCode()
55+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.yapp.infra.tag.repository
2+
3+
import org.springframework.data.jpa.repository.JpaRepository
4+
import org.yapp.infra.tag.entity.TagEntity
5+
import java.util.UUID
6+
7+
interface JpaTagRepository : JpaRepository<TagEntity, UUID> {
8+
fun findByName(name: String): TagEntity?
9+
fun findByNameIn(names: List<String>): List<TagEntity>
10+
fun findByIdIn(ids: List<UUID>): List<TagEntity>
11+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.yapp.infra.tag.repository
2+
3+
import org.springframework.stereotype.Repository
4+
import org.yapp.domain.tag.Tag
5+
import org.yapp.domain.tag.TagRepository
6+
import org.yapp.infra.tag.entity.TagEntity
7+
import java.util.UUID
8+
9+
@Repository
10+
class TagRepositoryImpl(
11+
private val jpaTagRepository: JpaTagRepository
12+
) : TagRepository {
13+
override fun findByName(name: String): Tag? {
14+
return jpaTagRepository.findByName(name)?.toDomain()
15+
}
16+
17+
override fun save(tag: Tag): Tag {
18+
return jpaTagRepository.save(TagEntity.fromDomain(tag)).toDomain()
19+
}
20+
21+
override fun findByNames(names: List<String>): List<Tag> {
22+
return jpaTagRepository.findByNameIn(names).map { it.toDomain() }
23+
}
24+
25+
override fun findByIds(ids: List<UUID>): List<Tag> {
26+
return jpaTagRepository.findByIdIn(ids).map { it.toDomain() }
27+
}
28+
}

infra/src/main/kotlin/org/yapp/infra/userbook/entity/UserBookEntity.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package org.yapp.infra.userbook.entity
33
import jakarta.persistence.*
44
import org.hibernate.annotations.JdbcTypeCode
55
import org.hibernate.annotations.SQLDelete
6+
import org.hibernate.annotations.SQLRestriction
67
import org.yapp.infra.common.BaseTimeEntity
78
import org.yapp.domain.userbook.BookStatus
89
import org.yapp.domain.userbook.UserBook
@@ -12,6 +13,7 @@ import java.util.*
1213
@Entity
1314
@Table(name = "user_books")
1415
@SQLDelete(sql = "UPDATE user_books SET deleted_at = NOW() WHERE id = ?")
16+
@SQLRestriction("deleted_at IS NULL")
1517
class UserBookEntity(
1618
@Id
1719
@JdbcTypeCode(Types.VARCHAR)
@@ -22,6 +24,10 @@ class UserBookEntity(
2224
@JdbcTypeCode(Types.VARCHAR)
2325
val userId: UUID,
2426

27+
@Column(name = "book_id", nullable = false, length = 36)
28+
@JdbcTypeCode(Types.VARCHAR)
29+
val bookId: UUID,
30+
2531
@Column(name = "book_isbn", nullable = false)
2632
val bookIsbn: String,
2733

@@ -56,6 +62,7 @@ class UserBookEntity(
5662
fun toDomain(): UserBook = UserBook.reconstruct(
5763
id = UserBook.Id.newInstance(this.id),
5864
userId = UserBook.UserId.newInstance(this.userId),
65+
bookId = UserBook.BookId.newInstance(this.bookId),
5966
bookIsbn = UserBook.BookIsbn.newInstance(this.bookIsbn),
6067
coverImageUrl = this.coverImageUrl,
6168
publisher = this.publisher,
@@ -72,6 +79,7 @@ class UserBookEntity(
7279
return UserBookEntity(
7380
id = userBook.id.value,
7481
userId = userBook.userId.value,
82+
bookId = userBook.bookId.value,
7583
bookIsbn = userBook.bookIsbn.value,
7684
coverImageUrl = userBook.coverImageUrl,
7785
publisher = userBook.publisher,

0 commit comments

Comments
 (0)