SlideShare a Scribd company logo
1 of 30
7±2 things you didn’t
know about Exposed
Alexey Soshin, November 2022
vs
Selecting using criteria with an annotation
Selecting using criteria with an annotation
Deleting using conventions
UsersTable
.select { UsersTable.firstName eq firstName }
.toList()
Selecting using criteria: SQL DSL
val count: Int = UsersTable
.deleteWhere { UsersTable.lastName eq lastName }
Deleting: SQL DSL
val users = User.find {
UsersTable.firstName eq firstName
}.toList()
Selecting using criteria: DAO API
users.forEach {
it.delete()
}
Deleting: DAO API
Logging
transaction {
addLogger(StdOutSqlLogger)
UsersTable
.select { UsersTable.firstName eq firstName
}
.toList()
}
Logging
SQL: SELECT users.id, users.first_name,
users.last_name FROM users WHERE users.first_name =
'Alexey'
transaction {
addLogger(StdOutSqlLogger)
UsersTable
.select { UsersTable.firstName eq firstName
}
.toList()
}
Logging
val sql = UsersTable
.select { UsersTable.firstName eq firstName }
.prepareSQL(this)
println(sql)
SELECT users.id, users.first_name, users.last_name
FROM users WHERE users.first_name = ?
Date support
object UsersTable : IntIdTable() {
val firstName = varchar("first_name", 20)
val lastName = varchar("last_name", 20)
val createdAt = datetime("created_at")
}
Date support
// JDK 7, legacy
"org.jetbrains.exposed:exposed-jodatime"
// JDK 8+
"org.jetbrains.exposed:exposed-java-time"
// Kotlin
"org.jetbrains.exposed:exposed-kotlin-datetime"
Many–to-many relationship
Many–to-many relationship
object Members : UUIDTable() {
val user = reference("user_id", Users, onDelete =
ReferenceOption.CASCADE)
val group = reference("group_id", Groups, onDelete =
ReferenceOption.CASCADE)
val createdAt =
datetime("created_at").defaultExpression(CurrentDateTime)
}
Many–to-many relationship
class Group(id: EntityID<UUID>) : UUIDEntity(id) {
companion object : UUIDEntityClass<Group>(Groups)
var name by Groups.name
var description by Groups.description
var owner by User referencedOn Groups.owner
val members by User.via(Members.group, Members.user)
}
Many–to-many relationship
class User(id: EntityID<UUID>) : UUIDEntity(id) {
companion object : UUIDEntityClass<User>(Users)
var username by Users.username
val groups by Group.via(Members.user, Members.group)
}
Coroutines support
suspend fun doSomeIO() {
delay(10L)
}
transaction {
doSomeIO()
}
Coroutines support
newSuspendedTransaction {
doSomeIO()
}
👍
newSuspendedTransaction {
// Nesting suspended transactions
suspendedTransaction {
doSomeIO()
}
doSomeIO() // Failure here will rollback everything
}
Coroutines support
🤔
newSuspendedTransaction {
// Nesting suspended transactions
newSuspendedTransaction {
doSomeIO()
}
doSomeIO() // Failure here won’t rollback everything!
}
Null expression
SELECT COUNT(CASE
WHEN messages.seen = 'NO' THEN NULL
ELSE 1 END)
FROM messages
Null expression
SELECT COUNT(CASE
WHEN messages.seen = 'NO' THEN NULL
ELSE 1 END)
FROM messages
Messages.slice(
Count(
case()
.When(seen eq "NO", "NULL"/null)
.Else(intLiteral(1))
)
).selectAll().toList()
Null expression
SELECT COUNT(CASE
WHEN messages.seen = 'NO' THEN NULL
ELSE 1 END)
FROM messages
Messages.slice(
Count(
case()
.When(seen eq "NO", Op.nullOp<Int>())
.Else(intLiteral(1))
)
).selectAll().toList()
Null expression
SELECT COUNT(CASE
WHEN messages.seen = 'YES' THEN 1
ELSE NULL END)
FROM messages
Messages.slice(
Count(
case()
.When(seen eq "YES", intLiteral(1))
.Else(Op.nullOp())
)
).selectAll().toList()
From SQL DSL to DAO Entities
val query: Query = Groups
.innerJoin(Users)
.innerJoin(Members)
.slice(Groups.columns)
.selectAll()
.withDistinct()
🤔
From SQL DSL to DAO Entities
val groups: SizedIterable<Group> =
Group.wrapRows(query)
val query: Query = Groups
.innerJoin(Users)
.innerJoin(Members)
.slice(Groups.columns)
.selectAll()
.withDistinct()
Breaking the rules
exec("select * from users") { rs ->
while (rs.next()) {
// Not zero based!
println(rs.getString(1))
}
}
Summary
1. Log a single query
2. Choose what date library to work with
3. Flexible support for many-to-many relationship
4. Coroutine support
5. Expression that represents SQL NULL
6. Easy mapping from SQL DSL to DAO Entities
7. Arbitrary statements
Questions and contributions
Questions:
stackoverflow.com/questions/tagged/kotlin-exposed
Bugs:
github.com/JetBrains/Exposed/issues
PRs are welcome!
github.com/JetBrains/Exposed/pulls
Video course on Exposed in making
Out in January 2023
Let’s stay in touch!
www.linkedin.com/in/alexeysoshin
alexey-soshin.medium.com
twitter.com/alexey_soshin
Coupon: KOTLINDEVDAY2022
Glory to Ukraine!
🇺🇦

More Related Content

What's hot

L2 over L3 ecnaspsulations
L2 over L3 ecnaspsulationsL2 over L3 ecnaspsulations
L2 over L3 ecnaspsulationsMotonori Shindo
 
モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)
モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)
モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)株式会社MonotaRO Tech Team
 
Outlook アドイン開発入門
Outlook アドイン開発入門Outlook アドイン開発入門
Outlook アドイン開発入門Hiroaki Oikawa
 
ランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナー
ランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナーランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナー
ランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナー株式会社クライム
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知るShuhei Fujita
 
Rdraモデリングをしよう
RdraモデリングをしようRdraモデリングをしよう
RdraモデリングをしようZenji Kanzaki
 
Akkaで分散システム入門
Akkaで分散システム入門Akkaで分散システム入門
Akkaで分散システム入門Shingo Omura
 
Confluence と DITA による Webマニュアル作成フロー
Confluence と DITA によるWebマニュアル作成フローConfluence と DITA によるWebマニュアル作成フロー
Confluence と DITA による Webマニュアル作成フローTakashi Yamaguchi
 
明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化Taiji Tsuchiya
 
オトナのDocker入門
オトナのDocker入門オトナのDocker入門
オトナのDocker入門Tsukasa Kato
 
.NETで動くチケット管理ツール「プリザンター」
.NETで動くチケット管理ツール「プリザンター」.NETで動くチケット管理ツール「プリザンター」
.NETで動くチケット管理ツール「プリザンター」Taiji Uchida
 
10+ Deploys Per Day: Dev and Ops Cooperation at Flickr
10+ Deploys Per Day: Dev and Ops Cooperation at Flickr10+ Deploys Per Day: Dev and Ops Cooperation at Flickr
10+ Deploys Per Day: Dev and Ops Cooperation at FlickrJohn Allspaw
 
忙しい人の5分で分かるMesos入門 - Mesos って何だ?
忙しい人の5分で分かるMesos入門 - Mesos って何だ?忙しい人の5分で分かるMesos入門 - Mesos って何だ?
忙しい人の5分で分かるMesos入門 - Mesos って何だ?Masahito Zembutsu
 
The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)
The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)
The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)Kosetsu Tsukuda
 
Flumeを活用したAmebaにおける大規模ログ収集システム
Flumeを活用したAmebaにおける大規模ログ収集システムFlumeを活用したAmebaにおける大規模ログ収集システム
Flumeを活用したAmebaにおける大規模ログ収集システムSatoshi Iijima
 
Spring fest2020 spring-security
Spring fest2020 spring-securitySpring fest2020 spring-security
Spring fest2020 spring-security土岐 孝平
 

What's hot (20)

L2 over L3 ecnaspsulations
L2 over L3 ecnaspsulationsL2 over L3 ecnaspsulations
L2 over L3 ecnaspsulations
 
モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)
モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)
モノタロウの1900万商品を検索する Elasticsearch構築運用事例(2022-10-26 第50回Elasticsearch 勉強会発表資料)
 
Outlook アドイン開発入門
Outlook アドイン開発入門Outlook アドイン開発入門
Outlook アドイン開発入門
 
ランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナー
ランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナーランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナー
ランサムウェア対策 ”最後の砦” データ保護からみる感染対策セミナー
 
イベント・ソーシングを知る
イベント・ソーシングを知るイベント・ソーシングを知る
イベント・ソーシングを知る
 
OS入門
OS入門OS入門
OS入門
 
Rdraモデリングをしよう
RdraモデリングをしようRdraモデリングをしよう
Rdraモデリングをしよう
 
Akkaで分散システム入門
Akkaで分散システム入門Akkaで分散システム入門
Akkaで分散システム入門
 
Confluence と DITA による Webマニュアル作成フロー
Confluence と DITA によるWebマニュアル作成フローConfluence と DITA によるWebマニュアル作成フロー
Confluence と DITA による Webマニュアル作成フロー
 
明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化明日からはじめるネットワーク運用自動化
明日からはじめるネットワーク運用自動化
 
オトナのDocker入門
オトナのDocker入門オトナのDocker入門
オトナのDocker入門
 
.NETで動くチケット管理ツール「プリザンター」
.NETで動くチケット管理ツール「プリザンター」.NETで動くチケット管理ツール「プリザンター」
.NETで動くチケット管理ツール「プリザンター」
 
エグゼクティブサマリー–サイバー成熟度レビュー
エグゼクティブサマリー–サイバー成熟度レビューエグゼクティブサマリー–サイバー成熟度レビュー
エグゼクティブサマリー–サイバー成熟度レビュー
 
XMPPの紹介
XMPPの紹介XMPPの紹介
XMPPの紹介
 
10+ Deploys Per Day: Dev and Ops Cooperation at Flickr
10+ Deploys Per Day: Dev and Ops Cooperation at Flickr10+ Deploys Per Day: Dev and Ops Cooperation at Flickr
10+ Deploys Per Day: Dev and Ops Cooperation at Flickr
 
Tackling Complexity
Tackling ComplexityTackling Complexity
Tackling Complexity
 
忙しい人の5分で分かるMesos入門 - Mesos って何だ?
忙しい人の5分で分かるMesos入門 - Mesos って何だ?忙しい人の5分で分かるMesos入門 - Mesos って何だ?
忙しい人の5分で分かるMesos入門 - Mesos って何だ?
 
The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)
The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)
The Web Conference 2020 国際会議報告(ACM SIGMOD 日本支部第73回支部大会・依頼講演)
 
Flumeを活用したAmebaにおける大規模ログ収集システム
Flumeを活用したAmebaにおける大規模ログ収集システムFlumeを活用したAmebaにおける大規模ログ収集システム
Flumeを活用したAmebaにおける大規模ログ収集システム
 
Spring fest2020 spring-security
Spring fest2020 spring-securitySpring fest2020 spring-security
Spring fest2020 spring-security
 

Similar to 7 Things You Didn't Know About Exposed

React, Redux, ES2015 by Max Petruck
React, Redux, ES2015 by Max PetruckReact, Redux, ES2015 by Max Petruck
React, Redux, ES2015 by Max PetruckLingvokot
 
React, Redux, ES2015 by Max Petruck
React, Redux, ES2015   by Max PetruckReact, Redux, ES2015   by Max Petruck
React, Redux, ES2015 by Max PetruckMaksym Petruk
 
Functional Principles for OO Developers
Functional Principles for OO DevelopersFunctional Principles for OO Developers
Functional Principles for OO Developersjessitron
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF Luc Bors
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scalaparag978978
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6Dmitry Soshnikov
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Augustin Bralley
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bitsChris Saylor
 
How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)Giuseppe Filograno
 
Java beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designJava beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designPatrick Kostjens
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJSKyung Yeol Kim
 
The Ring programming language version 1.3 book - Part 83 of 88
The Ring programming language version 1.3 book - Part 83 of 88The Ring programming language version 1.3 book - Part 83 of 88
The Ring programming language version 1.3 book - Part 83 of 88Mahmoud Samir Fayed
 

Similar to 7 Things You Didn't Know About Exposed (20)

React, Redux, ES2015 by Max Petruck
React, Redux, ES2015 by Max PetruckReact, Redux, ES2015 by Max Petruck
React, Redux, ES2015 by Max Petruck
 
React, Redux, ES2015 by Max Petruck
React, Redux, ES2015   by Max PetruckReact, Redux, ES2015   by Max Petruck
React, Redux, ES2015 by Max Petruck
 
Functional Principles for OO Developers
Functional Principles for OO DevelopersFunctional Principles for OO Developers
Functional Principles for OO Developers
 
How te bring common UI patterns to ADF
How te bring common UI patterns to ADFHow te bring common UI patterns to ADF
How te bring common UI patterns to ADF
 
Django - sql alchemy - jquery
Django - sql alchemy - jqueryDjango - sql alchemy - jquery
Django - sql alchemy - jquery
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6FalsyValues. Dmitry Soshnikov - ECMAScript 6
FalsyValues. Dmitry Soshnikov - ECMAScript 6
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1Egghead redux-cheat-sheet-3-2-1
Egghead redux-cheat-sheet-3-2-1
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
Javascript: the important bits
Javascript: the important bitsJavascript: the important bits
Javascript: the important bits
 
Saving lives with rx java
Saving lives with rx javaSaving lives with rx java
Saving lives with rx java
 
How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)How to become an Android dev starting from iOS (and vice versa)
How to become an Android dev starting from iOS (and vice versa)
 
Angular2 rxjs
Angular2 rxjsAngular2 rxjs
Angular2 rxjs
 
Java beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application designJava beginners meetup: Introduction to class and application design
Java beginners meetup: Introduction to class and application design
 
Compose Async with RxJS
Compose Async with RxJSCompose Async with RxJS
Compose Async with RxJS
 
Sqlapi0.1
Sqlapi0.1Sqlapi0.1
Sqlapi0.1
 
The Ring programming language version 1.3 book - Part 83 of 88
The Ring programming language version 1.3 book - Part 83 of 88The Ring programming language version 1.3 book - Part 83 of 88
The Ring programming language version 1.3 book - Part 83 of 88
 

Recently uploaded

Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 

Recently uploaded (20)

Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 

7 Things You Didn't Know About Exposed

Editor's Notes

  1. 35s Hi, My name is Alexey Soshin. I’m a contributor to the Exposed framework, and I’m a big fan of it. Today I wanted to talk about a few less known features of that framework. Most of the examples here come from questions asked on GitHub issues of the Exposed project, or on StackOverflow. About the title of my talk, for those that are unfamiliar with Seven Plus Minus Two. It’s the number of things we can hold in our short term memory. In this case, it’s just an escape hatch for me. So I don’t need to commit exactly how many topic I’m going to cover. https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two
  2. 40s Now, let’s start with a quick raise of hands please. How many here are using Hibernate or some other form of JPA in production? Like SpringData or something like that? … And how many of you use Exposed in production? … Ok, great, thank you. That’s just for me to understand how much time I need to spend on discussing what Exposed framework is. And also to check who is either came to the wrong talk, or just didn’t have coffee in the morning.
  3. 40s To set the scene, this is how I usually worked with databases before discovering the Exposed framework. This is from official SpringData GitHub example. To be clear, my intention is not to mock JPA or Hibernate in any way. This is just so I could compare apples to apples, so to say. The top example uses an annotation on an interface and a special language that describes what data should we fetch at runtime.
  4. 40s And the bottom example uses some conventions, like starting the method name with an action, like “remove”. And specifying the columns used in the name of the method. In both cases, you have zero support from your language. If you have an active database connection, and your IDE is very smart, then you may get some support. But not much.
  5. 50s Now, when JetBrains were working on Kotlin, one of their goals was to create a language that would be great for creating DSLs. Funny fact, you can look at the code of the Exposed library, and you will see a lot of commits from their CTO. That was how he tested the limits of the new language his company was creating. What do you get as a result when you use the Exposed library? It provides you with a SQL DSL. So there’s no need to write your SQLs in Strings. No need to remember what the function naming conventions are. You get typesafety provided by the compiler. And autocompletion as a bonus.
  6. If you prefer to work with objects instead of building queries, Exposed framework also provides a DAO API. Here you can see that we invoke methods on the entity, and instead of select they are called find. Instead of writing a delete query, with DAO API you would just invoke a delete method on each object. Whether to use SQL DSL or the DAO API has a lot to do with preferences of your team. DAO API is simpler, and SQL DSL is more poferwul.
  7. ??? But this talk is not the “Convince my company to use Exposed” talk. This is a talk about things you may not known about. So, let’s start with the first point: logging queries. The usual way you log queries in Exposed is by adding a logger to the transaction. That’s how you open a transaction in Exposed, by using a transaction block. And then inside it you can define a logger.
  8. 15s Then each query that you run gets printed to the console like this.
  9. ??? There’s another way to inspect just a single query that you may now know about, though. You can invoke `prepareSQL` method on the query, and it will return you your query as a string. This is useful if you want to run this query yourself. Or do EXPLAIN PLAN on it, for example. There’s a subtle difference between this and using a logger. This method won’t execute the query at all. It will return the SQL, but won’t run it. While the logger prints the query as you try to run it.
  10. 20s If you worked with Exposed, you may have noticed that it supports different column types out of the box, like integer, varchar and all that. But not dates. For dates you need to pick one of the three libraries. Why is that, and which library is the correct one?
  11. The reason that you need to specify the date library explicitly is that Exposed was one of the first Kotlin libraries. And JetBrains started developing it when Java 7 was around, which didn’t have a good Date support. Back in the day, everyone was using JodaTime library for dates. So did JetBrains in their projects. It was natural for them to use JodaTime for representing dates. When Java 8 came out, the Exposed team added support for the Date it came with. And then a few years ago Kotlin has added it’s own DateTime library mainly for the sake of Kotlin Multiplatform. So now there are three date libraries to pick from. If your project is pure Kotlin, you should use DateTime. In other cases, use the Java Time library. I don’t think there’s a good reason to use JodaTime nowadays.
  12. 30s Next topic. When you work with relational databases, you often need to represent a many-to-many relationship. For example here we have users, that can be assigned to groups. A single user can be in multiple groups. And groups of course have multiple users, otherwise those aren’t really groups.
  13. First let’s look at the connection table, that connects users to groups. It doesn’t have anything special defined on it, and the only thing I want to show you here is that this table is called “Members”, because we’ll use that later.
  14. Some may not know that in Exposed, many-to-many relationship is defined using a `via` function. Now, let’s take a look at the Group entity, and focus on the definition on the last line. We say that we’ll fetch users via Members table, using the group_id column as source, and user_id column as target
  15. And just to drive that point home, here’s how it looks from the user perspective. So again we say that we fetch Groups via the members table, and now the source is the user, and the target is the groups that user belongs to.
  16. The next feature is in my opinion pretty well documented, but we still get a lot of questions about, so I decided to cover it anyway. Coroutines and suspending functions as you all know are one of the Kotlin killer features. They allow you to be efficient about IO, and you can run thousands of coroutines concurrently. For those reasons, a lot of functions in Kotlin are suspending functions. But you can’t invoke suspending functions from the Exposed transaction block, because that block is not a suspending function itself. So here we have a simple suspending function, that just waits 10 milliseconds and doesn’t return anything. And if we try to invoke it from a transaction, we get a compilation error.
  17. The way to overcome that is to use “newSuspendedTransaction” provided by Exposed library. This is a suspending function, so from that block you can invoke other suspending functions. You can also nest suspended transactions. For that we have the suspendedTransaction function. So, if you need some fine grained control over your transactions, you can have it with Exposed. You can open one transaction, and inside open an inner transaction, and if any part of that fails, everything will be rolled back.
  18. One subtle detail is that if you decide to use newSuspendedTransaction inside another newSuspendedTransaction, it will do exactly as you tell it to. It will open a completely new transaction. So if the outer transaction rolls back, the inner transaction won’t. Sometimes you want that behavior, sometimes you don’t. So be aware of it, and pick carefully between those two blocks.
  19. Next, let’s look at the following SQL query someone tried to rewrite with Exposed. The SQL part should look pretty straightforward. There’s a varchar type column that says if a message was seen or not. If it wasn’t seen, we map it to null, otherwise, we map it to 1. And then we count how many see messages there are. And count function ignores the nulls. There may be some SQL experts that would say that it could be rewritten is such a way that the NULL is made redundant, but let’s assume that person absolutely had to have that null there.
  20. So, the way you would try to write it is by using the case() builder we have in Exposed. And for those that don’t work with Exposed, slice() function is just Exposed way of specifying which columns you want to query. As you can see, this is pretty similar to the SQL query, and you get autompletion, so it isn’t hard to write. The problem we have here is that you cannot pass “NULL” as a string, and you also can’t pass Kotlin’s null. So it’s not very intuitive what should you do there.
  21. The way that problem can be solved is by using a NullOp Exposed provides. It’s an expression, and the value it returns is SQL NULL. Now remember, case is also an expression, and its result is the number of read messages user has or something like that. So we need to specify the type of the null, and its type in this case is integer. That’s why we have that nullOp<Int> there
  22. If we were allowed to rewrite that query slightly, and have the NullOp in the Else case, for example, then Kotlin generic type inference would kick in, and we wouldn’t have to specify the type of the null.
  23. I mentioned earlier that Exposed has two syntaxes: the SQL DSL syntax and the DAO syntax. Sometimes you have a complex query that you’ve written with Exposed SQL DSL. And now you want to convert its results to DAO entities. You can do a mapping yourself, but there’s a better way to do it.
  24. There’s a method called `wrapRows` in Exposed, that is available on each entity. It takes the query, and attempts to map it. So there’s no need to do that work manually. Exposed can do it for you. There’s also a method that is called wrapRow, that works on a single row.
  25. I think that’s my final point for today. Now, I talked a lot about how the aim of Exposed framework is to provide a type safe and ergonomic way to work with databases. And I hope that I showed a few tricks how to do that efficiently. Maybe I even convinced some of you to give Exposed a try. But sometimes, a database feature is too specific or too new for us to implement it. So, there is an exec method available to you inside a transaction, and that method will execute an arbitrary prepared statement. This method exposes a low level Java API, so you have an awkward iterator and indexes that start with 1. Not recommended, but that option is left to you.
  26. Well, let’s quickly recap the things you may have not known. In Exposed, you can log a single query, no need to log all of them. We discussed why Exposed requires you to pick the date library you work with, and that by default, you should pick Kotlin DateTime Exposed provides you with a flexible way to define many-to-many relationships using via fucntion There’s coroutine support, so if your code uses suspending functions, it’s not a problem for Exposed. Use newSuspendedTransaction If you need to use NULL in your query, there’s a special expression for that. You also don’t have to map SQL DSL to entities manually, Exposed can do this for you. And finally, you can break Exposed and use arbitrary statements if you really have to.
  27. That’s all the features I wanted to talk about today. If you have questions on how to use some of the Exposed features, me and other contributors will be happy to answer them on StackOverflow. If you find any bugs related to Exposed library, you can open a GitHub issue, and the team will look into it. And if you have an idea for improving the library, Pull Requests are more than welcome!
  28. If you’re interested to learn more about the Exposed framework, I just finished recording the first course on Exposed for LinkedIn Learning. It should be out beginning of 2023.
  29. Thank you for coming to my talk. If you enjoyed it, you can follow me on LinkedIn, Medium or Twitter. I’m an author of a video course on System Design that is published on Udemy, so if you’re interested in Software Architecture, there’s a coupon that will provide you this course for free. Also, I’m an author of Kotlin Design Patterns and Best Practices book. Check it out on Amazon.
  30. And last thing I wanted to say as someone who was born in Ukraine. Thank you for all your support. Glory to Ukraine! Enjoy the rest of this great conference. Thank you.