Spring Boot Mybatis++ 2025詳解
Structure
this blog introduce 3 ways using mybatis
- based on annotationed SQL and Query interfaces : suppored by MyBatis framework
- based on Query Wrapper : supported by MyBatis Plus framework
- MyBatis Plus provides a easier way to dynamically set condition and updated fields
- base on Query Condition : combined MyBatis Plus and Kotlin, so called MyBatis++
- MyBatis++ provides a more easier way to build complicated conditions
- and supports update values through an Example bean
MyBatis++ Controller Abilities
this controller present multiple ways to do CURD with MyBatis++
you can choose your favorite ones or those match your current project most comfortably
package x.spring.hello.controller
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RestController
import x.kotlin.commons.serialize.JSON.toJson
import x.kotlin.commons.serialize.JSON.toJsonOrNull
import x.kotlin.commons.string.UUID
import x.spring.hello.model.User
import x.spring.hello.model.UserExample
import x.spring.hello.repository.UserMapper
import x.spring.hello.mybatis.*
@RestController
class UserController {
@Autowired
private lateinit var userMapper: UserMapper
@GetMapping("/01")
fun selectAll(): String {
val userList = userMapper.selectAll()
return userList.toJson()
}
@GetMapping("/02")
fun selectByName(): String {
val user = userMapper.selectUserByName("Jimmy")
return user.toJsonOrNull().orEmpty()
}
@GetMapping("/03")
fun selectByCondition(): String {
val condition = condition { it.eq(User::name, "Jimmy") }
val users = userMapper.selectList(condition.build())
return users.toJson()
}
@GetMapping("/04")
fun insert(): String {
val user = User()
user.name = UUID.short()
userMapper.insert(user)
return user.toJson()
}
@GetMapping("/05")
fun insertOrUpdate(): String {
val user = User()
user.id = "1"
user.name = UUID.short()
userMapper.insertOrUpdate(user)
return user.toJson()
}
@GetMapping("/06")
fun updateByCondition(): String {
val cond1 = condition { it.isNotNull(User::id) }
val cond2 = condition { it.eq(User::name, "Jimmy") }
val cond3 = condition { it.gt(User::age, 15) }
val cond4 = condition {
it.set(User::name, "Jimmy")
it.set(User::age, 18)
}
val condition = cond1 and cond2 and cond3 attributes cond4
val count = userMapper.update(condition.build())
return count.toJson()
}
@GetMapping("/07")
fun updateByEntityAndCondition(): String {
val entity = User()
entity.name = "Updated"
entity.age = 36
val cond1 = condition { it.isNotNull(User::id) }
val cond2 = condition { it.like(User::name, "Jimmy") }
val cond3 = condition { it.gt(User::age, 35) }
val condition = cond1 and (cond2 or cond3)
val count = userMapper.update(entity, condition.build())
return count.toJson()
}
@GetMapping("/08")
fun updateByExampleAndCondition(): String {
val example = UserExample()
example.age = 18
val cond1 = condition { it.isNotNull(User::id) }
val cond2 = condition { it.like(User::name, "Jimmy") }
val cond3 = condition { it.gt(User::age, 35) }
val condition = cond1 and (cond2 or cond3) values example
val count = userMapper.update(condition.build())
return count.toJson()
}
@GetMapping("/09")
fun selectCrossTables(): String {
val userRoles = userMapper.selectUserRole()
return userRoles.toJson()
}
}Configure Plugins and Repositories
pluginManagement {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
dependencyResolutionManagement {
repositoriesMode = RepositoriesMode.PREFER_SETTINGS
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
buildscript {
repositories {
gradlePluginPortal()
google()
mavenCentral()
}
}
plugins {
id("org.jetbrains.kotlin.jvm") version "2.0.21" apply false
id("org.jetbrains.kotlin.kapt") version "2.0.21" apply false
id("org.jetbrains.kotlin.plugin.spring") version "2.0.21" apply false
id("org.springframework.boot") version "3.4.1" apply false
}
include("spring-mybatis")Apply Plugins and Add Dependencies
plugins {
id("org.jetbrains.kotlin.jvm")
id("org.jetbrains.kotlin.kapt")
id("org.jetbrains.kotlin.plugin.spring")
id("org.springframework.boot")
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
}
}
dependencies {
val springBootVersion = "3.4.1"
val springCloudVersion = "4.2.0"
val springCloudAlibabaVersion = "2023.0.3.2"
// commons
api("io.github.hellogoogle2000:kotlin-commons:1.0.19")
// kotlin
api("org.jetbrains.kotlin:kotlin-reflect:2.0.21")
// spring
api("org.springframework.boot:spring-boot-starter:$springBootVersion")
api("org.springframework.boot:spring-boot-starter-web:$springBootVersion")
api("org.springframework.cloud:spring-cloud-starter-bootstrap:$springCloudVersion")
// mybatis
api("link.thingscloud:quick-spring-boot-starter-mybatis-plus:2025.01.22")
}MyBatis++ Spring Properties
# service server.port=10003 spring.application.name=mybatis spring.profiles.active=dev spring.devtools.add-properties=false # mybatis spring.datasource.username=root spring.datasource.password=123456789 spring.datasource.url=jdbc:mysql://localhost:3306/dev?characterEncoding=utf-8&serverTimezone=UTC
MyBatis++ Application
package x.spring.hello
import org.mybatis.spring.annotation.MapperScan
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
@SpringBootApplication
@MapperScan(basePackages = ["x.spring.hello.repository"])
class MybatisApplication
fun main(args: Array<String>) {
runApplication<MybatisApplication>(*args)
}MyBatis++ Beans
package x.spring.hello.model
import com.baomidou.mybatisplus.annotation.IdType
import com.baomidou.mybatisplus.annotation.TableId
class User {
@TableId(type = IdType.ASSIGN_UUID)
var id = ""
var name = ""
var age = 0
}package x.spring.hello.model
class UserExample {
var id: String? = null
var name: String? = null
var age: Int? = null
}package x.spring.hello.model
class UserRoleQueryResult {
var name = ""
var role = ""
}MyBatis++ Mapper
mapper sometimes called interface, service or repository in other projects
package x.spring.hello.repository
import link.thingscloud.quick.mybatisplus.base.BaseMapper
import org.apache.ibatis.annotations.Select
import x.spring.hello.model.User
import x.spring.hello.model.UserRoleQueryResult
interface UserMapper : BaseMapper<User> {
@Select("select * from user")
fun selectAll(): MutableList<User>
@Select("select * from user where name = #{name}")
fun selectUserByName(name: String): User?
@Select(
"""
select
user.name as name,
role.name as role
from user left join role
on user.roleId = role.id
"""
)
fun selectUserRole(): List<UserRoleQueryResult>
}MyBatis++ Query Builder
this is the core component to build query condition and examples
difference between entity and example is :
entity will update all field, while example only update non-null fields
package x.spring.hello.mybatis
import com.baomidou.mybatisplus.extension.kotlin.KtUpdateWrapper
import kotlin.reflect.KClass
import kotlin.reflect.KProperty1
import kotlin.reflect.full.memberProperties
fun interface ConditionConfigurator<T : Any> {
fun configure(wrapper: KtUpdateWrapper<T>)
}
data class QueryCondition<T : Any>(
val configurator: ConditionConfigurator<T>
)
inline fun <reified T : Any> QueryCondition<T>.build(): KtUpdateWrapper<T> {
val wrapper = KtUpdateWrapper(T::class.java)
configurator.configure(wrapper)
return wrapper
}
inline fun <reified T : Any> condition(configurator: ConditionConfigurator<T>): QueryCondition<T> {
return QueryCondition(configurator)
}
infix fun <T : Any> QueryCondition<T>.and(other: QueryCondition<T>): QueryCondition<T> {
val configurator = ConditionConfigurator {
configurator.configure(it)
it.and { other.configurator.configure(it) }
}
return QueryCondition(configurator)
}
infix fun <T : Any> QueryCondition<T>.or(other: QueryCondition<T>): QueryCondition<T> {
val configurator = ConditionConfigurator {
configurator.configure(it)
it.or { other.configurator.configure(it) }
}
return QueryCondition(configurator)
}
infix fun <T : Any> QueryCondition<T>.not(other: QueryCondition<T>): QueryCondition<T> {
val configurator = ConditionConfigurator {
configurator.configure(it)
it.not { other.configurator.configure(it) }
}
return QueryCondition(configurator)
}
infix fun <T : Any> QueryCondition<T>.attributes(other: QueryCondition<T>): QueryCondition<T> {
val configurator = ConditionConfigurator {
configurator.configure(it)
other.configurator.configure(it)
}
return QueryCondition(configurator)
}
inline infix fun <reified T : Any, reified S : Any> QueryCondition<T>.values(example: S): QueryCondition<T> {
val configurator = ConditionConfigurator { wrapper ->
configurator.configure(wrapper)
val properties = S::class.memberProperties
properties.forEach { propertyS ->
val value = propertyS.get(example)
value.takeIf { it != null } ?: return@forEach
val property = T::class.findPropertyByName(propertyS.name)
property.takeIf { it != null } ?: return@forEach
wrapper.set(property, value)
}
}
return QueryCondition(configurator)
}
inline fun <reified T : Any> KClass<T>.findPropertyByName(name: String): KProperty1<T, *>? {
return memberProperties.firstOrNull { it.name == name }
}到此這篇關(guān)于Spring Boot Mybatis++ 2025的文章就介紹到這了,更多相關(guān)Spring Boot Mybatis++ 2025內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 5分鐘快速搭建SpringBoot3?+?MyBatis-Plus工程/項目的實現(xiàn)示例
- 解決mybatis-plus-boot-starter與mybatis-spring-boot-starter的錯誤問題
- Spring Boot 中整合 MyBatis-Plus詳細步驟(最新推薦)
- Spring?Boot?集成?MyBatis?全面講解(最新推薦)
- Spring Boot 中使用 Mybatis Plus的操作方法
- SpringBoot同時集成Mybatis和Mybatis-plus框架
- Springboot使用MybatisPlus實現(xiàn)mysql樂觀鎖
- 淺談Spring Boot、MyBatis、MyBatis-Plus 依賴版本對應(yīng)關(guān)系
相關(guān)文章
Java Semaphore實現(xiàn)高并發(fā)場景下的流量控制
在java開發(fā)的工作中是否會出現(xiàn)這樣的場景,你需要實現(xiàn)一些異步運行的任務(wù),該任務(wù)可能存在消耗大量內(nèi)存的情況,所以需要對任務(wù)進行并發(fā)控制。本文將介紹通過Semaphore類優(yōu)雅的實現(xiàn)并發(fā)控制,感興趣的可以了解一下2021-12-12
詳解springboot接口如何優(yōu)雅的接收時間類型參數(shù)
這篇文章主要為大家詳細介紹了springboot的接口如何優(yōu)雅的接收時間類型參數(shù),文中為大家整理了三種常見的方法,希望對大家有一定的幫助2023-09-09
Java單例模式利用HashMap實現(xiàn)緩存數(shù)據(jù)
這篇文章主要為大家詳細介紹了Java單例模式利用HashMap實現(xiàn)緩存數(shù)據(jù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-04-04
SpringBoot使用Scheduling實現(xiàn)定時任務(wù)的示例代碼
Spring Boot提供了一種方便的方式來實現(xiàn)定時任務(wù),即使用Spring的@Scheduled注解,通過在方法上添加@Scheduled注解,我們可以指定方法在何時執(zhí)行,本文我們就給大家介紹一下SpringBoot如何使用Scheduling實現(xiàn)定時任務(wù),需要的朋友可以參考下2023-08-08
springboot部署linux訪問服務(wù)器資源的方法
這篇文章主要介紹了springboot部署linux訪問服務(wù)器資源,部署springboot項目至服務(wù)器用了幾種不同方法,文中給大家詳細介紹,需要的朋友可以參考下2019-12-12
解決執(zhí)行maven命令時提示Process terminated的問題
這篇文章主要介紹了解決執(zhí)行maven命令時提示Process terminated的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09

