最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot Mybatis++ 2025詳解

 更新時間:2025年02月05日 09:25:01   作者:ByteFlys  
文章介紹了三種基于注解SQL和查詢接口的MyBatis使用方式,討論了Entity和Example的區(qū)別,即Entity會更新所有字段,而Example僅更新非空字段,感興趣的朋友一起看看吧

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 }
}

到此這篇關于Spring Boot Mybatis++ 2025的文章就介紹到這了,更多相關Spring Boot Mybatis++ 2025內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • java?NIO實現(xiàn)簡單聊天程序

    java?NIO實現(xiàn)簡單聊天程序

    這篇文章主要為大家詳細介紹了java?NIO實現(xiàn)簡單聊天程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Java中值類型和引用類型詳解

    Java中值類型和引用類型詳解

    大家好,本篇文章主要講的是Java中值類型和引用類型詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 玩轉(zhuǎn)SpringBoot中的那些連接池(小結(jié))

    玩轉(zhuǎn)SpringBoot中的那些連接池(小結(jié))

    這篇文章主要介紹了玩轉(zhuǎn)SpringBoot中的那些連接池(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Java之PreparedStatement的使用詳解

    Java之PreparedStatement的使用詳解

    這篇文章主要介紹了Java之PreparedStatement的使用詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 官方詳解HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)

    官方詳解HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)

    這篇文章主要為大家介紹了HDFS?Balancer工具主要調(diào)優(yōu)參數(shù)的?官方詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Java基于FFmpeg實現(xiàn)Mp4視頻轉(zhuǎn)GIF

    Java基于FFmpeg實現(xiàn)Mp4視頻轉(zhuǎn)GIF

    FFmpeg是一套可以用來記錄、轉(zhuǎn)換數(shù)字音頻、視頻,并能將其轉(zhuǎn)化為流的開源計算機程序。本文主要介紹了在Java中如何基于FFmpeg進行Mp4視頻到Gif動圖的轉(zhuǎn)換,感興趣的小伙伴可以了解一下
    2022-11-11
  • SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法

    SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法

    這篇文章主要介紹了SpringBoot中MyBatis-Plus 查詢時排除某些字段的操作方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Java Lambda表達式與引用類淺析

    Java Lambda表達式與引用類淺析

    Lambda表達式是Java SE8中一個重要的新特性,允許通過表達式來代替功能接口。本文將通過一些簡單的示例和大家講講Lamda表達式的使用,感興趣的可以了解一下
    2023-01-01
  • Java中SpringBoot的TCC事務詳解

    Java中SpringBoot的TCC事務詳解

    這篇文章主要介紹了Java中SpringBoot的TCC事務詳解,近年來,隨著微服務架構(gòu)的普及,TCC?事務成為了一種非常流行的分布式事務解決方案,在?Spring?Boot?中,我們可以很容易地使用?TCC?事務來管理分布式事務,需要的朋友可以參考下
    2023-07-07
  • java 中ThreadLocal 的正確用法

    java 中ThreadLocal 的正確用法

    這篇文章主要介紹了java 中ThreadLocal 的正確用法的相關資料,需要的朋友可以參考下
    2017-03-03

最新評論

舒兰市| 巢湖市| 桦川县| 化州市| 北辰区| 印江| 资溪县| 南通市| 南汇区| 建平县| 白山市| 维西| 南阳市| 丁青县| 林州市| 牡丹江市| 柏乡县| 垫江县| 辽中县| 台中县| 建始县| 无为县| 贵阳市| 景德镇市| 敖汉旗| 桃江县| 罗山县| 新源县| 石狮市| 广灵县| 宁都县| 得荣县| 湾仔区| 奉新县| 富宁县| 包头市| 十堰市| 右玉县| 诸暨市| 兰考县| 蓬溪县|