Kaynağa Gözat

添加kotlin链式调用支持

FlyInWind 4 yıl önce
ebeveyn
işleme
5f8ae61394

+ 3 - 3
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/conditions/AbstractChainWrapper.java

@@ -37,8 +37,8 @@ import java.util.function.Consumer;
  * @author miemie
  * @since 2018-12-19
  */
-@SuppressWarnings({"serial", "unchecked", "rawtypes"})
-public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainWrapper<T, R, Children, Param>, Param extends AbstractWrapper>
+@SuppressWarnings({"serial", "unchecked"})
+public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainWrapper<T, R, Children, Param>, Param extends AbstractWrapper<T, R, Param>>
     extends Wrapper<T> implements Compare<Children, R>, Func<Children, R>, Join<Children>, Nested<Param, Children> {
 
     protected final Children typedThis = (Children) this;
@@ -53,7 +53,7 @@ public abstract class AbstractChainWrapper<T, R, Children extends AbstractChainW
     public AbstractChainWrapper() {
     }
 
-    public AbstractWrapper getWrapper() {
+    public AbstractWrapper<T, R, Param> getWrapper() {
         return wrapperChildren;
     }
 

+ 31 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/IService.java

@@ -27,6 +27,8 @@ import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
 import com.baomidou.mybatisplus.extension.conditions.update.ChainUpdate;
 import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
 import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
+import com.baomidou.mybatisplus.extension.kotlin.KtQueryChainWrapper;
+import com.baomidou.mybatisplus.extension.kotlin.KtUpdateChainWrapper;
 import com.baomidou.mybatisplus.extension.toolkit.ChainWrappers;
 import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
 import org.springframework.transaction.annotation.Transactional;
@@ -96,7 +98,7 @@ public interface IService<T> {
      * @param batchSize  每次的数量
      */
     boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
-    
+
     /**
      * 根据 ID 删除
      *
@@ -189,7 +191,7 @@ public interface IService<T> {
      * @param entity 实体对象
      */
     boolean saveOrUpdate(T entity);
-    
+
     /**
      * 根据 ID 查询
      *
@@ -386,6 +388,13 @@ public interface IService<T> {
      */
     BaseMapper<T> getBaseMapper();
 
+    /**
+     * 获取 entity 的 class
+     *
+     * @return {@link Class<T>}
+     */
+    Class<T> getEntityClass();
+
     /**
      * 以下的方法使用介绍:
      *
@@ -422,6 +431,26 @@ public interface IService<T> {
         return ChainWrappers.lambdaQueryChain(getBaseMapper());
     }
 
+    /**
+     * 链式查询 lambda 式
+     * kotlin 使用
+     *
+     * @return KtQueryWrapper 的包装类
+     */
+    default KtQueryChainWrapper<T> ktQuery() {
+        return ChainWrappers.ktQueryChain(getBaseMapper(), getEntityClass());
+    }
+
+    /**
+     * 链式查询 lambda 式
+     * kotlin 使用
+     *
+     * @return KtQueryWrapper 的包装类
+     */
+    default KtUpdateChainWrapper<T> ktUpdate() {
+        return ChainWrappers.ktUpdateChain(getBaseMapper(), getEntityClass());
+    }
+
     /**
      * 链式更改 普通
      *

+ 7 - 2
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/service/impl/ServiceImpl.java

@@ -58,9 +58,14 @@ public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
         return baseMapper;
     }
 
-    protected Class<?> entityClass = currentModelClass();
+    protected Class<T> entityClass = currentModelClass();
 
-    protected Class<?> mapperClass = currentMapperClass();
+    @Override
+    public Class<T> getEntityClass() {
+        return entityClass;
+    }
+
+    protected Class<T> mapperClass = currentMapperClass();
 
     /**
      * 判断数据库操作是否成功

+ 43 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/toolkit/ChainWrappers.java

@@ -20,6 +20,8 @@ import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapp
 import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
 import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
 import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
+import com.baomidou.mybatisplus.extension.kotlin.KtQueryChainWrapper;
+import com.baomidou.mybatisplus.extension.kotlin.KtUpdateChainWrapper;
 
 /**
  * 快捷构造 chain 式调用的工具类
@@ -53,6 +55,26 @@ public final class ChainWrappers {
         return new LambdaQueryChainWrapper<>(mapper);
     }
 
+    /**
+     * 链式查询 lambda 式
+     * 仅支持 Kotlin
+     *
+     * @return KtQueryWrapper 的包装类
+     */
+    public static <T> KtQueryChainWrapper<T> ktQueryChain(BaseMapper<T> mapper, Class<T> entityClass) {
+        return new KtQueryChainWrapper<>(mapper, entityClass);
+    }
+
+    /**
+     * 链式查询 lambda 式
+     * 仅支持 Kotlin
+     *
+     * @return KtQueryWrapper 的包装类
+     */
+    public static <T> KtQueryChainWrapper<T> ktQueryChain(BaseMapper<T> mapper, T entity) {
+        return new KtQueryChainWrapper<>(mapper, entity);
+    }
+
     /**
      * 链式更改 普通
      *
@@ -71,4 +93,25 @@ public final class ChainWrappers {
     public static <T> LambdaUpdateChainWrapper<T> lambdaUpdateChain(BaseMapper<T> mapper) {
         return new LambdaUpdateChainWrapper<>(mapper);
     }
+
+    /**
+     * 链式更改 lambda 式
+     * 仅支持 Kotlin
+     *
+     * @return KtQueryWrapper 的包装类
+     */
+    public static <T> KtUpdateChainWrapper<T> ktUpdateChain(BaseMapper<T> mapper, Class<T> entityClass) {
+        return new KtUpdateChainWrapper<>(mapper, entityClass);
+    }
+
+    /**
+     * 链式更改 lambda 式
+     * 仅支持 Kotlin
+     *
+     * @return KtQueryWrapper 的包装类
+     */
+    public static <T> KtUpdateChainWrapper<T> ktUpdateChain(BaseMapper<T> mapper, T entity) {
+        return new KtUpdateChainWrapper<>(mapper, entity);
+    }
+
 }

+ 43 - 0
mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtQueryChainWrapper.kt

@@ -0,0 +1,43 @@
+package com.baomidou.mybatisplus.extension.kotlin
+
+import com.baomidou.mybatisplus.core.conditions.query.Query
+import com.baomidou.mybatisplus.core.mapper.BaseMapper
+import com.baomidou.mybatisplus.core.metadata.TableFieldInfo
+import com.baomidou.mybatisplus.extension.conditions.AbstractChainWrapper
+import com.baomidou.mybatisplus.extension.conditions.query.ChainQuery
+import java.util.function.Predicate
+import kotlin.reflect.KProperty
+
+/**
+ * @author FlyInWind
+ * @since 2020-10-18
+ */
+class KtQueryChainWrapper<T : Any>(
+    internal val baseMapper: BaseMapper<T>
+) : AbstractChainWrapper<T, KProperty<*>, KtQueryChainWrapper<T>, KtQueryWrapper<T>>(),
+    ChainQuery<T>, Query<KtQueryChainWrapper<T>, T, KProperty<*>> {
+
+
+    constructor(baseMapper: BaseMapper<T>, entityClass: Class<T>) : this(baseMapper) {
+        super.wrapperChildren = KtQueryWrapper(entityClass)
+    }
+
+    constructor(baseMapper: BaseMapper<T>, entity: T) : this(baseMapper) {
+        super.wrapperChildren = KtQueryWrapper(entity)
+    }
+
+    override fun select(vararg columns: KProperty<*>): KtQueryChainWrapper<T> {
+        wrapperChildren.select(*columns)
+        return typedThis
+    }
+
+    override fun select(entityClass: Class<T>, predicate: Predicate<TableFieldInfo>): KtQueryChainWrapper<T> {
+        wrapperChildren.select(entityClass, predicate)
+        return typedThis
+    }
+
+    override fun getBaseMapper(): BaseMapper<T> {
+        return baseMapper
+    }
+
+}

+ 41 - 0
mybatis-plus-extension/src/main/kotlin/com/baomidou/mybatisplus/extension/kotlin/KtUpdateChainWrapper.kt

@@ -0,0 +1,41 @@
+package com.baomidou.mybatisplus.extension.kotlin
+
+import com.baomidou.mybatisplus.core.conditions.update.Update
+import com.baomidou.mybatisplus.core.mapper.BaseMapper
+import com.baomidou.mybatisplus.extension.conditions.AbstractChainWrapper
+import com.baomidou.mybatisplus.extension.conditions.update.ChainUpdate
+import kotlin.reflect.KProperty
+
+/**
+ * @author FlyInWind
+ * @since 2020-10-18
+ */
+class KtUpdateChainWrapper<T : Any>(
+    internal val baseMapper: BaseMapper<T>
+) : AbstractChainWrapper<T, KProperty<*>, KtUpdateChainWrapper<T>, KtUpdateWrapper<T>>(),
+    ChainUpdate<T>, Update<KtUpdateChainWrapper<T>, KProperty<*>> {
+
+
+    constructor(baseMapper: BaseMapper<T>, entityClass: Class<T>) : this(baseMapper) {
+        super.wrapperChildren = KtUpdateWrapper(entityClass)
+    }
+
+    constructor(baseMapper: BaseMapper<T>, entity: T) : this(baseMapper) {
+        super.wrapperChildren = KtUpdateWrapper(entity)
+    }
+
+    override fun set(condition: Boolean, column: KProperty<*>, value: Any?): KtUpdateChainWrapper<T> {
+        wrapperChildren.set(condition, column, value)
+        return typedThis
+    }
+
+    override fun setSql(condition: Boolean, sql: String): KtUpdateChainWrapper<T> {
+        wrapperChildren.setSql(condition, sql)
+        return typedThis
+    }
+
+    override fun getBaseMapper(): BaseMapper<T> {
+        return baseMapper
+    }
+
+}

+ 3 - 0
mybatis-plus/build.gradle

@@ -1,6 +1,9 @@
+apply plugin: 'kotlin'
+
 dependencies {
     api project(":mybatis-plus-extension")
     implementation project(":mybatis-plus-generator")
+    implementation "${lib."kotlin-stdlib-jdk8"}"
 
     testImplementation "${lib.'spring-web'}"
     testImplementation "${lib.'javax.servlet-api'}"

+ 48 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/KtH2UserTest.kt

@@ -0,0 +1,48 @@
+package com.baomidou.mybatisplus.test.h2
+
+import com.baomidou.mybatisplus.test.h2.entity.KtH2User
+import com.baomidou.mybatisplus.test.h2.enums.AgeEnum
+import com.baomidou.mybatisplus.test.h2.service.KtH2UserService
+import org.junit.jupiter.api.Assertions
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.ExtendWith
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.test.context.ContextConfiguration
+import org.springframework.test.context.junit.jupiter.SpringExtension
+
+/**
+ * Kotlin h2user test
+ *
+ * @author FlyInWind
+ * @since 2020/10/18
+ */
+@ExtendWith(SpringExtension::class)
+@ContextConfiguration(locations = ["classpath:h2/spring-test-h2.xml"])
+class KtH2UserTest {
+    @Autowired
+    private lateinit var userService: KtH2UserService
+
+
+    @Test
+    fun testServiceImplInnerKtChain() {
+        var tomcat = userService.ktQuery().eq(KtH2User::name, "Tomcat").one()
+        Assertions.assertNotNull(tomcat)
+        Assertions.assertNotEquals(0, userService.ktQuery().like(KtH2User::name, "a").count())
+
+        val users = userService.ktQuery()
+            .like(KtH2User::age, AgeEnum.TWO)
+            .ne(KtH2User::version, 1)
+            .isNull(KtH2User::price)
+            .list()
+        Assertions.assertTrue(users.isEmpty())
+
+
+        userService.ktUpdate()
+            .set(KtH2User::name, "Tomcat2")
+            .eq(KtH2User::name, "Tomcat")
+            .update()
+        tomcat = userService.ktQuery().eq(KtH2User::name, "Tomcat").one()
+        Assertions.assertNull(tomcat)
+    }
+
+}

+ 34 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/entity/KtH2User.kt

@@ -0,0 +1,34 @@
+package com.baomidou.mybatisplus.test.h2.entity
+
+import com.baomidou.mybatisplus.annotation.TableField
+import com.baomidou.mybatisplus.annotation.TableLogic
+import com.baomidou.mybatisplus.annotation.TableName
+import com.baomidou.mybatisplus.annotation.Version
+import com.baomidou.mybatisplus.test.h2.enums.AgeEnum
+import java.math.BigDecimal
+import java.util.*
+
+@TableName("h2user")
+class KtH2User {
+
+    var name: String? = null
+
+    var age: AgeEnum? = null
+
+    var price: BigDecimal? = null
+
+    var testType: Int? = null
+
+    @TableField("`desc`")
+    var desc: String? = null
+
+    @TableField(select = false)
+    var testDate: Date? = null
+
+    @Version
+    var version: Int? = null
+
+    @TableLogic
+    val deleted: Int? = null
+
+}

+ 7 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/mapper/KtUserMapper.kt

@@ -0,0 +1,7 @@
+package com.baomidou.mybatisplus.test.h2.mapper
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper
+import com.baomidou.mybatisplus.test.h2.entity.KtH2User
+
+interface KtUserMapper : BaseMapper<KtH2User> {
+}

+ 7 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/service/KtH2UserService.kt

@@ -0,0 +1,7 @@
+package com.baomidou.mybatisplus.test.h2.service
+
+import com.baomidou.mybatisplus.extension.service.IService
+import com.baomidou.mybatisplus.test.h2.entity.KtH2User
+
+interface KtH2UserService : IService<KtH2User> {
+}

+ 12 - 0
mybatis-plus/src/test/kotlin/com/baomidou/mybatisplus/test/h2/service/impl/KtH2UserServiceImpl.kt

@@ -0,0 +1,12 @@
+package com.baomidou.mybatisplus.test.h2.service.impl
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
+import com.baomidou.mybatisplus.test.h2.entity.KtH2User
+import com.baomidou.mybatisplus.test.h2.mapper.KtUserMapper
+import com.baomidou.mybatisplus.test.h2.service.KtH2UserService
+import org.springframework.stereotype.Service
+
+@Service
+class KtH2UserServiceImpl : ServiceImpl<KtUserMapper, KtH2User>(), KtH2UserService {
+
+}