Skip to content

Commit 90ddb51

Browse files
committed
Example of a Custom Condition in Kotlin
1 parent 1d4dbe1 commit 90ddb51

File tree

2 files changed

+105
-18
lines changed

2 files changed

+105
-18
lines changed
Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,54 @@
11
package examples.kotlin.mybatis3.mariadb
22

3+
import java.util.function.Predicate
4+
import java.util.function.Function
35
import org.mybatis.dynamic.sql.AbstractSingleValueCondition
46
import org.mybatis.dynamic.sql.BindableColumn
57
import org.mybatis.dynamic.sql.render.RenderingContext
68
import org.mybatis.dynamic.sql.util.FragmentAndParameters
7-
import java.util.function.Predicate
89

9-
open class KIsLikeEscape<T : Any>(value: T, private val escapeCharacter: Char? = null) : AbstractSingleValueCondition<T>(value) {
10+
sealed class KIsLikeEscape<T : Any>(
11+
value: T,
12+
private val escapeCharacter: Char? = null
13+
) : AbstractSingleValueCondition<T>(value) {
1014

1115
override fun operator(): String = "like"
1216

1317
override fun renderCondition(
1418
renderingContext: RenderingContext,
1519
leftColumn: BindableColumn<T>
16-
): FragmentAndParameters {
17-
val f = super.renderCondition(renderingContext, leftColumn)
18-
19-
return escapeCharacter?.let { f.mapFragment{ "$it ESCAPE '$escapeCharacter'"} } ?: f
20+
): FragmentAndParameters = with(super.renderCondition(renderingContext, leftColumn)) {
21+
escapeCharacter?.let { mapFragment { "$it ESCAPE '$escapeCharacter'" } } ?: this
2022
}
2123

22-
override fun filter(predicate: Predicate<in T>): KIsLikeEscape<T> {
23-
return filterSupport(predicate, ::empty, this)
24-
}
24+
override fun filter(predicate: Predicate<in T>): KIsLikeEscape<T> =
25+
filterSupport(predicate, EmptyIsLikeEscape::empty, this)
2526

26-
fun <R : Any> map(mapper : (T) -> R): KIsLikeEscape<R> {
27-
return mapSupport(mapper, { r -> KIsLikeEscape(r, escapeCharacter) }, ::empty)
27+
fun <R : Any> map(mapper : Function<in T, out R>): KIsLikeEscape<R> =
28+
mapSupport(mapper, { r -> ConcreteIsLikeEscape(r, escapeCharacter) }, EmptyIsLikeEscape::empty)
29+
30+
companion object {
31+
fun <T: Any> isLike(value: T, escapeCharacter: Char? = null) : KIsLikeEscape<T> =
32+
ConcreteIsLikeEscape(value, escapeCharacter)
2833
}
34+
}
35+
36+
private class ConcreteIsLikeEscape<T: Any>(
37+
value: T,
38+
escapeCharacter: Char? = null
39+
) : KIsLikeEscape<T>(value, escapeCharacter)
2940

30-
private class EmptyCondition : KIsLikeEscape<Any>(-1) {
31-
override fun isEmpty(): Boolean = true
41+
private class EmptyIsLikeEscape : KIsLikeEscape<Any>(-1) {
42+
override fun isEmpty(): Boolean = true
3243

33-
override fun value(): Any {
34-
throw NoSuchElementException("No value present") //$NON-NLS-1$
35-
}
44+
override fun value(): Any {
45+
throw NoSuchElementException("No value present")
3646
}
3747

3848
companion object {
39-
private val EMPTY: KIsLikeEscape<Any> = EmptyCondition()
49+
private val EMPTY: KIsLikeEscape<Any> = EmptyIsLikeEscape()
4050

4151
@Suppress("UNCHECKED_CAST")
42-
fun <T : Any> empty(): KIsLikeEscape<T> = EMPTY as KIsLikeEscape<T>
52+
internal fun <T : Any> empty(): KIsLikeEscape<T> = EMPTY as KIsLikeEscape<T>
4353
}
4454
}

src/test/kotlin/examples/kotlin/mybatis3/mariadb/KMariaDBTest.kt

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import org.mybatis.dynamic.sql.util.mybatis3.CommonUpdateMapper
3838
import org.testcontainers.containers.MariaDBContainer
3939
import org.testcontainers.junit.jupiter.Container
4040
import org.testcontainers.junit.jupiter.Testcontainers
41+
import java.util.*
4142

4243
@Testcontainers
4344
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@@ -142,6 +143,82 @@ class KMariaDBTest {
142143
}
143144
}
144145

146+
@Test
147+
fun testIsLikeEscape() {
148+
sqlSessionFactory.openSession().use { session ->
149+
val mapper = session.getMapper(CommonSelectMapper::class.java)
150+
val selectStatement = select(id, description) {
151+
from(items)
152+
where {
153+
description(KIsLikeEscape.isLike("Item 1%", '#'))
154+
}
155+
}
156+
157+
assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR} ESCAPE '#'")
158+
assertThat(selectStatement.parameters).containsEntry("p1", "Item 1%")
159+
160+
val rows = mapper.selectManyMappedRows(selectStatement)
161+
assertThat(rows).hasSize(11)
162+
}
163+
}
164+
165+
@Test
166+
fun testIsLikeEscapeNoEscapeCharacter() {
167+
val selectStatement = select(id, description) {
168+
from(items)
169+
where {
170+
description(KIsLikeEscape.isLike("%fred%"))
171+
}
172+
}
173+
174+
assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR}")
175+
assertThat(selectStatement.parameters).containsEntry("p1", "%fred%")
176+
}
177+
178+
@Test
179+
fun testIsLikeEscapeMap() {
180+
val selectStatement = select(id, description) {
181+
from(items)
182+
where {
183+
description(KIsLikeEscape.isLike("%fred%", '#').map { s -> s.uppercase(Locale.getDefault()) })
184+
}
185+
}
186+
187+
assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items where description like #{parameters.p1,jdbcType=VARCHAR} ESCAPE '#'")
188+
assertThat(selectStatement.parameters).containsEntry("p1", "%FRED%")
189+
}
190+
191+
@Test
192+
fun testIsLikeEscapeFilter() {
193+
val selectStatement = select(id, description) {
194+
from(items)
195+
where {
196+
description(KIsLikeEscape.isLike("%fred%", '#').filter { _ -> false })
197+
}
198+
configureStatement { isNonRenderingWhereClauseAllowed = true }
199+
}
200+
201+
assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items")
202+
assertThat(selectStatement.parameters).isEmpty()
203+
}
204+
205+
@Test
206+
fun testIsLikeEscapeFilterMapFilter() {
207+
val selectStatement = select(id, description) {
208+
from(items)
209+
where {
210+
description(KIsLikeEscape.isLike("%fred%", '#')
211+
.filter { _ -> true }
212+
.map { s -> s.uppercase(Locale.getDefault()) }
213+
.filter{_ -> false })
214+
}
215+
configureStatement { isNonRenderingWhereClauseAllowed = true }
216+
}
217+
218+
assertThat(selectStatement.selectStatement).isEqualTo("select id, description from items")
219+
assertThat(selectStatement.parameters).isEmpty()
220+
}
221+
145222
companion object {
146223
@Container
147224
private val mariadb = MariaDBContainer(TestContainersConfiguration.MARIADB_LATEST)

0 commit comments

Comments
 (0)