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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 5分鐘快速搭建SpringBoot3?+?MyBatis-Plus工程/項(xiàng)目的實(shí)現(xiàn)示例
- 解決mybatis-plus-boot-starter與mybatis-spring-boot-starter的錯(cuò)誤問(wèn)題
- Spring Boot 中整合 MyBatis-Plus詳細(xì)步驟(最新推薦)
- Spring?Boot?集成?MyBatis?全面講解(最新推薦)
- Spring Boot 中使用 Mybatis Plus的操作方法
- SpringBoot同時(shí)集成Mybatis和Mybatis-plus框架
- Springboot使用MybatisPlus實(shí)現(xiàn)mysql樂(lè)觀鎖
- 淺談Spring Boot、MyBatis、MyBatis-Plus 依賴版本對(duì)應(yīng)關(guān)系
相關(guān)文章
Java Semaphore實(shí)現(xiàn)高并發(fā)場(chǎng)景下的流量控制
在java開(kāi)發(fā)的工作中是否會(huì)出現(xiàn)這樣的場(chǎng)景,你需要實(shí)現(xiàn)一些異步運(yùn)行的任務(wù),該任務(wù)可能存在消耗大量?jī)?nèi)存的情況,所以需要對(duì)任務(wù)進(jìn)行并發(fā)控制。本文將介紹通過(guò)Semaphore類優(yōu)雅的實(shí)現(xiàn)并發(fā)控制,感興趣的可以了解一下2021-12-12詳解springboot接口如何優(yōu)雅的接收時(shí)間類型參數(shù)
這篇文章主要為大家詳細(xì)介紹了springboot的接口如何優(yōu)雅的接收時(shí)間類型參數(shù),文中為大家整理了三種常見(jiàn)的方法,希望對(duì)大家有一定的幫助2023-09-09Java單例模式利用HashMap實(shí)現(xiàn)緩存數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Java單例模式利用HashMap實(shí)現(xiàn)緩存數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04SpringBoot使用Scheduling實(shí)現(xiàn)定時(shí)任務(wù)的示例代碼
Spring Boot提供了一種方便的方式來(lái)實(shí)現(xiàn)定時(shí)任務(wù),即使用Spring的@Scheduled注解,通過(guò)在方法上添加@Scheduled注解,我們可以指定方法在何時(shí)執(zhí)行,本文我們就給大家介紹一下SpringBoot如何使用Scheduling實(shí)現(xiàn)定時(shí)任務(wù),需要的朋友可以參考下2023-08-08springboot部署linux訪問(wèn)服務(wù)器資源的方法
這篇文章主要介紹了springboot部署linux訪問(wèn)服務(wù)器資源,部署springboot項(xiàng)目至服務(wù)器用了幾種不同方法,文中給大家詳細(xì)介紹,需要的朋友可以參考下2019-12-12解決執(zhí)行maven命令時(shí)提示Process terminated的問(wèn)題
這篇文章主要介紹了解決執(zhí)行maven命令時(shí)提示Process terminated的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09JAVA得到數(shù)組中最大值和最小值的簡(jiǎn)單實(shí)例
這篇文章主要介紹了JAVA得到數(shù)組中最大值和最小值的簡(jiǎn)單實(shí)例,需要的朋友可以參考下2014-08-08