Skip to content

Instantly share code, notes, and snippets.

@AmaranthLIS
Forked from mustafo/ContactPhonesTest.kt
Created November 19, 2020 22:07
Show Gist options
  • Save AmaranthLIS/6ded35d7ce48a0f8514100b03691472f to your computer and use it in GitHub Desktop.
Save AmaranthLIS/6ded35d7ce48a0f8514100b03691472f to your computer and use it in GitHub Desktop.
The right way to use one to many relationship in jdbi with kotlin
import org.jdbi.v3.core.kotlin.KotlinMapper
import org.jdbi.v3.core.mapper.RowMapperFactory
import org.junit.jupiter.api.Test
import tj.alif.core.app.db.RepositoryTest
import org.jdbi.v3.core.result.RowView
data class Contact (
val id: Int,
val name: String,
var phones: MutableList<Phone> = mutableListOf()
) {
fun addPhone(phone: Phone) = phones.add(phone)
}
data class Phone (val id: Int,
val type: String,
val number: String
)
fun factory(type: Class<*>, prefix: String): RowMapperFactory {
return RowMapperFactory.of(type, KotlinMapper(type, prefix))
}
class ContactPhonesTest: RepositoryTest() {
@Test
fun `some test`() {
val SELECT_ALL = ("select contacts.id c_id, name c_name, "
+ "phones.id p_id, type p_type, phones.number p_number "
+ "from contacts left join phones on contacts.id = phones.contact_id "
+ "order by c_name, p_type")
val contacts = db.createQuery(SELECT_ALL)
.registerRowMapper(factory(Contact::class.java, "c"))
.registerRowMapper(factory(Phone::class.java, "p"))
.reduceRows(linkedMapOf()) { map: LinkedHashMap<Int, Contact>, rowView: RowView ->
val contact = map.computeIfAbsent(rowView.getColumn("c_id", Int::class.javaObjectType)) {
rowView.getRow(Contact::class.java)
}
if (rowView.getColumn("p_id", Int::class.javaObjectType) != null) {
contact.addPhone(rowView.getRow(Phone::class.java))
}
map
}
.toList().map { it.second }
println(contacts)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment