Skip to content

Instantly share code, notes, and snippets.

@mustafo
Created August 31, 2018 04:31
Show Gist options
  • Save mustafo/36e9f754aaefc85924eb0ddc276d970e to your computer and use it in GitHub Desktop.
Save mustafo/36e9f754aaefc85924eb0ddc276d970e 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)
}
}
@stepbeekio
Copy link

👍 This was very helpful, thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment