init: 导入团队知识库内容
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
qModel Model Platform(Open Source Edition)
|
||||
*
|
||||
License:
|
||||
Released under the Apache License, Version 2.0.
|
||||
You may use, modify, and distribute this software for commercial purposes
|
||||
under the terms of the License.
|
||||
*
|
||||
Special Notice:
|
||||
All derivative versions are strictly prohibited from modifying or removing
|
||||
the default system logo and copyright information.
|
||||
For brand customization, please apply for brand customization authorization via official channels.
|
||||
*
|
||||
More information: https://qmodel.qiantong.tech/business.html
|
||||
*
|
||||
============================================================================
|
||||
*
|
||||
版权所有 © 2026 江苏千桐科技有限公司
|
||||
qModel 模型平台(开源版)
|
||||
*
|
||||
许可协议:
|
||||
本项目基于 Apache License 2.0 开源协议发布,
|
||||
允许在遵守协议的前提下进行商用、修改和分发。
|
||||
*
|
||||
特别说明:
|
||||
所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
*
|
||||
更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>qmodel-framework</artifactId>
|
||||
<groupId>tech.qiantong</groupId>
|
||||
<version>1.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>qmodel-mybatis</artifactId>
|
||||
|
||||
<description>
|
||||
qModel-mybatis框架核心
|
||||
</description>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 阿里数据库连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Mysql驱动包 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>8.0.33</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 达梦驱动包 -->
|
||||
<dependency>
|
||||
<groupId>com.dameng</groupId>
|
||||
<artifactId>Dm8JdbcDriver18</artifactId>
|
||||
<version>8.1.1.49</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Oracle 驱动包 -->
|
||||
<dependency>
|
||||
<groupId>com.oracle.database.jdbc</groupId>
|
||||
<artifactId>ojdbc8</artifactId>
|
||||
<version>21.1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 人大金仓驱动包 -->
|
||||
<dependency>
|
||||
<groupId>cn.com.kingbase</groupId>
|
||||
<artifactId>kingbase8</artifactId>
|
||||
<version>8.6.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- mybatis-plus 增强CRUD -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>3.5.3</version>
|
||||
</dependency>
|
||||
|
||||
<!-- MyBatis 联表查询 -->
|
||||
<dependency>
|
||||
<groupId>com.github.yulichang</groupId>
|
||||
<artifactId>mybatis-plus-join-boot-starter</artifactId>
|
||||
<version>1.4.13</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 多数据源 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||
<version>4.3.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- pagehelper 分页插件 -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.31</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>tech.qiantong</groupId>
|
||||
<artifactId>qmodel-common</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.config;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.aspectj.lang.annotation.Before;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 数据源切换切面
|
||||
* @author Ming
|
||||
*/
|
||||
@Slf4j
|
||||
@Aspect
|
||||
@Component
|
||||
public class DynamicDataSourceAspect {
|
||||
|
||||
@Before("@annotation(ds)")
|
||||
public void beforeChangeDataSource(DS ds) {
|
||||
log.info("切换数据源: {}", ds.value());
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.config;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 主数据源配置文件
|
||||
* @author anivia
|
||||
*/
|
||||
@Component
|
||||
public class MasterDataSourceConfig {
|
||||
|
||||
private static String databaseType;
|
||||
|
||||
@Value("${datasource.type}")
|
||||
public void setDatabaseType(String databaseType) {
|
||||
MasterDataSourceConfig.databaseType = databaseType;
|
||||
}
|
||||
|
||||
public static String getDatabaseType() {
|
||||
return databaseType;
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.config;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
/**
|
||||
* Mybatis Plus 配置
|
||||
*
|
||||
* @author anivia
|
||||
*/
|
||||
@EnableTransactionManagement(proxyTargetClass = true)
|
||||
@Configuration
|
||||
public class MybatisPlusConfig
|
||||
{
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor()
|
||||
{
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
// 分页插件
|
||||
interceptor.addInnerInterceptor(paginationInnerInterceptor());
|
||||
// 乐观锁插件
|
||||
interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
|
||||
// 阻断插件
|
||||
interceptor.addInnerInterceptor(blockAttackInnerInterceptor());
|
||||
return interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页插件,自动识别数据库类型 https://baomidou.com/guide/interceptor-pagination.html
|
||||
*/
|
||||
public PaginationInnerInterceptor paginationInnerInterceptor()
|
||||
{
|
||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
||||
// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
|
||||
// paginationInnerInterceptor.setDbType(DbType.MYSQL);
|
||||
// 设置最大单页限制数量,默认 500 条,-1 不受限制
|
||||
paginationInnerInterceptor.setMaxLimit(-1L);
|
||||
return paginationInnerInterceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 乐观锁插件 https://baomidou.com/guide/interceptor-optimistic-locker.html
|
||||
*/
|
||||
public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor()
|
||||
{
|
||||
return new OptimisticLockerInnerInterceptor();
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果是对全表的删除或更新操作,就会终止该操作 https://baomidou.com/guide/interceptor-block-attack.html
|
||||
*/
|
||||
public BlockAttackInnerInterceptor blockAttackInnerInterceptor()
|
||||
{
|
||||
return new BlockAttackInnerInterceptor();
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.enums;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 针对 MyBatis Plus 的 {@link DbType} 增强,补充更多信息
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DbTypeEnum {
|
||||
|
||||
/**
|
||||
* MySQL
|
||||
*/
|
||||
MY_SQL( DbType.MYSQL, "MySQL", "FIND_IN_SET('#{value}', #{column}) <> 0"),
|
||||
|
||||
/**
|
||||
* Oracle
|
||||
*/
|
||||
ORACLE(DbType.ORACLE, "Oracle", "FIND_IN_SET('#{value}', #{column}) <> 0"),
|
||||
|
||||
/**
|
||||
* PostgreSQL
|
||||
*
|
||||
* 华为 openGauss 使用 ProductName 与 PostgreSQL 相同
|
||||
*/
|
||||
POSTGRE_SQL(DbType.POSTGRE_SQL,"PostgreSQL", "POSITION('#{value}' IN #{column}) <> 0"),
|
||||
|
||||
/**
|
||||
* SQL Server
|
||||
*/
|
||||
SQL_SERVER(DbType.SQL_SERVER, "Microsoft SQL Server", "CHARINDEX(',' + #{value} + ',', ',' + #{column} + ',') <> 0"),
|
||||
|
||||
/**
|
||||
* 达梦
|
||||
*/
|
||||
DM(DbType.DM, "DM DBMS", "FIND_IN_SET('#{value}', #{column}) <> 0"),
|
||||
|
||||
/**
|
||||
* 人大金仓
|
||||
*/
|
||||
KINGBASE_ES(DbType.KINGBASE_ES, "KingbaseES", "POSITION('#{value}' IN #{column}) <> 0"),
|
||||
;
|
||||
|
||||
public static final Map<String, DbTypeEnum> MAP_BY_NAME = Arrays.stream(values())
|
||||
.collect(Collectors.toMap(DbTypeEnum::getProductName, Function.identity()));
|
||||
|
||||
public static final Map<DbType, DbTypeEnum> MAP_BY_MP = Arrays.stream(values())
|
||||
.collect(Collectors.toMap(DbTypeEnum::getMpDbType, Function.identity()));
|
||||
|
||||
/**
|
||||
* MyBatis Plus 类型
|
||||
*/
|
||||
private final DbType mpDbType;
|
||||
/**
|
||||
* 数据库产品名
|
||||
*/
|
||||
private final String productName;
|
||||
/**
|
||||
* SQL FIND_IN_SET 模板
|
||||
*/
|
||||
private final String findInSetTemplate;
|
||||
|
||||
public static DbType find(String databaseProductName) {
|
||||
if (StrUtil.isBlank(databaseProductName)) {
|
||||
return null;
|
||||
}
|
||||
return MAP_BY_NAME.get(databaseProductName).getMpDbType();
|
||||
}
|
||||
|
||||
public static String getFindInSetTemplate(DbType dbType) {
|
||||
return Optional.of(MAP_BY_MP.get(dbType).getFindInSetTemplate())
|
||||
.orElseThrow(() -> new IllegalArgumentException("FIND_IN_SET not supported"));
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.enums;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
|
||||
/**
|
||||
* SQL相关常量类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class SqlConstants {
|
||||
|
||||
/**
|
||||
* 数据库的类型
|
||||
*/
|
||||
public static DbType DB_TYPE;
|
||||
|
||||
public static void init(DbType dbType) {
|
||||
DB_TYPE = dbType;
|
||||
}
|
||||
|
||||
}
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.mapper;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.baomidou.mybatisplus.extension.toolkit.Db;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
import com.github.yulichang.interfaces.MPJBaseJoin;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import tech.qiantong.qmodel.common.core.page.PageParam;
|
||||
import tech.qiantong.qmodel.common.core.page.PageResult;
|
||||
import tech.qiantong.qmodel.common.core.page.SortablePageParam;
|
||||
import tech.qiantong.qmodel.common.core.page.SortingField;
|
||||
import tech.qiantong.qmodel.mybatis.core.enums.SqlConstants;
|
||||
import tech.qiantong.qmodel.mybatis.core.util.MyBatisUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
|
||||
*
|
||||
* 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力
|
||||
* 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力
|
||||
*/
|
||||
public interface BaseMapperX<T> extends MPJBaseMapper<T> {
|
||||
|
||||
default PageResult<T> selectPage(SortablePageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
|
||||
return selectPage(pageParam, pageParam.getSortingFields(), queryWrapper);
|
||||
}
|
||||
|
||||
default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
|
||||
return selectPage(pageParam, null, queryWrapper);
|
||||
}
|
||||
|
||||
default PageResult<T> selectPage(PageParam pageParam, Collection<SortingField> sortingFields, @Param("ew") Wrapper<T> queryWrapper) {
|
||||
// 特殊:不分页,直接查询全部
|
||||
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
|
||||
List<T> list = selectList(queryWrapper);
|
||||
return new PageResult<>(list, (long) list.size());
|
||||
}
|
||||
|
||||
// MyBatis Plus 查询
|
||||
IPage<T> mpPage = MyBatisUtils.buildPage(pageParam, sortingFields);
|
||||
selectPage(mpPage, queryWrapper);
|
||||
// 转换返回
|
||||
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
||||
}
|
||||
|
||||
default <D> PageResult<D> selectJoinPage(PageParam pageParam, Class<D> clazz, MPJLambdaWrapper<T> lambdaWrapper) {
|
||||
// 特殊:不分页,直接查询全部
|
||||
if (PageParam.PAGE_SIZE_NONE.equals(pageParam.getPageSize())) {
|
||||
List<D> list = selectJoinList(clazz, lambdaWrapper);
|
||||
return new PageResult<>(list, (long) list.size());
|
||||
}
|
||||
|
||||
// MyBatis Plus Join 查询
|
||||
IPage<D> mpPage = MyBatisUtils.buildPage(pageParam);
|
||||
mpPage = selectJoinPage(mpPage, clazz, lambdaWrapper);
|
||||
// 转换返回
|
||||
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
||||
}
|
||||
|
||||
default <DTO> PageResult<DTO> selectJoinPage(PageParam pageParam, Class<DTO> resultTypeClass, MPJBaseJoin<T> joinQueryWrapper) {
|
||||
IPage<DTO> mpPage = MyBatisUtils.buildPage(pageParam);
|
||||
selectJoinPage(mpPage, resultTypeClass, joinQueryWrapper);
|
||||
// 转换返回
|
||||
return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
|
||||
}
|
||||
|
||||
default T selectOne(String field, Object value) {
|
||||
return selectOne(new QueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default T selectOne(SFunction<T, ?> field, Object value) {
|
||||
return selectOne(new LambdaQueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default T selectOne(String field1, Object value1, String field2, Object value2) {
|
||||
return selectOne(new QueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
||||
}
|
||||
|
||||
default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
||||
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
||||
}
|
||||
|
||||
default T selectOne(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2,
|
||||
SFunction<T, ?> field3, Object value3) {
|
||||
return selectOne(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2)
|
||||
.eq(field3, value3));
|
||||
}
|
||||
|
||||
default Long selectCount() {
|
||||
return selectCount(new QueryWrapper<>());
|
||||
}
|
||||
|
||||
default Long selectCount(String field, Object value) {
|
||||
return selectCount(new QueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default Long selectCount(SFunction<T, ?> field, Object value) {
|
||||
return selectCount(new LambdaQueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default List<T> selectList() {
|
||||
return selectList(new QueryWrapper<>());
|
||||
}
|
||||
|
||||
default List<T> selectList(String field, Object value) {
|
||||
return selectList(new QueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default List<T> selectList(SFunction<T, ?> field, Object value) {
|
||||
return selectList(new LambdaQueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default List<T> selectList(String field, Collection<?> values) {
|
||||
if (CollUtil.isEmpty(values)) {
|
||||
return CollUtil.newArrayList();
|
||||
}
|
||||
return selectList(new QueryWrapper<T>().in(field, values));
|
||||
}
|
||||
|
||||
default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
|
||||
if (CollUtil.isEmpty(values)) {
|
||||
return CollUtil.newArrayList();
|
||||
}
|
||||
return selectList(new LambdaQueryWrapper<T>().in(field, values));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
default List<T> selectList(SFunction<T, ?> leField, SFunction<T, ?> geField, Object value) {
|
||||
return selectList(new LambdaQueryWrapper<T>().le(leField, value).ge(geField, value));
|
||||
}
|
||||
|
||||
default List<T> selectList(SFunction<T, ?> field1, Object value1, SFunction<T, ?> field2, Object value2) {
|
||||
return selectList(new LambdaQueryWrapper<T>().eq(field1, value1).eq(field2, value2));
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入,适合大量数据插入
|
||||
*
|
||||
* @param entities 实体们
|
||||
*/
|
||||
default Boolean insertBatch(Collection<T> entities) {
|
||||
// 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
|
||||
if (Objects.equals(SqlConstants.DB_TYPE, DbType.SQL_SERVER)) {
|
||||
entities.forEach(this::insert);
|
||||
return CollUtil.isNotEmpty(entities);
|
||||
}
|
||||
return Db.saveBatch(entities);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量插入,适合大量数据插入
|
||||
*
|
||||
* @param entities 实体们
|
||||
* @param size 插入数量 Db.saveBatch 默认为 1000
|
||||
*/
|
||||
default Boolean insertBatch(Collection<T> entities, int size) {
|
||||
// 特殊:SQL Server 批量插入后,获取 id 会报错,因此通过循环处理
|
||||
if (Objects.equals(SqlConstants.DB_TYPE, DbType.SQL_SERVER)) {
|
||||
entities.forEach(this::insert);
|
||||
return CollUtil.isNotEmpty(entities);
|
||||
}
|
||||
return Db.saveBatch(entities, size);
|
||||
}
|
||||
|
||||
default int updateBatch(T update) {
|
||||
return update(update, new QueryWrapper<>());
|
||||
}
|
||||
|
||||
default Boolean updateBatch(Collection<T> entities) {
|
||||
return Db.updateBatchById(entities);
|
||||
}
|
||||
|
||||
default Boolean updateBatch(Collection<T> entities, int size) {
|
||||
return Db.updateBatchById(entities, size);
|
||||
}
|
||||
|
||||
default Boolean insertOrUpdateBatch(Collection<T> collection) {
|
||||
return Db.saveOrUpdateBatch(collection);
|
||||
}
|
||||
|
||||
default int delete(String field, String value) {
|
||||
return delete(new QueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
default int delete(SFunction<T, ?> field, Object value) {
|
||||
return delete(new LambdaQueryWrapper<T>().eq(field, value));
|
||||
}
|
||||
|
||||
}
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.query;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 拓展 MyBatis Plus QueryWrapper 类,主要增加如下功能:
|
||||
* <p>
|
||||
* 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
|
||||
*
|
||||
* @param <T> 数据类型
|
||||
*/
|
||||
public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
|
||||
|
||||
public LambdaQueryWrapperX<T> likeIfPresent(SFunction<T, ?> column, String val) {
|
||||
if (StringUtils.hasText(val)) {
|
||||
return (LambdaQueryWrapperX<T>) super.like(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> likeRightIfPresent(SFunction<T, ?> column, String val) {
|
||||
if (StringUtils.hasText(val)) {
|
||||
return (LambdaQueryWrapperX<T>) super.likeRight(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
|
||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||
return (LambdaQueryWrapperX<T>) super.in(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> inIfPresent(SFunction<T, ?> column, Object... values) {
|
||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||
return (LambdaQueryWrapperX<T>) super.in(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public LambdaQueryWrapperX<T> notInIfPresent(SFunction<T, ?> column, Object... values) {
|
||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||
return (LambdaQueryWrapperX<T>) super.notIn(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> eqIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (ObjectUtil.isNotEmpty(val)) {
|
||||
return (LambdaQueryWrapperX<T>) super.eq(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> neIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (ObjectUtil.isNotEmpty(val)) {
|
||||
return (LambdaQueryWrapperX<T>) super.ne(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> gtIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (LambdaQueryWrapperX<T>) super.gt(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> geIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (LambdaQueryWrapperX<T>) super.ge(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> ltIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (LambdaQueryWrapperX<T>) super.lt(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> leIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (LambdaQueryWrapperX<T>) super.le(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public LambdaQueryWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object val1, Object val2) {
|
||||
if (val1 != null && val2 != null) {
|
||||
return (LambdaQueryWrapperX<T>) super.between(column, val1, val2);
|
||||
}
|
||||
if (val1 != null) {
|
||||
return (LambdaQueryWrapperX<T>) ge(column, val1);
|
||||
}
|
||||
if (val2 != null) {
|
||||
return (LambdaQueryWrapperX<T>) le(column, val2);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 添加基于字符串字段名的多列排序方法,使用允许的字段集合防止 SQL 注入。
|
||||
*
|
||||
* @param columns 逗号分隔的列名(驼峰命名)
|
||||
* @param isAsc 逗号分隔的排序方向("asc", "desc"),或单一方向应用于所有列
|
||||
* @param allowedColumns 允许排序的字段集合(下划线命名)
|
||||
* @return this,保持链式调用
|
||||
*/
|
||||
public LambdaQueryWrapperX<T> orderBy(String columns, String isAsc, Set<String> allowedColumns) {
|
||||
if (columns != null && !columns.trim().isEmpty()) {
|
||||
String[] columnArray = columns.split(",");
|
||||
String[] isAscArray = (isAsc != null && !isAsc.trim().isEmpty()) ? isAsc.split(",") : new String[0];
|
||||
StringBuilder orderClause = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < columnArray.length; i++) {
|
||||
String column = columnArray[i].trim();
|
||||
if (column.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String columnName = camelToUnderline(column);
|
||||
// 校验字段名是否合法
|
||||
if (!allowedColumns.contains(columnName)) {
|
||||
throw new IllegalArgumentException("非法的排序字段:" + column);
|
||||
}
|
||||
|
||||
boolean ascending = true; // 默认升序
|
||||
|
||||
if (isAscArray.length > 0) {
|
||||
if (i < isAscArray.length) {
|
||||
String direction = isAscArray[i].trim().toLowerCase(Locale.ROOT);
|
||||
if (direction.equals("desc")) {
|
||||
ascending = false;
|
||||
} else if (!direction.equals("asc")) {
|
||||
// 如果方向无效,默认降序
|
||||
ascending = false;
|
||||
}
|
||||
} else if (isAscArray.length == 1) {
|
||||
String direction = isAscArray[0].trim().toLowerCase(Locale.ROOT);
|
||||
if (direction.equals("desc")) {
|
||||
ascending = false;
|
||||
} else if (!direction.equals("asc")) {
|
||||
ascending = false;
|
||||
}
|
||||
} else {
|
||||
// 如果没有提供对应的排序方向,默认降序
|
||||
ascending = false;
|
||||
}
|
||||
} else {
|
||||
// 如果未提供 isAsc,默认降序
|
||||
ascending = false;
|
||||
}
|
||||
|
||||
orderClause.append(columnName).append(ascending ? " ASC, " : " DESC, ");
|
||||
}
|
||||
|
||||
// 移除末尾的逗号和空格
|
||||
if (orderClause.length() > 0) {
|
||||
orderClause.setLength(orderClause.length() - 2);
|
||||
// 检查是否已经存在 ORDER BY 子句
|
||||
String existingOrderBy = this.getSqlSegment().toLowerCase(Locale.ROOT);
|
||||
if (existingOrderBy.contains("order by")) {
|
||||
// 追加到现有的 ORDER BY 子句
|
||||
this.last(", " + orderClause.toString());
|
||||
} else {
|
||||
// 添加新的 ORDER BY 子句
|
||||
this.last(" ORDER BY " + orderClause.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将驼峰命名转换为下划线命名
|
||||
*
|
||||
* @param param 驼峰命名字符串
|
||||
* @return 下划线命名字符串
|
||||
*/
|
||||
public static String camelToUnderline(String param) {
|
||||
if (param == null || param.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder(param.length());
|
||||
char[] chars = param.toCharArray();
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
char c = chars[i];
|
||||
if (Character.isUpperCase(c) && i > 0) {
|
||||
sb.append('_');
|
||||
}
|
||||
sb.append(Character.toLowerCase(c));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public LambdaQueryWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object[] values) {
|
||||
Object val1 = ArrayUtils.get(values, 0);
|
||||
Object val2 = ArrayUtils.get(values, 1);
|
||||
return betweenIfPresent(column, val1, val2);
|
||||
}
|
||||
|
||||
// ========== 重写父类方法,方便链式调用 ==========
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> eq(boolean condition, SFunction<T, ?> column, Object val) {
|
||||
super.eq(condition, column, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> eq(SFunction<T, ?> column, Object val) {
|
||||
super.eq(column, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> or() {
|
||||
super.or();
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> isNull(SFunction<T, ?> column) {
|
||||
super.isNull(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> orderByDesc(SFunction<T, ?> column) {
|
||||
super.orderByDesc(true, column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> orderByAsc(SFunction<T, ?> column) {
|
||||
super.orderByAsc(true, column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> last(String lastSql) {
|
||||
super.last(lastSql);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> in(SFunction<T, ?> column, Collection<?> coll) {
|
||||
super.in(column, coll);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.query;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||
import com.github.yulichang.toolkit.MPJWrappers;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能:
|
||||
* <p>
|
||||
* 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
|
||||
*
|
||||
* @param <T> 数据类型
|
||||
*/
|
||||
public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
|
||||
|
||||
public MPJLambdaWrapperX<T> likeIfPresent(SFunction<T, ?> column, String val) {
|
||||
MPJWrappers.lambdaJoin().like(column, val);
|
||||
if (StringUtils.hasText(val)) {
|
||||
return (MPJLambdaWrapperX<T>) super.like(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
|
||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> inIfPresent(SFunction<T, ?> column, Object... values) {
|
||||
if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
|
||||
return (MPJLambdaWrapperX<T>) super.in(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> eqIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (ObjectUtil.isNotEmpty(val)) {
|
||||
return (MPJLambdaWrapperX<T>) super.eq(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> neIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (ObjectUtil.isNotEmpty(val)) {
|
||||
return (MPJLambdaWrapperX<T>) super.ne(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> gtIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (MPJLambdaWrapperX<T>) super.gt(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> geIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (MPJLambdaWrapperX<T>) super.ge(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> ltIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (MPJLambdaWrapperX<T>) super.lt(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> leIfPresent(SFunction<T, ?> column, Object val) {
|
||||
if (val != null) {
|
||||
return (MPJLambdaWrapperX<T>) super.le(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object val1, Object val2) {
|
||||
if (val1 != null && val2 != null) {
|
||||
return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
|
||||
}
|
||||
if (val1 != null) {
|
||||
return (MPJLambdaWrapperX<T>) ge(column, val1);
|
||||
}
|
||||
if (val2 != null) {
|
||||
return (MPJLambdaWrapperX<T>) le(column, val2);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public MPJLambdaWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object[] values) {
|
||||
Object val1 = ArrayUtils.get(values, 0);
|
||||
Object val2 = ArrayUtils.get(values, 1);
|
||||
return betweenIfPresent(column, val1, val2);
|
||||
}
|
||||
|
||||
// ========== 重写父类方法,方便链式调用 ==========
|
||||
|
||||
@Override
|
||||
public <X> MPJLambdaWrapperX<T> eq(boolean condition, SFunction<X, ?> column, Object val) {
|
||||
super.eq(condition, column, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> MPJLambdaWrapperX<T> eq(SFunction<X, ?> column, Object val) {
|
||||
super.eq(column, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> MPJLambdaWrapperX<T> orderByDesc(SFunction<X, ?> column) {
|
||||
//noinspection unchecked
|
||||
super.orderByDesc(true, column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPJLambdaWrapperX<T> last(String lastSql) {
|
||||
super.last(lastSql);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> MPJLambdaWrapperX<T> in(SFunction<X, ?> column, Collection<?> coll) {
|
||||
super.in(column, coll);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPJLambdaWrapperX<T> selectAll(Class<?> clazz) {
|
||||
super.selectAll(clazz);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPJLambdaWrapperX<T> selectAll(Class<?> clazz, String prefix) {
|
||||
super.selectAll(clazz, prefix);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectAs(SFunction<S, ?> column, String alias) {
|
||||
super.selectAs(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> MPJLambdaWrapperX<T> selectAs(String column, SFunction<E, ?> alias) {
|
||||
super.selectAs(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectAs(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectAs(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E, X> MPJLambdaWrapperX<T> selectAs(String index, SFunction<E, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectAs(index, column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E> MPJLambdaWrapperX<T> selectAsClass(Class<E> source, Class<?> tag) {
|
||||
super.selectAsClass(source, tag);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E, F> MPJLambdaWrapperX<T> selectSub(Class<E> clazz, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
|
||||
super.selectSub(clazz, consumer, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E, F> MPJLambdaWrapperX<T> selectSub(Class<E> clazz, String st, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
|
||||
super.selectSub(clazz, st, consumer, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column) {
|
||||
super.selectCount(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MPJLambdaWrapperX<T> selectCount(Object column, String alias) {
|
||||
super.selectCount(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <X> MPJLambdaWrapperX<T> selectCount(Object column, SFunction<X, ?> alias) {
|
||||
super.selectCount(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, String alias) {
|
||||
super.selectCount(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectCount(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column) {
|
||||
super.selectSum(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, String alias) {
|
||||
super.selectSum(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectSum(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column) {
|
||||
super.selectMax(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, String alias) {
|
||||
super.selectMax(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectMax(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column) {
|
||||
super.selectMin(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, String alias) {
|
||||
super.selectMin(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectMin(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column) {
|
||||
super.selectAvg(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, String alias) {
|
||||
super.selectAvg(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectAvg(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column) {
|
||||
super.selectLen(column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, String alias) {
|
||||
super.selectLen(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
||||
super.selectLen(column, alias);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.query;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import tech.qiantong.qmodel.mybatis.core.enums.SqlConstants;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 拓展 MyBatis Plus QueryWrapper 类,主要增加如下功能:
|
||||
*
|
||||
* 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
|
||||
*
|
||||
* @param <T> 数据类型
|
||||
*/
|
||||
public class QueryWrapperX<T> extends QueryWrapper<T> {
|
||||
|
||||
public QueryWrapperX<T> likeIfPresent(String column, String val) {
|
||||
if (StringUtils.hasText(val)) {
|
||||
return (QueryWrapperX<T>) super.like(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> inIfPresent(String column, Collection<?> values) {
|
||||
if (!CollectionUtils.isEmpty(values)) {
|
||||
return (QueryWrapperX<T>) super.in(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> inIfPresent(String column, Object... values) {
|
||||
if (!ArrayUtils.isEmpty(values)) {
|
||||
return (QueryWrapperX<T>) super.in(column, values);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> eqIfPresent(String column, Object val) {
|
||||
if (val != null) {
|
||||
return (QueryWrapperX<T>) super.eq(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> neIfPresent(String column, Object val) {
|
||||
if (val != null) {
|
||||
return (QueryWrapperX<T>) super.ne(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> gtIfPresent(String column, Object val) {
|
||||
if (val != null) {
|
||||
return (QueryWrapperX<T>) super.gt(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> geIfPresent(String column, Object val) {
|
||||
if (val != null) {
|
||||
return (QueryWrapperX<T>) super.ge(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> ltIfPresent(String column, Object val) {
|
||||
if (val != null) {
|
||||
return (QueryWrapperX<T>) super.lt(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> leIfPresent(String column, Object val) {
|
||||
if (val != null) {
|
||||
return (QueryWrapperX<T>) super.le(column, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> betweenIfPresent(String column, Object val1, Object val2) {
|
||||
if (val1 != null && val2 != null) {
|
||||
return (QueryWrapperX<T>) super.between(column, val1, val2);
|
||||
}
|
||||
if (val1 != null) {
|
||||
return (QueryWrapperX<T>) ge(column, val1);
|
||||
}
|
||||
if (val2 != null) {
|
||||
return (QueryWrapperX<T>) le(column, val2);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public QueryWrapperX<T> betweenIfPresent(String column, Object[] values) {
|
||||
if (values!= null && values.length != 0 && values[0] != null && values[1] != null) {
|
||||
return (QueryWrapperX<T>) super.between(column, values[0], values[1]);
|
||||
}
|
||||
if (values!= null && values.length != 0 && values[0] != null) {
|
||||
return (QueryWrapperX<T>) ge(column, values[0]);
|
||||
}
|
||||
if (values!= null && values.length != 0 && values[1] != null) {
|
||||
return (QueryWrapperX<T>) le(column, values[1]);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// ========== 重写父类方法,方便链式调用 ==========
|
||||
|
||||
@Override
|
||||
public QueryWrapperX<T> eq(boolean condition, String column, Object val) {
|
||||
super.eq(condition, column, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapperX<T> eq(String column, Object val) {
|
||||
super.eq(column, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapperX<T> orderByDesc(String column) {
|
||||
super.orderByDesc(true, column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapperX<T> last(String lastSql) {
|
||||
super.last(lastSql);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QueryWrapperX<T> in(String column, Collection<?> coll) {
|
||||
super.in(column, coll);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置只返回最后一条
|
||||
*
|
||||
* TODO 芋艿:不是完美解,需要在思考下。如果使用多数据源,并且数据源是多种类型时,可能会存在问题:实现之返回一条的语法不同
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public QueryWrapperX<T> limitN(int n) {
|
||||
Assert.notNull(SqlConstants.DB_TYPE, "获取不到数据库的类型");
|
||||
switch (SqlConstants.DB_TYPE) {
|
||||
case ORACLE:
|
||||
case ORACLE_12C:
|
||||
super.le("ROWNUM", n);
|
||||
break;
|
||||
case SQL_SERVER:
|
||||
case SQL_SERVER2005:
|
||||
super.select("TOP " + n + " *"); // 由于 SQL Server 是通过 SELECT TOP 1 实现限制一条,所以只好使用 * 查询剩余字段
|
||||
break;
|
||||
default:
|
||||
super.last("LIMIT " + n);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.type;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import cn.hutool.crypto.symmetric.AES;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import org.apache.ibatis.type.BaseTypeHandler;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* 字段字段的 TypeHandler 实现类,基于 {@link AES} 实现
|
||||
* 可通过 jasypt.encryptor.password 配置项,设置密钥
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class EncryptTypeHandler extends BaseTypeHandler<String> {
|
||||
|
||||
private static final String ENCRYPTOR_PROPERTY_NAME = "mybatis-plus.encryptor.password";
|
||||
|
||||
private static AES aes;
|
||||
|
||||
@Override
|
||||
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
|
||||
ps.setString(i, encrypt(parameter));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String value = rs.getString(columnName);
|
||||
return decrypt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String value = rs.getString(columnIndex);
|
||||
return decrypt(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String value = cs.getString(columnIndex);
|
||||
return decrypt(value);
|
||||
}
|
||||
|
||||
private static String decrypt(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return getEncryptor().decryptStr(value);
|
||||
}
|
||||
|
||||
public static String encrypt(String rawValue) {
|
||||
if (rawValue == null) {
|
||||
return null;
|
||||
}
|
||||
return getEncryptor().encryptBase64(rawValue);
|
||||
}
|
||||
|
||||
private static AES getEncryptor() {
|
||||
if (aes != null) {
|
||||
return aes;
|
||||
}
|
||||
// 构建 AES
|
||||
String password = SpringUtil.getProperty(ENCRYPTOR_PROPERTY_NAME);
|
||||
Assert.notEmpty(password, "配置项({}) 不能为空", ENCRYPTOR_PROPERTY_NAME);
|
||||
aes = SecureUtil.aes(password.getBytes());
|
||||
return aes;
|
||||
}
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.type;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
import tech.qiantong.qmodel.common.utils.string.StrUtils;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* List<Integer> 的类型转换器实现类,对应数据库的 varchar 类型
|
||||
*
|
||||
* @author jason
|
||||
*/
|
||||
@MappedJdbcTypes(JdbcType.VARCHAR)
|
||||
@MappedTypes(List.class)
|
||||
public class IntegerListTypeHandler implements TypeHandler<List<Integer>> {
|
||||
|
||||
private static final String COMMA = ",";
|
||||
|
||||
@Override
|
||||
public void setParameter(PreparedStatement ps, int i, List<Integer> strings, JdbcType jdbcType) throws SQLException {
|
||||
ps.setString(i, CollUtil.join(strings, COMMA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String value = rs.getString(columnName);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String value = rs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String value = cs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
private List<Integer> getResult(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return StrUtils.splitToInteger(value, COMMA);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.type;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
import tech.qiantong.qmodel.common.utils.string.StrUtils;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* List<Long> 的类型转换器实现类,对应数据库的 varchar 类型
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@MappedJdbcTypes(JdbcType.VARCHAR)
|
||||
@MappedTypes(List.class)
|
||||
public class LongListTypeHandler implements TypeHandler<List<Long>> {
|
||||
|
||||
private static final String COMMA = ",";
|
||||
|
||||
@Override
|
||||
public void setParameter(PreparedStatement ps, int i, List<Long> strings, JdbcType jdbcType) throws SQLException {
|
||||
// 设置占位符
|
||||
ps.setString(i, CollUtil.join(strings, COMMA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String value = rs.getString(columnName);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String value = rs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String value = cs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
private List<Long> getResult(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return StrUtils.splitToLong(value, COMMA);
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.type;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.apache.ibatis.type.MappedJdbcTypes;
|
||||
import org.apache.ibatis.type.MappedTypes;
|
||||
import org.apache.ibatis.type.TypeHandler;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* List<String> 的类型转换器实现类,对应数据库的 varchar 类型
|
||||
*
|
||||
* @author 永不言败
|
||||
* @since 2022 3/23 12:50:15
|
||||
*/
|
||||
@MappedJdbcTypes(JdbcType.VARCHAR)
|
||||
@MappedTypes(List.class)
|
||||
public class StringListTypeHandler implements TypeHandler<List<String>> {
|
||||
|
||||
private static final String COMMA = ",";
|
||||
|
||||
@Override
|
||||
public void setParameter(PreparedStatement ps, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
|
||||
// 设置占位符
|
||||
ps.setString(i, CollUtil.join(strings, COMMA));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getResult(ResultSet rs, String columnName) throws SQLException {
|
||||
String value = rs.getString(columnName);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||
String value = rs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||
String value = cs.getString(columnIndex);
|
||||
return getResult(value);
|
||||
}
|
||||
|
||||
private List<String> getResult(String value) {
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
return StrUtil.splitTrim(value, COMMA);
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.util;
|
||||
|
||||
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import tech.qiantong.qmodel.common.utils.spring.SpringUtils;
|
||||
import tech.qiantong.qmodel.mybatis.core.enums.DbTypeEnum;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* JDBC 工具类
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public class JdbcUtils {
|
||||
|
||||
/**
|
||||
* 判断连接是否正确
|
||||
*
|
||||
* @param url 数据源连接
|
||||
* @param username 账号
|
||||
* @param password 密码
|
||||
* @return 是否正确
|
||||
*/
|
||||
public static boolean isConnectionOK(String url, String username, String password) {
|
||||
try (Connection ignored = DriverManager.getConnection(url, username, password)) {
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 URL 对应的 DB 类型
|
||||
*
|
||||
* @param url URL
|
||||
* @return DB 类型
|
||||
*/
|
||||
public static DbType getDbType(String url) {
|
||||
return com.baomidou.mybatisplus.extension.toolkit.JdbcUtils.getDbType(url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过当前数据库连接获得对应的 DB 类型
|
||||
*
|
||||
* @return DB 类型
|
||||
*/
|
||||
public static DbType getDbType() {
|
||||
DynamicRoutingDataSource dynamicRoutingDataSource = SpringUtils.getBean(DynamicRoutingDataSource.class);
|
||||
DataSource dataSource = dynamicRoutingDataSource.determineDataSource();
|
||||
try (Connection conn = dataSource.getConnection()) {
|
||||
return DbTypeEnum.find(conn.getMetaData().getDatabaseProductName());
|
||||
} catch (SQLException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.util;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import net.sf.jsqlparser.expression.Alias;
|
||||
import net.sf.jsqlparser.schema.Column;
|
||||
import net.sf.jsqlparser.schema.Table;
|
||||
import tech.qiantong.qmodel.common.core.page.PageParam;
|
||||
import tech.qiantong.qmodel.common.core.page.SortingField;
|
||||
import tech.qiantong.qmodel.mybatis.core.enums.DbTypeEnum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* MyBatis 工具类
|
||||
*/
|
||||
public class MyBatisUtils {
|
||||
|
||||
private static final String MYSQL_ESCAPE_CHARACTER = "`";
|
||||
|
||||
public static <T> Page<T> buildPage(PageParam pageParam) {
|
||||
return buildPage(pageParam, null);
|
||||
}
|
||||
|
||||
public static <T> Page<T> buildPage(PageParam pageParam, Collection<SortingField> sortingFields) {
|
||||
// 页码 + 数量
|
||||
Page<T> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());
|
||||
// 排序字段
|
||||
if (!CollectionUtil.isEmpty(sortingFields)) {
|
||||
page.addOrder(sortingFields.stream().map(sortingField -> SortingField.ORDER_ASC.equals(sortingField.getOrder()) ?
|
||||
OrderItem.asc(sortingField.getField()) : OrderItem.desc(sortingField.getField()))
|
||||
.collect(Collectors.toList()));
|
||||
}
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将拦截器添加到链中
|
||||
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
||||
*
|
||||
* @param interceptor 链
|
||||
* @param inner 拦截器
|
||||
* @param index 位置
|
||||
*/
|
||||
public static void addInterceptor(MybatisPlusInterceptor interceptor, InnerInterceptor inner, int index) {
|
||||
List<InnerInterceptor> inners = new ArrayList<>(interceptor.getInterceptors());
|
||||
inners.add(index, inner);
|
||||
interceptor.setInterceptors(inners);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得 Table 对应的表名
|
||||
* <p>
|
||||
* 兼容 MySQL 转义表名 `t_xxx`
|
||||
*
|
||||
* @param table 表
|
||||
* @return 去除转移字符后的表名
|
||||
*/
|
||||
public static String getTableName(Table table) {
|
||||
String tableName = table.getName();
|
||||
if (tableName.startsWith(MYSQL_ESCAPE_CHARACTER) && tableName.endsWith(MYSQL_ESCAPE_CHARACTER)) {
|
||||
tableName = tableName.substring(1, tableName.length() - 1);
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 Column 对象
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param tableAlias 别名
|
||||
* @param column 字段名
|
||||
* @return Column 对象
|
||||
*/
|
||||
public static Column buildColumn(String tableName, Alias tableAlias, String column) {
|
||||
if (tableAlias != null) {
|
||||
tableName = tableAlias.getName();
|
||||
}
|
||||
return new Column(tableName + StringPool.DOT + column);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跨数据库的 find_in_set 实现
|
||||
*
|
||||
* @param column 字段名称
|
||||
* @param value 查询值(不带单引号)
|
||||
* @return sql
|
||||
*/
|
||||
public static String findInSet(String column, Object value) {
|
||||
// 这里不用SqlConstants.DB_TYPE,因为它是使用 primary 数据源的 url 推断出来的类型
|
||||
DbType dbType = JdbcUtils.getDbType();
|
||||
return DbTypeEnum.getFindInSetTemplate(dbType)
|
||||
.replace("#{column}", column)
|
||||
.replace("#{value}", StrUtil.toString(value));
|
||||
}
|
||||
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.core.util;
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import tech.qiantong.qmodel.common.core.domain.model.LoginUser;
|
||||
import tech.qiantong.qmodel.common.utils.SecurityUtils;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Component
|
||||
public class MyMetaObjectHandler implements MetaObjectHandler {
|
||||
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
// 检查是否有名为createTime的字段,如果有则自动填充当前时间
|
||||
boolean hasCreateTime = metaObject.hasSetter("createTime");
|
||||
if (hasCreateTime) {
|
||||
metaObject.setValue("createTime", new Date());
|
||||
}
|
||||
// 检查是否有名为updateTime的字段,如果有则自动填充当前时间 部分表设置的updateTime不能为空
|
||||
boolean hasUpdateTime = metaObject.hasSetter("updateTime");
|
||||
if (hasUpdateTime) {
|
||||
metaObject.setValue("updateTime", new Date());
|
||||
}
|
||||
boolean hasCreatorId = metaObject.hasSetter("creatorId");
|
||||
boolean hasCreateBy = metaObject.hasSetter("createBy");
|
||||
boolean hasUpdatorId = metaObject.hasSetter("updatorId");
|
||||
boolean HasUpdateBy = metaObject.hasSetter("updateBy");
|
||||
LoginUser loginUser = null;
|
||||
try {
|
||||
loginUser = (LoginUser) SecurityUtils.getAuthentication().getPrincipal();
|
||||
} catch (Exception e) {
|
||||
logger.info("获取用户信息异常:{}", e);
|
||||
}
|
||||
if (loginUser != null) {
|
||||
if (hasCreatorId) {
|
||||
metaObject.setValue("creatorId", loginUser.getUserId());
|
||||
}
|
||||
if (hasCreateBy) {
|
||||
metaObject.setValue("createBy", loginUser.getUser().getNickName());
|
||||
}
|
||||
if (hasUpdatorId) {
|
||||
metaObject.setValue("updatorId", loginUser.getUserId());
|
||||
}
|
||||
if (HasUpdateBy) {
|
||||
metaObject.setValue("updateBy", loginUser.getUser().getNickName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
// 检查是否有名为updateTime的字段,如果有则自动填充当前时间
|
||||
boolean hasUpdateTime = metaObject.hasSetter("updateTime");
|
||||
if (hasUpdateTime) {
|
||||
metaObject.setValue("updateTime", new Date());
|
||||
}
|
||||
|
||||
boolean hasUpdatorId = metaObject.hasSetter("updatorId");
|
||||
boolean HasUpdateBy = metaObject.hasSetter("updateBy");
|
||||
|
||||
LoginUser loginUser = null;
|
||||
try {
|
||||
loginUser = (LoginUser) SecurityUtils.getAuthentication().getPrincipal();
|
||||
} catch (Exception e) {
|
||||
logger.info("获取用户信息异常:{}", e);
|
||||
}
|
||||
if (loginUser != null) {
|
||||
if (hasUpdatorId) {
|
||||
metaObject.setValue("updatorId", loginUser.getUserId());
|
||||
}
|
||||
if (HasUpdateBy) {
|
||||
metaObject.setValue("updateBy", loginUser.getUser().getNickName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.datasource;
|
||||
|
||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 动态数据源
|
||||
*
|
||||
* @author anivia
|
||||
*/
|
||||
public class DynamicDataSource extends AbstractRoutingDataSource
|
||||
{
|
||||
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
|
||||
{
|
||||
super.setDefaultTargetDataSource(defaultTargetDataSource);
|
||||
super.setTargetDataSources(targetDataSources);
|
||||
super.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object determineCurrentLookupKey()
|
||||
{
|
||||
return DynamicDataSourceContextHolder.getDataSourceType();
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright © 2026 Qiantong Technology Co., Ltd.
|
||||
* qModel Model Platform(Open Source Edition)
|
||||
* *
|
||||
* License:
|
||||
* Released under the Apache License, Version 2.0.
|
||||
* You may use, modify, and distribute this software for commercial purposes
|
||||
* under the terms of the License.
|
||||
* *
|
||||
* Special Notice:
|
||||
* All derivative versions are strictly prohibited from modifying or removing
|
||||
* the default system logo and copyright information.
|
||||
* For brand customization, please apply for brand customization authorization via official channels.
|
||||
* *
|
||||
* More information: https://qmodel.qiantong.tech/business.html
|
||||
* *
|
||||
* ============================================================================
|
||||
* *
|
||||
* 版权所有 © 2026 江苏千桐科技有限公司
|
||||
* qModel 模型平台(开源版)
|
||||
* *
|
||||
* 许可协议:
|
||||
* 本项目基于 Apache License 2.0 开源协议发布,
|
||||
* 允许在遵守协议的前提下进行商用、修改和分发。
|
||||
* *
|
||||
* 特别说明:
|
||||
* 所有衍生版本不得修改或移除系统默认的 LOGO 和版权信息;
|
||||
* 如需定制品牌,请通过官方渠道申请品牌定制授权。
|
||||
* *
|
||||
* 更多信息请访问:https://qmodel.qiantong.tech/business.html
|
||||
*/
|
||||
|
||||
package tech.qiantong.qmodel.mybatis.datasource;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* 数据源切换处理
|
||||
*
|
||||
* @author anivia
|
||||
*/
|
||||
public class DynamicDataSourceContextHolder
|
||||
{
|
||||
public static final Logger log = LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
|
||||
|
||||
/**
|
||||
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
|
||||
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
|
||||
*/
|
||||
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 设置数据源的变量
|
||||
*/
|
||||
public static void setDataSourceType(String dsType)
|
||||
{
|
||||
log.info("切换到{}数据源", dsType);
|
||||
CONTEXT_HOLDER.set(dsType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得数据源的变量
|
||||
*/
|
||||
public static String getDataSourceType()
|
||||
{
|
||||
return CONTEXT_HOLDER.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空数据源变量
|
||||
*/
|
||||
public static void clearDataSourceType()
|
||||
{
|
||||
CONTEXT_HOLDER.remove();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user