Upgrade to Pro — share decks privately, control downloads, hide ads and more …

なにも考えずClean ArchitectureでExposedを使ったらパフォーマンスで地獄を見た話

5155c9bc5b30d9e2a8fd677695887861?s=47 kaonash
April 05, 2021

なにも考えずClean ArchitectureでExposedを使ったらパフォーマンスで地獄を見た話

5155c9bc5b30d9e2a8fd677695887861?s=128

kaonash

April 05, 2021
Tweet

Transcript

  1. ͳʹ΋ߟ͑ͣClean ArchitectureͰExposedΛ࢖ͬͨΒ ύϑΥʔϚϯεͰ஍ࠈΛݟͨ࿩ UPSIDERɹਗ਼ਫݦ

  2. SELF INTRODUCTION • ਗ਼ਫݦ(@kaonash_ ) • Lead Software Engineer &

    PdM & ΤϯδχΞ૊৫ߏங etc… @ UPSIDE R • Ҡॅ͍ͨ͠ܥΤϯδχΞʢ2022೥ɺ௕໺ʹҠॅ༧ఆʣ • Love: ୌ / Kitkat / Kotlin
  3. એ఻ ௒࠾༻ͯ͠ΔͷͰ͚͍ͨͯͩ͘͢͞ʂ ʢϑϧϦϞʔτɾϑϧϑϨοΫεɾ෭ۀͰ΋OKʣ https://corporatecard.up-sider.jp/career

  4. WHAT IS • Pure KotlinͷORMϑϨʔϜϫʔΫ • JetBrains੡ • 2छྨͷσʔλΞΫηεํ๏ •

    λΠϓηʔϑʹSQLͬΆ͘ΫΤϦΛ૊ΈཱͯΒΕΔDSL AP I • DAO(Data Access Object)Λ࢖͏DAO API
  5. ࠓճαϯϓϧͰ࢖͏ςʔϒϧΛఆٛ object BillTable : LongIdTable("bills") { val name = varchar("name",

    128 ) } object BillStatusTable : LongIdTable("bill_status") { val billId = reference("bill_id", BillTable ) val status = enumerationByName("status", 20, BillStatus::class ) val startAt = datetime("start_at").defaultExpression(CurrentDateTime() ) } billsςʔϒϧ΁ͷ֎෦ΩʔΛදݱ
  6. DAO APIΛ࢖͏৔߹͸ENTITY(DAO)΋ఆٛ class BillEntity(id: EntityID<Long>) : LongEntity(id) { companion object

    : LongEntityClass<BillEntity>(BillTable ) var name by BillTable.nam e val statusHistory by BillStatusEntity.referrersOn ( column = BillStatusTable.bill , cache = tru e ) } class BillStatusEntity(id: EntityID<Long>) : LongEntity(id) { companion object : LongEntityClass<BillStatusEntity>(BillStatusTable ) var bill by BillStatusTable.bil l var status by BillStatusTable.statu s var startAt by BillStatusTable.startA t } referrersOnΛ࢖͏͜ͱͰbill_statusςʔϒϧͷσʔλ΋ҰॹʹऔΕΔʂ
  7. ࣮ࡍͷσʔλऔಘํ๏ʢDAO APIʣ BillEntity.all().forEach { bill - > println("[${bill.id.value}] ${bill.name}" )

    } billsςʔϒϧʹϨίʔυ͕2݅͋Δ৔߹ͷ݁Ռ ࣮ࡍͷΫΤϦ
  8. ͋Εɺbill_statusςʔϒϧ͸ɾɾɾʁ

  9. ஗ԆධՁͳͷͰɺ σʔλΛࢀর͢Δ࣌ʹॳΊͯऔΓʹߦ͘ ʢJOIN͍ͯ͠ΔΘ͚Ͱ͸ͳ͍ʣ BillEntity.all().forEach { bill - > println("[${bill.id.value}] ${bill.name}"

    ) println(bill.statusHistory.joinToString(separator = ",") { it.status.name } ) }
  10. Exposed, ݡ͍ʂʂ

  11. ͕͔͠͠

  12. CleanArchitectureͰ͜ͷػೳΛ ͦͷ··࢖ͬͯ஍ࠈΛݟͨ

  13. CleanArchitectureͱ͸ʁ

  14. ҎԼུ

  15. େࣄͳ͜ͱɿϢʔεέʔε͸DBΛ஌Βͳ͍

  16. Ϣʔεέʔε͸DBΛ஌Βͳ͍ ↓ ౰વɺExposedͷ͜ͱ΋஌Βͳ͍ ↓ Exposedʹґଘͨ͠Entity΋ฦͤͳ͍ ↓ σʔλऔಘͷࡍ͸ɺϢʔεέʔε͕஌ͬͯΔ ΦϒδΣΫτʹ٧Ίସ͑Δඞཁ͕͋Δ

  17. ٧Ίସ͑Ε͹͑͑΍ͳ͍ͷ data class Bill ( val name: String , val

    statusHistory: List<BillStatus > ) data class BillStatus ( val status: String , val startAt: DateTime , ) ————————————————————————————————————————————————————————————————— — return BillEntity.all().map { bill - > Bill ( name = bill.name , statusHistory = bill.statusHistory.map { status - > BillStatus(status = status.status.name, startAt = status.startAt ) } ) }
  18. ผͷΦϒδΣΫτʹ٧Ίସ͑Δ ↓ ͦͷ࣌఺Ͱ஗ԆධՁ͕࣮ߦ͞ΕΔ ↓ billsͷϨίʔυ਺͚ͩ bill_status΁ͷselect͕࣮ߦ͞ΕΔ ʢϏδωεϩδοΫ಺Ͱ࢖͏͔Ͳ͏͔ʹؔΘΒͣʣ

  19. Ϋι஗͍ʢ࣮ࡍ͸΋ͬͱςʔϒϧߏ଄͕ෳࡶͳ ͷͰ͞Βʹ๲େͳ਺ͷSELECTจ͕͕͕ʣ

  20. ղܾࡦɿEager LoadingΛ࢖͏ BillEntity.all().with(BillEntity::statusHistory).map { bill - > Bill ( name

    = bill.name , statusHistory = bill.statusHistory.map { status - > BillStatus(status = status.status.name, startAt = status.startAt ) } ) }.forEach { println(it) } ͜ͷ࣌఺Ͱ·ͱΊͯಡΈࠐΜͰ͘ΕΔʂ
  21. ஫ҙ఺ɿEntityఆٛ࣌ʹcache=trueʹ͓ͯ͠ ͔ͳ͍ͱ݁ہେྔͷΫΤϦ͕౤͛ΒΕΔ class BillEntity(id: EntityID<Long>) : LongEntity(id) { companion object

    : LongEntityClass<BillEntity>(BillTable ) var name by BillTable.nam e val statusHistory by BillStatusEntity.referrersOn ( column = BillStatusTable.bill , cache = fals e ) } ͜ΕͰಉ͡ॲཧΛ࣮ߦ͢Δͱɾɾɾ
  22. Thank you!!