Merge branch 'master' into master

This commit is contained in:
yueke 2024-04-11 08:52:36 +08:00 committed by GitHub
commit 52982356a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
218 changed files with 8219 additions and 3192 deletions

View File

@ -0,0 +1,15 @@
### 当前使用版本(必填,否则不予处理)
### 该问题是如何引起的?(确定最新版也有问题再提!!!)
### 重现步骤(如果有就写完整)
### 报错信息

View File

@ -0,0 +1,15 @@
### 该Pull Request关联的Issue
### 修改描述
### 测试用例
### 修复效果的截屏

15
.github/ISSUE_TEMPLATE.zh-CN vendored Normal file
View File

@ -0,0 +1,15 @@
### 当前使用版本(必填,否则不予处理)
### 该问题是如何引起的?(确定最新版也有问题再提!!!)
### 重现步骤(如果有就写完整)
### 报错信息

15
.github/PULL_REQUEST_TEMPLATE.zh-CN vendored Normal file
View File

@ -0,0 +1,15 @@
### 该Pull Request关联的Issue
### 修改描述
### 测试用例
### 修复效果的截屏

11
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "gradle" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"

View File

@ -1,113 +0,0 @@
# mybatis-plus-join
#### @EntityMapping@FieldMapping 注解
UserDO.java
```java
@Data
@TableName("user")
public class UserDO {
@TableId
private Integer id;
private Integer pid;//父id
/* 其他属性略 */
/**
* 查询上级 一对一
*/
@TableField(exist = false)
@EntityMapping(thisField = "pid", joinField = "id")
private UserDO pUser;
/**
* 查询下级 一对多
*/
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "pid")
private List<UserDO> childUser;
/**
* 带条件的查询下级 一对多
*/
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "pid",
condition = {
@MPJMappingCondition(column = "sex", value = "0"),//sex = '0' 默认条件是等于
@MPJMappingCondition(column = "name", value = "张三", keyWord = SqlKeyword.LIKE)//name like '%a%'
},
apply = @MPJMappingApply(value = "id between 1 and 20"))//拼接sql 同 wrapper.apply()
private List<UserDO> childUserCondition;
/**
* 查询地址 (一对多)
*/
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "userId")
private List<UserAddressDO> addressList;
/**
* 绑定字段 (一对多)
*/
@TableField(exist = false)
@FieldMapping(tag = UserDO.class, thisField = "id", joinField = "pid", select = "id")
private List<Integer> childIds;
}
```
使用
```java
/**
* 一对一,一对多关系映射查询
* 如果不需要关系映射就使用mybatis plus原生方法即可比如 getById listByIds 等
* <p>
* 注意关系映射不会去关联查询而是执行多次单表查询对结果汇总后使用in语句查询,再对结果进行匹配)
*/
@SpringBootTest
class MappingTest {
@Resource
private UserMapper userMapper;
@Test
void test1() {
UserDO deep = userMapper.selectByIdDeep(2);
System.out.println(deep);
}
@Test
void test2() {
List<UserDO> list = userMapper.selectRelation(mapper -> mapper.selectList(Wrappers.emptyWrapper()));
list.forEach(System.out::println);
}
@Test
void test3() {
Page<UserDO> page = new Page<>(2, 2);
Page<UserDO> result = userMapper.selectRelation(mapper -> mapper.selectPage(page, Wrappers.emptyWrapper()));
result.getRecords().forEach(System.out::println);
}
/*
更多方法请查阅 MPJDeepMapper 或者 MPJDeepService
使用方式与 mybatis plus 一致
*/
}
```
MPJMapping 说明:
* @EntityMapping / @FieldMapping tag 关联实体类
* @EntityMapping / @FieldMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键
* @EntityMapping / @FieldMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键
* @EntityMapping / @FieldMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据
*
更多功能请看代码注释 [EntityMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/EntityMapping.java)
[FieldMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/FieldMapping.java)

162
README-zh.md Normal file
View File

@ -0,0 +1,162 @@
<!--suppress HtmlDeprecatedAttribute -->
<p align="center">
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img alt="Mybatis-Plus-Join-Logo" src="https://mybatisplusjoin.com/lg.png">
</a>
</p>
<h1 align="center">MyBatis-Plus-Join</h1>
<p align="center">
为简化开发工作、提高生产率而生
</p>
<p align="center">
<a href="https://central.sonatype.com/artifact/com.github.yulichang/mybatis-plus-join-boot-starter">
<img alt="maven" src="https://img.shields.io/maven-central/v/com.github.yulichang/mybatis-plus-join-boot-starter.svg?style=flat-square">
</a>
<a href="https://www.apache.org/licenses/LICENSE-2.0">
<img alt="code style" src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square">
</a>
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img src="https://img.shields.io/github/stars/yulichang/mybatis-plus-join.svg?style=social&label=Stars" alt=""/>
</a>
<a href="https://gitee.com/best_handsome/mybatis-plus-join" target="_blank">
<img src="https://gitee.com/best_handsome/mybatis-plus-join/badge/star.svg?theme=dark" alt=""/>
</a>
</p>
<p align="center">
<a href="https://gitee.com/baomidou/mybatis-plus" target="_blank">MyBatis-Plus</a> 多表查询的扩展 |
<a href="https://gitee.com/best_handsome/mybatis-plus-join-demo" target="_blank">演示工程</a> |
<a href="https://www.baidu.com/link?url=wdmhssysW-Mj19Gkcc2CBOzNVoimHat57mlnH78SEU_6y0awYgDKTBy7es9BXnAH&wd=&eqid=908484020001866e000000056440b5e3" target="_blank">使用文档</a> |
点个Star支持一下吧 (☆▽☆)
</p>
<p align="center">
QQ群:680016987 或者
<a href="https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M" target="_blank">添加作者微信备注MPJ加入微信群</a>
<br/>
<img width="200px" height="200px" src="https://mybatisplusjoin.com/qr.png" alt="添加作者微信备注MPJ加入微信群"/>
</p>
### <a href="https://www.baidu.com/link?url=6NtKqbGKUIIdwoBUaqNkQnLiG3d5y03L6Pfg6ODId0VKfPifpB1xqdQzsBprm-0h&wd=&eqid=d26e7f1600004777000000056440ade6" target="_blank">使用文档WIKI</a>
## 使用方法
### 安装
- Maven
```xml
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.12</version>
</dependency>
```
- Gradle
```
implementation 'com.github.yulichang:mybatis-plus-join-boot-starter:1.4.12'
```
或者clone代码到本地执行 mvn install, 再引入以上依赖
<br>
注意: MyBatis Plus版本需要3.3.0+
<br>
### 使用
* mapper继承MPJBaseMapper (必选)
* service继承MPJBaseService (可选)
* serviceImpl继承MPJBaseServiceImpl (可选)
### Lambda形式用法MPJLambdaWrapper
#### 简单的连表查询
```java
class test {
@Resource
private UserMapper userMapper;
void testJoin() {
//和Mybatis plus一致MPJLambdaWrapper的泛型必须是主表的泛型并且要用主表的Mapper来调用
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
.selectAll(UserDO.class)//查询user表全部字段
.select(UserAddressDO::getTel)//查询user_address tel 字段
.selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress)//别名
.select(AreaDO::getProvince, AreaDO::getCity)
.leftJoin(UserAddressDO.class, UserAddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, UserAddressDO::getAreaId)
.eq(UserDO::getId, 1)
.like(UserAddressDO::getTel, "1")
.gt(UserDO::getId, 5);
//连表查询 返回自定义ResultType
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
//分页查询 (需要启用 mybatis plus 分页插件)
Page<UserDTO> listPage = userMapper.selectJoinPage(new Page<>(2, 10), UserDTO.class, wrapper);
}
}
```
对应sql
```
SELECT
t.id, t.name, t.sex, t.head_img,
t1.tel, t1.address AS userAddress,
t2.province, t2.city
FROM
user t
LEFT JOIN user_address t1 ON t1.user_id = t.id
LEFT JOIN area t2 ON t2.id = t1.area_id
WHERE (
t.id = ?
AND t1.tel LIKE ?
AND t.id > ?)
```
说明:
* UserDTO.class 查询结果返回类(resultType)
* selectAll() 查询指定实体类的全部字段
* select() 查询指定的字段,支持可变参数,同一个select只能查询相同表的字段
* selectAs() 字段别名查询,用于数据库字段与业务实体类属性名不一致时使用
* leftJoin() 参数说明
第一个参数: 参与连表的实体类class
第二个参数: 连表的ON字段,这个属性必须是第一个参数实体类的属性
第三个参数: 参与连表的ON的另一个实体类属性
* 默认主表别名是t,其他的表别名以先后调用的顺序使用t1,t2,t3....
* 条件查询,可以查询主表以及参与连接的所有表的字段,全部调用mp原生的方法,正常使用没有sql注入风险
#### 一对多查询
```java
class test {
@Resource
private UserMapper userMapper;
@Test
void testResultMap() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<>(User.class)
.selectAll(UserDO.class)
//对多查询
.selectCollection(AddressDO.class, UesrDTO::getAddressList)
//对一查询
.selectAssociation(AddressDO.class, UesrDTO::getAddress)
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId);
List<UserDTO> dtoList = userMapper.selectJoinList(UserDTO.class, wrapper);
//关于对多分页查询
//由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
}
}
```
MPJLambdaWrapper其他功能
* <a href="https://mybatisplusjoin.com/pages/core/lambda/select/selectCollection.html" target="_blank">
一对一,一对多使用</a>
* <a href="https://mybatisplusjoin.com/pages/core/lambda/select/selectFunc.html" target="_blank">简单的SQL函数使用</a>
* <a href="https://mybatisplusjoin.com/pages/core/lambda/join/leftJoin.html" target="_blank">ON语句多条件支持</a>
* <a href="https://www.baidu.com/link?url=wdmhssysW-Mj19Gkcc2CBOzNVoimHat57mlnH78SEU_6y0awYgDKTBy7es9BXnAH&wd=&eqid=908484020001866e000000056440b5e3" target="_blank">其他全部功能请参考使用文档</a>
# <a href="https://www.baidu.com/link?url=wdmhssysW-Mj19Gkcc2CBOzNVoimHat57mlnH78SEU_6y0awYgDKTBy7es9BXnAH&wd=&eqid=908484020001866e000000056440b5e3" target="_blank">使用文档 wiki</a>

View File

@ -4,39 +4,36 @@
<img alt="Mybatis-Plus-Join-Logo" src="https://mybatisplusjoin.com/lg.png">
</a>
</p>
<h1 align="center">MyBatis-Plus-Join</h1>
<p align="center">
为简化开发工作、提高生产率而生
</p>
<p align="center">
<a href="https://central.sonatype.com/artifact/com.github.yulichang/mybatis-plus-join-boot-starter">
<img alt="maven" src="https://img.shields.io/maven-central/v/com.github.yulichang/mybatis-plus-join-boot-starter.svg?style=flat-square">
</a>
<a href="https://www.apache.org/licenses/LICENSE-2.0">
<img alt="code style" src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square">
</a>
<a href="https://github.com/yulichang/mybatis-plus-join" target="_blank">
<img src="https://img.shields.io/github/stars/yulichang/mybatis-plus-join.svg?style=social&label=Stars" alt=""/>
</a>
<a href="https://gitee.com/best_handsome/mybatis-plus-join" target="_blank">
<img src="https://gitee.com/best_handsome/mybatis-plus-join/badge/star.svg?theme=dark" alt=""/>
</a>
<br/>
<a href="https://central.sonatype.com/artifact/com.github.yulichang/mybatis-plus-join-boot-starter">
<img alt="maven" src="https://img.shields.io/maven-central/v/com.github.yulichang/mybatis-plus-join-boot-starter.svg?style=flat-square">
</a>
<a href="https://www.apache.org/licenses/LICENSE-2.0">
<img alt="code style" src="https://img.shields.io/badge/license-Apache%202-4EB1BA.svg?style=flat-square">
</a>
</p>
<h1 align="center">mybatis-plus-join</h1>
<p align="center">
<a href="https://gitee.com/baomidou/mybatis-plus" target="_blank">mybatis-plus</a> 多表查询的扩展 |
<a href="https://gitee.com/baomidou/mybatis-plus" target="_blank">MyBatis-Plus</a> 多表查询的扩展 |
<a href="https://gitee.com/best_handsome/mybatis-plus-join-demo" target="_blank">演示工程</a> |
<a href="https://www.baidu.com/link?url=wdmhssysW-Mj19Gkcc2CBOzNVoimHat57mlnH78SEU_6y0awYgDKTBy7es9BXnAH&wd=&eqid=908484020001866e000000056440b5e3" target="_blank">使用文档</a> |
点个Star支持一下吧 (☆▽☆)
</p>
<p align="center">
QQ群:1022221898 或者
<a href="https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M" target="_blank">添加作者微信备注MPJ加入微信群</a>
QQ群:680016987 或者
<a href="https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M" target="_blank">添加作者微信备注MPJ加入微信群</a>
<br/>
<img width="200px" src="https://mybatisplusjoin.com/qr.png" alt="添加作者微信备注MPJ加入微信群"/>
<img width="200px" height="200px" src="https://mybatisplusjoin.com/qr.png" alt="添加作者微信备注MPJ加入微信群"/>
</p>
### <a href="https://www.baidu.com/link?url=6NtKqbGKUIIdwoBUaqNkQnLiG3d5y03L6Pfg6ODId0VKfPifpB1xqdQzsBprm-0h&wd=&eqid=d26e7f1600004777000000056440ade6" target="_blank">使用文档WIKI</a>
@ -50,16 +47,16 @@ QQ群:1022221898 或者
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.6</version>
<version>1.4.12</version>
</dependency>
```
- Gradle
```
implementation 'com.github.yulichang:mybatis-plus-join-boot-starter:1.4.6'
implementation 'com.github.yulichang:mybatis-plus-join-boot-starter:1.4.12'
```
或者clone代码到本地执行 mvn install, 再引入以上依赖
<br>
注意: mybatis plus version >= 3.3.0
注意: MyBatis Plus版本需要3.3.0+
<br>
### 使用

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>mybatis-plus-join-adapter-jsqlparser-v46</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-jsqlparser-v46</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.5.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,59 @@
package com.github.yulichang.adapter.jsqlparser.v46;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.*;
import java.util.function.Consumer;
/**
* 字段解析
*
* @author yulichang
* @since 1.4.12
*/
public class JSqlParserHelperV46 {
public static void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
try {
boolean parser = false;
Statement statement = CCJSqlParserUtil.parse(String.format("SELECT %s FROM table %s %s", selectSql, alias, from));
if (statement instanceof Select) {
Select select = (Select) statement;
SelectBody selectBody = select.getSelectBody();
if (selectBody instanceof PlainSelect) {
PlainSelect plainSelect = (PlainSelect) selectBody;
if (CollectionUtils.isNotEmpty(plainSelect.getSelectItems())) {
for (SelectItem item : plainSelect.getSelectItems()) {
if (item instanceof SelectExpressionItem) {
String col;
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) item;
if (null == selectExpressionItem.getAlias()) {
if (selectExpressionItem.getExpression() instanceof Column) {
col = ((Column) selectExpressionItem.getExpression()).getColumnName();
} else {
col = selectExpressionItem.getExpression().toString();
}
} else {
col = selectExpressionItem.getAlias().getName();
}
if (StringUtils.isNotBlank(col)) {
columConsumer.accept(StringUtils.getTargetColumn(col));
}
}
}
parser = true;
}
}
if (!parser)
throw ExceptionUtils.mpe("JSqlParser parser error <%s>", selectSql);
}
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
}

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>mybatis-plus-join-adapter-jsqlparser</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-jsqlparser</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>${mpj.mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,54 @@
package com.github.yulichang.adapter.jsqlparser;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectItem;
import java.util.function.Consumer;
/**
* 字段解析
*
* @author yulichang
* @since 1.4.12
*/
public class JSqlParserHelper {
public static void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
try {
boolean parser = false;
Statement statement = CCJSqlParserUtil.parse(String.format("SELECT %s FROM table %s %s", selectSql, alias, from));
if (statement instanceof PlainSelect) {
PlainSelect plainSelect = (PlainSelect) statement;
if (CollectionUtils.isNotEmpty(plainSelect.getSelectItems())) {
for (SelectItem<?> item : plainSelect.getSelectItems()) {
String col;
if (item.getAlias() == null) {
if (item.getExpression() instanceof Column) {
Column column = (Column) item.getExpression();
col = column.getColumnName();
} else {
col = item.getExpression().toString();
}
} else {
col = item.getAlias().getName();
}
if (StringUtils.isNotBlank(col)) {
columConsumer.accept(StringUtils.getTargetColumn(col));
}
}
parser = true;
}
}
if (!parser)
throw ExceptionUtils.mpe("JSqlParser parser error <%s>", selectSql);
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
}
}
}

View File

@ -6,10 +6,10 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-base</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
@ -33,21 +33,22 @@
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.5.3.2</version>
<version>${mpj.mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-jsqlparser</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-jsqlparser-v46</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,50 @@
package com.github.yulichang.adapter.base;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.3
*/
public interface IAdapter {
default boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isWithLogicDelete();
}
default boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.isPrimitive();
}
default TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getLogicDeleteFieldInfo();
}
default boolean mpjHasPK(TableInfo tableInfo) {
return tableInfo.havePK();
}
default Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
default Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return fieldInfo.getField();
}
default List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
return tableInfo.getOrderByFields().stream().map(f ->
new OrderFieldInfo(f.getColumn(), f.getType(), f.getSort())).collect(Collectors.toList());
}
void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer);
}

View File

@ -1,27 +0,0 @@
package com.github.yulichang.adapter.base;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field;
import java.util.function.Supplier;
/**
* @author yulichang
* @since 1.4.3
*/
public interface ITableInfoAdapter {
boolean mpjHasLogic(TableInfo tableInfo);
boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo);
TableFieldInfo mpjGetLogicField(TableInfo tableInfo);
boolean mpjHasPK(TableInfo tableInfo);
Configuration mpjGetConfiguration(TableInfo tableInfo);
Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier);
}

View File

@ -0,0 +1,35 @@
package com.github.yulichang.adapter.base.metadata;
import lombok.Data;
/**
* 兼容MP 3.5.4
* copy {@link com.baomidou.mybatisplus.core.metadata.OrderFieldInfo}
*
* @since 1.4.7
*/
@Data
public class OrderFieldInfo {
/**
* 字段
*/
private String column;
/**
* 排序类型
*/
private String type;
/**
* 排序顺序
*/
private short sort;
public OrderFieldInfo(String column, String type, short orderBySort) {
this.column = column;
this.type = type;
this.sort = orderBySort;
}
}

View File

@ -6,10 +6,10 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v33x</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v33x</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
@ -46,7 +46,7 @@
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>

View File

@ -1,20 +1,28 @@
package com.github.yulichang.adapter.v33x;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.adapter.base.ITableInfoAdapter;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;
/**
* @author yulichang
* @since 1.4.3
*/
public class TableInfoAdapterV33x implements ITableInfoAdapter {
public class AdapterV33x implements IAdapter {
private static final boolean is330 = VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.3.0") == 0;
@Override
public boolean mpjHasLogic(TableInfo tableInfo) {
@ -45,6 +53,16 @@ public class TableInfoAdapterV33x implements ITableInfoAdapter {
@Override
public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return supplier.get();
return is330 ? supplier.get() : IAdapter.super.mpjGetField(fieldInfo, null);
}
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
throw new UnsupportedOperationException("不支持排序");
}
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
}

View File

@ -6,10 +6,10 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v3431</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v3431</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
@ -46,7 +46,7 @@
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>

View File

@ -0,0 +1,34 @@
package com.github.yulichang.adapter.v3431;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import lombok.AllArgsConstructor;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.7
*/
@AllArgsConstructor
public class Adapter3431 implements IAdapter {
private static final boolean v = VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3") < 0;
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
return v ? null : tableInfo.getOrderByFields().stream().map(f ->
new OrderFieldInfo(f.getColumn(), f.getOrderByType(), f.getOrderBySort())).collect(Collectors.toList());
}
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
}

View File

@ -6,10 +6,10 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v352</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v352</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter</artifactId>
<version>${revision}</version>
</parent>
<artifactId>mybatis-plus-join-adapter-v355</artifactId>
<version>${revision}</version>
<name>mybatis-plus-join-adapter-v355</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url>
<licenses>
<license>
<name>The Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<developers>
<developer>
<id>mybatis-plus-join</id>
<name>yulichang</name>
<email>yu_lichang@qq.com</email>
</developer>
</developers>
<scm>
<connection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</connection>
<developerConnection>scm:git:https://github.com/yulichang/mybatis-plus-join.git</developerConnection>
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>3.5.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,18 @@
package com.github.yulichang.adapter.v355;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.jsqlparser.v46.JSqlParserHelperV46;
import java.util.function.Consumer;
/**
* @author yulichang
* @since 1.4.12
*/
public class Adapter355 implements IAdapter {
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelperV46.parserColum(alias, from, selectSql, columConsumer);
}
}

View File

@ -5,10 +5,10 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<packaging>pom</packaging>
<version>1.4.6</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-adapter</artifactId>
<name>mybatis-plus-join-adapter</name>
@ -17,6 +17,9 @@
<module>mybatis-plus-join-adapter-v33x</module>
<module>mybatis-plus-join-adapter-v3431</module>
<module>mybatis-plus-join-adapter-v352</module>
<module>mybatis-plus-join-adapter-v355</module>
<module>jsqlparser/mybatis-plus-join-adapter-jsqlparser</module>
<module>jsqlparser/mybatis-plus-join-adapter-jsqlparser-v46</module>
</modules>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
@ -40,12 +43,11 @@
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -7,9 +7,9 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<version>1.4.6</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-annotation</artifactId>
<name>mybatis-plus-join-annotation</name>

View File

@ -10,9 +10,9 @@ import java.lang.annotation.*;
* @since 1.2.0
*/
@Documented
@SuppressWarnings({"unused"})
@SuppressWarnings("unused")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Target(ElementType.FIELD)
public @interface EntityMapping {
/**

View File

@ -10,9 +10,9 @@ import java.lang.annotation.*;
* @since 1.2.0
*/
@Documented
@SuppressWarnings({"unused"})
@SuppressWarnings("unused")
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Target(ElementType.FIELD)
public @interface FieldMapping {
/**

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress ALL -->
<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">
@ -7,9 +6,9 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<version>1.4.6</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<name>mybatis-plus-join-boot-starter</name>
@ -34,37 +33,26 @@
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-extension</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
<version>${mpj.mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -2,20 +2,25 @@ package com.github.yulichang.autoconfigure;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusLanguageDriverAutoConfiguration;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.github.yulichang.autoconfigure.conditional.MPJSqlInjectorCondition;
import com.github.yulichang.autoconfigure.conditional.JoinSqlInjectorCondition;
import com.github.yulichang.autoconfigure.consumer.MybatisPlusJoinIfExistsConsumer;
import com.github.yulichang.autoconfigure.consumer.MybatisPlusJoinPropertiesConsumer;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.config.MPJInterceptorConfig;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import com.github.yulichang.extension.mapping.config.MappingConfig;
import com.github.yulichang.toolkit.SpringContentUtils;
import com.github.yulichang.injector.MPJSqlInjector;
import com.github.yulichang.interceptor.MPJInterceptor;
import com.github.yulichang.toolkit.SpringContentUtils;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -35,6 +40,8 @@ import org.springframework.core.annotation.Order;
import javax.sql.DataSource;
import java.util.List;
import java.util.Optional;
import java.util.function.BiPredicate;
/**
* springboot 自动配置类
@ -42,7 +49,6 @@ import java.util.List;
* @author yulichang
* @since 1.3.7
*/
@SuppressWarnings("ALL")
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
@ConditionalOnSingleCandidate(DataSource.class)
@ -52,20 +58,23 @@ public class MybatisPlusJoinAutoConfiguration {
private static final Logger logger = LoggerFactory.getLogger(MybatisPlusJoinAutoConfiguration.class);
@SuppressWarnings("FieldCanBeLocal")
private final MybatisPlusJoinProperties properties;
public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties) {
this.properties = properties;
ConfigProperties.subTableLogic = properties.getSubTableLogic();
ConfigProperties.msCache = properties.isMsCache();
ConfigProperties.tableAlias = properties.getTableAlias();
ConfigProperties.joinPrefix = properties.getJoinPrefix();
ConfigProperties.logicDelType = "where".equalsIgnoreCase(properties.getLogicDelType()) ?
LogicDelTypeEnum.WHERE : LogicDelTypeEnum.ON;
ConfigProperties.mappingMaxCount = properties.getMappingMaxCount();
public MybatisPlusJoinAutoConfiguration(MybatisPlusJoinProperties properties,
ObjectProvider<MybatisPlusJoinPropertiesConsumer> propertiesConsumers,
ObjectProvider<MybatisPlusJoinIfExistsConsumer> IfExistsConsumers) {
this.properties = Optional.ofNullable(propertiesConsumers.getIfAvailable()).map(c -> c.config(properties)).orElse(properties);
ConfigProperties.banner = this.properties.getBanner();
ConfigProperties.subTableLogic = this.properties.getSubTableLogic();
ConfigProperties.msCache = this.properties.isMsCache();
ConfigProperties.tableAlias = this.properties.getTableAlias();
ConfigProperties.joinPrefix = this.properties.getJoinPrefix();
ConfigProperties.logicDelType = this.properties.getLogicDelType();
ConfigProperties.mappingMaxCount = this.properties.getMappingMaxCount();
ConfigProperties.ifExists = Optional.ofNullable(IfExistsConsumers.getIfAvailable())
.map(m -> (BiPredicate<Object, IfExistsSqlKeyWordEnum>) m)
.orElse((val, key) -> this.properties.getIfExists().test(val));
info("mybatis plus join properties config complete");
}
/**
@ -81,8 +90,9 @@ public class MybatisPlusJoinAutoConfiguration {
* mybatis plus 拦截器配置
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJInterceptorConfig mpjInterceptorConfig(@Autowired(required = false) List<SqlSessionFactory> sqlSessionFactoryList) {
public MPJInterceptorConfig mpjInterceptorConfig(List<SqlSessionFactory> sqlSessionFactoryList) {
return new MPJInterceptorConfig(sqlSessionFactoryList, properties.getBanner());
}
@ -91,12 +101,12 @@ public class MybatisPlusJoinAutoConfiguration {
*/
@Bean
@Primary
@MPJSqlInjectorCondition
@JoinSqlInjectorCondition
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnBean(ISqlInjector.class)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJSqlInjector mpjSqlInjector(ISqlInjector sqlInjector) {
logger.info("MPJSqlInjector init");
info("mybatis plus join SqlInjector init");
return new MPJSqlInjector(sqlInjector);
}
@ -108,45 +118,62 @@ public class MybatisPlusJoinAutoConfiguration {
@ConditionalOnMissingBean(ISqlInjector.class)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public MPJSqlInjector mpjSqlInjectorOnMiss() {
logger.info("MPJSqlInjector init");
info("mybatis plus join SqlInjector init");
return new MPJSqlInjector();
}
/**
* springboot context 工具类
*/
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public SpringContentUtils mpjSpringContent(@Autowired(required = false) MPJSpringContext springContext) {
return new SpringContentUtils(springContext);
}
@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public static class MPJMappingConfig implements ApplicationListener<ApplicationReadyEvent> {
@Override
@SuppressWarnings("NullableProblems")
public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
new MappingConfig();
MappingConfig.init();
}
}
private void info(String info) {
if (properties.getBanner()) {
logger.info(info);
}
}
@Configuration
@ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class})
public static class MPJSpringContext implements SpringContentUtils.SpringContext, ApplicationContextAware {
public static class MPJSpringContext implements SpringContentUtils.SpringContext, BeanFactoryPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
private ListableBeanFactory listableBeanFactory;
@Override
public <T> T getBean(Class<T> clazz) {
return this.applicationContext.getBean(clazz);
return getBeanFactory().getBean(clazz);
}
@Override
public <T> void getBeansOfType(Class<T> clazz) {
getBeanFactory().getBeansOfType(clazz);
}
private ListableBeanFactory getBeanFactory() {
return applicationContext == null ? listableBeanFactory : applicationContext;
}
@Override
@SuppressWarnings("NullableProblems")
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
SpringContentUtils.setSpringContext(this);
}
@Override
@SuppressWarnings("NullableProblems")
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.listableBeanFactory = beanFactory;
SpringContentUtils.setSpringContext(this);
}
}
}

View File

@ -1,5 +1,7 @@
package com.github.yulichang.autoconfigure;
import com.github.yulichang.config.enums.IfExistsEnum;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ -43,7 +45,7 @@ public class MybatisPlusJoinProperties {
/**
* 逻辑删除类型 支持 where on
*/
private String logicDelType = "where";
private LogicDelTypeEnum logicDelType = LogicDelTypeEnum.ON;
/**
* 映射查询最大深度
@ -54,4 +56,15 @@ public class MybatisPlusJoinProperties {
* 子查询别名
*/
private String subQueryAlias = "st";
/**
* Wrapper IfExists 判断策略
* <p>
* NOT_NULL 非null
* <p>
* NOT_EMPTY 非空字符串 "" -> false, " " -> true ...
* <p>
* NOT_BLANK 非空白字符串 "" -> false, " " -> false, "\r" -> false, "abc" -> true ...
*/
private IfExistsEnum IfExists = IfExistsEnum.NOT_EMPTY;
}

View File

@ -13,5 +13,5 @@ import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Conditional(OnSqlInjectorCondition.class)
public @interface MPJSqlInjectorCondition {
public @interface JoinSqlInjectorCondition {
}

View File

@ -0,0 +1,14 @@
package com.github.yulichang.autoconfigure.consumer;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import java.util.function.BiPredicate;
/**
* 自定义IfExists策略
*
* @author yulichang
* @since 1.4.9
*/
public interface MybatisPlusJoinIfExistsConsumer extends BiPredicate<Object, IfExistsSqlKeyWordEnum> {
}

View File

@ -0,0 +1,20 @@
package com.github.yulichang.autoconfigure.consumer;
import com.github.yulichang.autoconfigure.MybatisPlusJoinProperties;
/**
* 自定义配置
*
* @author yulichang
* @since 1.4.9
*/
public interface MybatisPlusJoinPropertiesConsumer {
/**
* 自定义配置此方法会覆盖配置文件中的MPJ配置
*
* @param properties 配置文件里的配置
* @return 修改后的配置
*/
MybatisPlusJoinProperties config(MybatisPlusJoinProperties properties);
}

View File

@ -40,8 +40,8 @@
},
{
"name": "mybatis-plus-join.logic-del-type",
"defaultValue": "where",
"type": "java.lang.String",
"defaultValue": "com.github.yulichang.config.enums.LogicDelTypeEnum.ON",
"type": "com.github.yulichang.config.enums.LogicDelTypeEnum",
"description": "逻辑删除的位置支持where和on两个."
},
{
@ -55,21 +55,12 @@
"defaultValue": "st",
"type": "java.lang.String",
"description": "子查询表别名."
}
],
"hints": [
},
{
"name": "mybatis-plus-join.logic-del-type",
"values": [
{
"value": "where",
"description": "logic delete condition to where."
},
{
"value": "on",
"description": "logic delete condition to on."
}
]
"name": "mybatis-plus-join.if-exist",
"defaultValue": "com.github.yulichang.config.enums.IfExistsEnum.NOT_EMPTY",
"type": "com.github.yulichang.config.enums.IfExistsEnum",
"description": "IfExists方法判断策略,如需自定义请用@Bean形式MybatisPlusJoinIfExistsConsumer."
}
]
}

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress VulnerableLibrariesLocal -->
<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">
@ -7,9 +6,9 @@
<parent>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-root</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</parent>
<version>1.4.6</version>
<version>${revision}</version>
<artifactId>mybatis-plus-join-core</artifactId>
<name>mybatis-plus-join-core</name>
@ -34,58 +33,51 @@
<url>https://github.com/yulichang/mybatis-plus-join</url>
</scm>
<properties>
<jdkVersion>1.8</jdkVersion>
<jdkVersion.test>1.8</jdkVersion.test>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<github.global.server>github</github.global.server>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-annotation</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v33x</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v3431</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v352</artifactId>
<version>1.4.6</version>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v355</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.5.3.2</version>
<version>${mpj.mybatis.plus.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.29</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
<version>1.9.0</version>
<scope>provided</scope>
</dependency>
</dependencies>

View File

@ -0,0 +1,18 @@
package com.github.yulichang.adapter;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.jsqlparser.JSqlParserHelper;
import java.util.function.Consumer;
/**
* @author yulichang
* @since 1.4.3
*/
public class Adapter implements IAdapter {
@Override
public void parserColum(String alias, String from, String selectSql, Consumer<String> columConsumer) {
JSqlParserHelper.parserColum(alias, from, selectSql, columConsumer);
}
}

View File

@ -1,9 +1,13 @@
package com.github.yulichang.adapter;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.adapter.base.ITableInfoAdapter;
import com.github.yulichang.adapter.v33x.TableInfoAdapterV33x;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.v33x.AdapterV33x;
import com.github.yulichang.adapter.v3431.Adapter3431;
import com.github.yulichang.adapter.v355.Adapter355;
import lombok.Getter;
/**
* @author yulichang
@ -11,18 +15,23 @@ import com.github.yulichang.adapter.v33x.TableInfoAdapterV33x;
*/
public class AdapterHelper {
private static final ITableInfoAdapter adapter;
@Getter
private static final IAdapter adapter;
static {
String version = MybatisPlusVersion.getVersion();
if (StringUtils.isNotBlank(version) && version.startsWith("3.3.")) {
adapter = new TableInfoAdapterV33x();
if (VersionUtils.compare(version, "3.5.6") >= 0) {
adapter = new Adapter();
} else if (VersionUtils.compare(version, "3.5.4") >= 0) {
adapter = new Adapter355();
} else if (VersionUtils.compare(version, "3.4.0") >= 0) {
adapter = new Adapter3431();
} else if (VersionUtils.compare(version, "3.3.0") >= 0) {
adapter = new AdapterV33x();
} else {
adapter = new TableInfoAdapter();
throw ExceptionUtils.mpe("MPJ需要MP版本3.3.0+当前MP版本%s", version);
}
}
public static ITableInfoAdapter getTableInfoAdapter() {
return adapter;
}
}

View File

@ -1,46 +0,0 @@
package com.github.yulichang.adapter;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.adapter.base.ITableInfoAdapter;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field;
import java.util.function.Supplier;
/**
* @author yulichang
* @since 1.4.3
*/
public class TableInfoAdapter implements ITableInfoAdapter {
@Override
public boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isWithLogicDelete();
}
@Override
public boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.isPrimitive();
}
@Override
public TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getLogicDeleteFieldInfo();
}
@Override
public boolean mpjHasPK(TableInfo tableInfo) {
return tableInfo.havePK();
}
@Override
public Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
@Override
public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return fieldInfo.getField();
}
}

View File

@ -1,8 +1,12 @@
package com.github.yulichang.config;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.adapter.base.ITableInfoAdapter;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.config.enums.IfExistsEnum;
import com.github.yulichang.config.enums.LogicDelTypeEnum;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import java.util.function.BiPredicate;
/**
* @author yulichang
@ -10,6 +14,10 @@ import com.github.yulichang.config.enums.LogicDelTypeEnum;
*/
public class ConfigProperties {
/**
* 是否打印banner
*/
public static boolean banner = true;
/**
* 是否开启副表逻辑删除
*/
@ -29,17 +37,27 @@ public class ConfigProperties {
/**
* 逻辑删除类型 支持 where on
*/
public static LogicDelTypeEnum logicDelType = LogicDelTypeEnum.WHERE;
public static LogicDelTypeEnum logicDelType = LogicDelTypeEnum.ON;
/**
* 逻辑删除类型 支持 where on
* 映射查询最大深度
*/
public static int mappingMaxCount = 5;
/**
* TableInfo适配器
*/
public static ITableInfoAdapter tableInfoAdapter = AdapterHelper.getTableInfoAdapter();
public static IAdapter tableInfoAdapter = AdapterHelper.getAdapter();
/**
* 子查询别名
*/
public static String subQueryAlias = "st";
/**
* Wrapper IfExists 判断策略
* <p>
* NOT_NULL 非null
* <p>
* NOT_EMPTY 非空字符串 "" -> false, " " -> true ...
* <p>
* NOT_BLANK 非空白字符串 "" -> false, " " -> false, "\r" -> false, "abc" -> true ...
*/
public static BiPredicate<Object, IfExistsSqlKeyWordEnum> ifExists = (val, key) -> IfExistsEnum.NOT_EMPTY.test(val);
}

View File

@ -30,7 +30,7 @@ public class MPJInterceptorConfig {
System.out.println(" _ _ |_ _ _|_. ___ _ | _ . _ . _ \n" +
"| | |\\/|_)(_| | |_\\ |_)||_|_\\ | (_) | | | \n" +
" / | /\n" +
" 1.4.6");
" 1.4.12");
}
}

View File

@ -0,0 +1,39 @@
package com.github.yulichang.config.enums;
import com.github.yulichang.toolkit.MPJStringUtils;
import java.util.Objects;
import java.util.function.Predicate;
/**
* 条件判断策略
*
* @author yulichang
* @since 1.4.9
*/
public enum IfExistsEnum implements Predicate<Object> {
/**
* 非null
*/
NOT_NULL(Objects::nonNull),
/**
* 非空字符串 "" -> false, " " -> true ...
*/
NOT_EMPTY(val -> NOT_NULL.and(v -> !(v instanceof CharSequence) || MPJStringUtils.isNotEmpty((CharSequence) v)).test(val)),
/**
* NOT_BLANK 非空白字符串 "" -> false, " " -> false, "\r" -> false, "abc" -> true ...
*/
NOT_BLANK(val -> NOT_NULL.and(v -> !(v instanceof CharSequence) || MPJStringUtils.isNotBlank((CharSequence) v)).test(val));
private final Predicate<Object> predicate;
IfExistsEnum(Predicate<Object> predicate) {
this.predicate = predicate;
}
@Override
public boolean test(Object obj) {
return this.predicate.test(obj);
}
}

View File

@ -11,11 +11,11 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.v3431.AbstractMethodV3431;
import com.github.yulichang.method.*;
import com.github.yulichang.toolkit.MPJTableMapperHelper;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.VersionUtils;
import com.github.yulichang.toolkit.reflect.GenericTypeUtils;
import lombok.Getter;
import org.apache.ibatis.builder.MapperBuilderAssistant;
@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
@ -38,9 +39,9 @@ import static java.util.stream.Collectors.toList;
* @author yulichang
* @see DefaultSqlInjector
*/
@Getter
public class MPJSqlInjector extends DefaultSqlInjector {
@Getter
private AbstractSqlInjector sqlInjector;
public MPJSqlInjector() {
@ -167,7 +168,14 @@ public class MPJSqlInjector extends DefaultSqlInjector {
Class<?> modelClass = getSuperClassGenericType(mapperClass, Mapper.class, 0);
super.inspectInject(builderAssistant, mapperClass);
MPJTableMapperHelper.init(modelClass, mapperClass);
TableHelper.init(modelClass, extractModelClassOld(mapperClass));
Supplier<Class<?>> supplier = () -> {
try {
return extractModelClassOld(mapperClass);
} catch (Throwable throwable) {
return null;
}
};
TableHelper.init(modelClass, supplier.get());
}
public static Class<?> getSuperClassGenericType(final Class<?> clazz, final Class<?> genericIfc, final int index) {

View File

@ -1,9 +1,12 @@
package com.github.yulichang.interceptor;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.method.MPJResultType;
import com.github.yulichang.interfaces.MPJBaseJoin;
import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.MPJReflectionKit;
@ -15,6 +18,8 @@ import com.github.yulichang.wrapper.resultmap.IResult;
import com.github.yulichang.wrapper.resultmap.Label;
import com.github.yulichang.wrapper.segments.Select;
import com.github.yulichang.wrapper.segments.SelectLabel;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultFlag;
@ -41,14 +46,18 @@ import java.util.concurrent.ConcurrentHashMap;
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class MPJInterceptor implements Interceptor {
private static final boolean v = VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3.1") > 0;
private static final List<ResultMapping> EMPTY_RESULT_MAPPING = new ArrayList<>(0);
/**
* 缓存MappedStatement,不需要每次都去重新构建MappedStatement
* 缓存MappedStatement,不需要每次都去构建MappedStatement
*/
private static final Map<String, Map<Configuration, MappedStatement>> MS_CACHE = new ConcurrentHashMap<>();
private static final Map<String, Val> MS_MAPPER_CACHE = new ConcurrentHashMap<>();
private static final Map<String, Val> RES_MAPPER_CACHE = new ConcurrentHashMap<>();
@Override
@SuppressWarnings("Java8MapApi")
@ -59,16 +68,24 @@ public class MPJInterceptor implements Interceptor {
if (args[1] instanceof Map) {
Map<String, Object> map = (Map<String, Object>) args[1];
Object ew = map.containsKey(Constants.WRAPPER) ? map.get(Constants.WRAPPER) : null;
if (CollectionUtils.isNotEmpty(map) && map.containsKey(Constant.CLAZZ)) {
Class<?> clazz = (Class<?>) map.get(Constant.CLAZZ);
if (Objects.nonNull(clazz)) {
List<ResultMap> list = ms.getResultMaps();
if (CollectionUtils.isNotEmpty(list)) {
ResultMap resultMap = list.get(0);
if (resultMap.getType() == MPJResultType.class) {
args[0] = getMappedStatement(ms, clazz, ew);
if (Objects.nonNull(ew) && ew instanceof MPJBaseJoin) {
if (CollectionUtils.isNotEmpty(map)) {
Class<?> rt = null;
if (map.containsKey(Constant.CLAZZ)) {
rt = (Class<?>) map.get(Constant.CLAZZ);
} else {
if (CollectionUtils.isNotEmpty(ms.getResultMaps())) {
Class<?> entity = MPJTableMapperHelper.getEntity(getMapper(ms.getId(), ms.getResource()));
Class<?> type = ms.getResultMaps().get(0).getType();
if (Objects.nonNull(entity) && Objects.nonNull(type)
&& !MPJReflectionKit.isPrimitiveOrWrapper(type) && entity == type) {
rt = type;
}
}
}
if (Objects.nonNull(rt)) {
args[0] = getMappedStatement(ms, rt, ew);
}
}
}
}
@ -86,7 +103,7 @@ public class MPJInterceptor implements Interceptor {
if (ew instanceof SelectWrapper) {
SelectWrapper wrapper = (SelectWrapper) ew;
if (wrapper.getEntityClass() == null) {
wrapper.setEntityClass(MPJTableMapperHelper.getEntity(getEntity(ms.getId(), ms.getResource())));
wrapper.setEntityClass(MPJTableMapperHelper.getEntity(getMapper(ms.getId(), ms.getResource())));
}
if (wrapper.getSelectColumns().isEmpty() && wrapper.getEntityClass() != null) {
wrapper.selectAll(wrapper.getEntityClass());
@ -183,11 +200,23 @@ public class MPJInterceptor implements Interceptor {
}
} else {
FieldCache field = fieldMap.get(i.getColumProperty());
columnSet.add(i.getTagColumn());
if (Objects.nonNull(field)) {
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), i.getColumProperty(),
i.getTagColumn(), field.getType());
resultMappings.add(selectToResult(wrapper.getEntityClass(), i, field.getType(), builder));
if (StringUtils.isNotBlank(i.getTagColumn())) {
columnSet.add(i.getTagColumn());
if (Objects.nonNull(field)) {
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), i.getColumProperty(),
i.getTagColumn(), field.getType());
resultMappings.add(selectToResult(wrapper.getEntityClass(), i, field.getType(), builder));
}
} else if (wrapper.isResultMap()) {
AdapterHelper.getAdapter().parserColum(wrapper.getAlias(), wrapper.getFrom(), i.getColumn(), col -> {
FieldCache strField = fieldMap.get(col);
columnSet.add(col);
if (Objects.nonNull(strField)) {
ResultMapping.Builder builder = new ResultMapping.Builder(ms.getConfiguration(), col,
col, strField.getType());
resultMappings.add(selectToResult(wrapper.getEntityClass(), i, strField.getType(), builder));
}
});
}
}
}
@ -286,7 +315,7 @@ public class MPJInterceptor implements Interceptor {
childId.append("]");
}
//双检
String id = childId.toString();
String id = v ? childId.toString() : childId.toString().replaceAll("\\.", "~");
if (!ms.getConfiguration().hasResultMap(id)) {
ResultMap build = new ResultMap.Builder(ms.getConfiguration(), id, mybatisLabel.getOfType(), childMapping).build();
MPJInterceptor.addResultMap(ms, id, build);
@ -359,29 +388,37 @@ public class MPJInterceptor implements Interceptor {
}
}
private Class<?> getEntity(String id, String resource) {
Class<?> clazz = null;
try {
String className = id.substring(0, id.lastIndexOf(StringPool.DOT));
private Class<?> getMapper(String id, String resource) {
Class<?> clazz = MS_MAPPER_CACHE.computeIfAbsent(id, key -> {
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
clazz = MPJTableMapperHelper.getMapperForName(className);
String className = key.substring(0, key.lastIndexOf(StringPool.DOT));
try {
return new Val(Class.forName(className));
} catch (ClassNotFoundException e) {
return new Val(MPJTableMapperHelper.getMapperForName(className));
}
} catch (Exception ignored) {
return new Val(null);
}
} catch (Exception ignored) {
}
}).getVal();
if (Objects.nonNull(clazz)) {
return clazz;
}
try {
String className = resource.substring(0, id.lastIndexOf(StringPool.DOT)).replaceAll("/", StringPool.DOT);
clazz = RES_MAPPER_CACHE.computeIfAbsent(resource, key -> {
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
clazz = MPJTableMapperHelper.getMapperForName(className);
String className = key.substring(0, key.lastIndexOf(StringPool.DOT)).replaceAll("/", StringPool.DOT);
try {
return new Val(Class.forName(className));
} catch (ClassNotFoundException e) {
return new Val(MPJTableMapperHelper.getMapperForName(className));
}
} catch (Exception ignored) {
return new Val(null);
}
} catch (Exception ignored) {
}
}).getVal();
return clazz;
}
@ -397,7 +434,7 @@ public class MPJInterceptor implements Interceptor {
public Object plugin(Object target) {
try {
return Interceptor.super.plugin(target);
} catch (Exception e) {
} catch (Throwable e) {
return Plugin.wrap(target, this);
}
}
@ -406,7 +443,13 @@ public class MPJInterceptor implements Interceptor {
public void setProperties(Properties properties) {
try {
Interceptor.super.setProperties(properties);
} catch (Exception ignored) {
} catch (Throwable ignored) {
}
}
@Data
@AllArgsConstructor
public static class Val {
private Class<?> val;
}
}

View File

@ -43,6 +43,7 @@ public abstract class KtAbstractLambdaWrapper<T, Children extends KtAbstractLamb
/**
* 主表别名
*/
@Getter
protected String alias = ConfigProperties.tableAlias;
/**
* 副表别名
@ -217,18 +218,13 @@ public abstract class KtAbstractLambdaWrapper<T, Children extends KtAbstractLamb
}
@Override
protected String columnToString(Integer index, Object column, boolean isJoin, PrefixEnum prefixEnum) {
return columnToString(index, (KProperty<?>) column, isJoin, prefixEnum);
protected final String columnsToString(Integer index, PrefixEnum prefixEnum, String alias, KProperty<?>... columns) {
return Arrays.stream(columns).map(i -> columnToString(index, alias, i, false, prefixEnum)).collect(joining(StringPool.COMMA));
}
@Override
protected final String columnsToString(Integer index, boolean isJoin, PrefixEnum prefixEnum, Object... columns) {
return Arrays.stream(columns).map(i -> columnToString(index, (KProperty<?>) i, isJoin, prefixEnum)).collect(joining(StringPool.COMMA));
}
protected String columnToString(Integer index, KProperty<?> column, boolean isJoin, PrefixEnum prefixEnum) {
protected String columnToString(Integer index, String alias, KProperty<?> column, boolean isJoin, PrefixEnum prefixEnum) {
Class<?> entityClass = KtUtils.ref(column);
return getDefault(index, entityClass, isJoin, prefixEnum) + StringPool.DOT + getCache(column).getColumn();
return (alias == null ? getDefault(index, entityClass, isJoin, prefixEnum) : alias) + StringPool.DOT + getCache(column).getColumn();
}
protected SelectCache getCache(KProperty<?> fn) {
@ -336,7 +332,7 @@ public abstract class KtAbstractLambdaWrapper<T, Children extends KtAbstractLamb
for (Children wrapper : onWrappers) {
if (StringUtils.isBlank(wrapper.from.getStringValue())) {
if (this.subLogicSql && this.logicDelType == LogicDelTypeEnum.ON) {
TableInfo tableInfo = TableHelper.get(wrapper.getJoinClass());
TableInfo tableInfo = TableHelper.getAssert(wrapper.getJoinClass());
if (ConfigProperties.tableInfoAdapter.mpjHasLogic(tableInfo)) {
wrapper.appendSqlSegments(APPLY, () -> LogicInfoUtils.getLogicInfoNoAnd(
wrapper.getIndex(), wrapper.getJoinClass(), wrapper.isHasAlias(), wrapper.getAlias()
@ -364,10 +360,6 @@ public abstract class KtAbstractLambdaWrapper<T, Children extends KtAbstractLamb
return from.getStringValue();
}
public String getAlias() {
return alias;
}
/**
* 内部调用, 不建议使用
*/
@ -375,8 +367,7 @@ public abstract class KtAbstractLambdaWrapper<T, Children extends KtAbstractLamb
public Children join(String keyWord, Class<?> clazz, String tableAlias, BiConsumer<KtAbstractLambdaWrapper<?, ?>, Children> consumer) {
Integer oldIndex = this.getIndex();
int newIndex = tableIndex;
TableInfo info = TableHelper.get(clazz);
Asserts.hasTable(info, clazz);
TableInfo info = TableHelper.getAssert(clazz);
Children instance = instance(newIndex, keyWord, clazz, info.getTableName());
instance.isNo = true;
instance.isMain = false;

View File

@ -11,15 +11,18 @@ import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape;
import com.github.yulichang.kt.interfaces.Compare;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.kt.interfaces.CompareIfExists;
import com.github.yulichang.kt.interfaces.Func;
import com.github.yulichang.kt.interfaces.OnCompare;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJSqlInjectionUtils;
import com.github.yulichang.toolkit.Ref;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.enums.PrefixEnum;
import com.github.yulichang.wrapper.interfaces.CompareStr;
import com.github.yulichang.wrapper.interfaces.CompareStrIfExists;
import com.github.yulichang.wrapper.interfaces.FuncStr;
import com.github.yulichang.wrapper.interfaces.Join;
import kotlin.reflect.KProperty;
@ -29,6 +32,8 @@ import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.function.Supplier;
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*;
import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY;
@ -40,10 +45,10 @@ import static java.util.stream.Collectors.joining;
*
* @author yulichang
*/
@SuppressWarnings("ALL")
@SuppressWarnings({"unused", "unchecked", "DuplicatedCode"})
public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T, Children>> extends Wrapper<T>
implements Compare<Children>, Nested<Children, Children>, Join<Children>, Func<Children>, OnCompare<Children>,
CompareStr<Children, String>, FuncStr<Children, String> {
implements CompareIfExists<Children>, Nested<Children, Children>, Join<Children>, Func<Children>, OnCompare<Children>,
CompareStrIfExists<Children, String>, FuncStr<Children, String> {
/**
* 占位符
@ -59,12 +64,13 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
*/
@Getter
protected AtomicInteger paramNameSeq;
@Getter
protected Map<String, Object> paramNameValuePairs;
/**
* 其他
*/
/* mybatis plus 3.4.3新增 这个时wrapper的别名 不是MPJ的别名 */
protected SharedString paramAlias;
protected SharedString paramAlias = new SharedString(null);
protected SharedString lastSql;
/**
* SQL注释
@ -118,6 +124,12 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
*/
protected boolean checkSqlInjection = false;
/**
* IfExists 策略
*/
@Getter
protected BiPredicate<Object, IfExistsSqlKeyWordEnum> ifExists = ConfigProperties.ifExists;
@Override
public T getEntity() {
return entity;
@ -146,6 +158,21 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
return typedThis;
}
/**
* 转为子类方便自定义继承扩展
*/
public <C extends Children> C toChildren(Ref<C> children) {
return (C) this;
}
/**
* 转为子类方便自定义继承扩展
* 需要子类自定义字段
*/
public <C extends Children> C toChildren(Supplier<C> s) {
return (C) this;
}
/**
* 开启检查 SQL 注入
*/
@ -154,6 +181,16 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
return typedThis;
}
public Children setIfExists(BiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
this.ifExists = IfExists;
return typedThis;
}
public Children setIfExists(Predicate<Object> IfExists) {
this.ifExists = (o, k) -> IfExists.test(o);
return typedThis;
}
@Override
public Children allEq(boolean condition, Map<KProperty<?>, ?> params, boolean null2IsNull) {
if (condition && CollectionUtils.isNotEmpty(params)) {
@ -171,64 +208,74 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
}
@Override
public Children eq(boolean condition, KProperty<?> column, Object val) {
return addCondition(condition, column, EQ, val);
public Children eq(boolean condition, String alias, KProperty<?> column, Object val) {
return addCondition(condition, alias, column, EQ, val);
}
@Override
public Children ne(boolean condition, KProperty<?> column, Object val) {
return addCondition(condition, column, NE, val);
public Children ne(boolean condition, String alias, KProperty<?> column, Object val) {
return addCondition(condition, alias, column, NE, val);
}
@Override
public Children gt(boolean condition, KProperty<?> column, Object val) {
return addCondition(condition, column, GT, val);
public Children gt(boolean condition, String alias, KProperty<?> column, Object val) {
return addCondition(condition, alias, column, GT, val);
}
@Override
public Children ge(boolean condition, KProperty<?> column, Object val) {
return addCondition(condition, column, GE, val);
public Children ge(boolean condition, String alias, KProperty<?> column, Object val) {
return addCondition(condition, alias, column, GE, val);
}
@Override
public Children lt(boolean condition, KProperty<?> column, Object val) {
return addCondition(condition, column, LT, val);
public Children lt(boolean condition, String alias, KProperty<?> column, Object val) {
return addCondition(condition, alias, column, LT, val);
}
@Override
public Children le(boolean condition, KProperty<?> column, Object val) {
return addCondition(condition, column, LE, val);
public Children le(boolean condition, String alias, KProperty<?> column, Object val) {
return addCondition(condition, alias, column, LE, val);
}
@Override
public Children like(boolean condition, KProperty<?> column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.DEFAULT);
public Children like(boolean condition, String alias, KProperty<?> column, Object val) {
return likeValue(condition, LIKE, alias, column, val, SqlLike.DEFAULT);
}
@Override
public Children notLike(boolean condition, KProperty<?> column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.DEFAULT);
public Children notLike(boolean condition, String alias, KProperty<?> column, Object val) {
return likeValue(condition, NOT_LIKE, alias, column, val, SqlLike.DEFAULT);
}
@Override
public Children likeLeft(boolean condition, KProperty<?> column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.LEFT);
public Children likeLeft(boolean condition, String alias, KProperty<?> column, Object val) {
return likeValue(condition, LIKE, alias, column, val, SqlLike.LEFT);
}
@Override
public Children likeRight(boolean condition, KProperty<?> column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.RIGHT);
public Children notLikeLeft(boolean condition, String alias, KProperty<?> column, Object val) {
return likeValue(condition, NOT_LIKE, alias, column, val, SqlLike.LEFT);
}
@Override
public Children between(boolean condition, KProperty<?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), BETWEEN,
public Children likeRight(boolean condition, String alias, KProperty<?> column, Object val) {
return likeValue(condition, LIKE, alias, column, val, SqlLike.RIGHT);
}
@Override
public Children notLikeRight(boolean condition, String alias, KProperty<?> column, Object val) {
return likeValue(condition, NOT_LIKE, alias, column, val, SqlLike.RIGHT);
}
@Override
public Children between(boolean condition, String alias, KProperty<?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), BETWEEN,
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
}
@Override
public Children notBetween(boolean condition, KProperty<?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_BETWEEN,
public Children notBetween(boolean condition, String alias, KProperty<?> column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), NOT_BETWEEN,
() -> formatParam(null, val1), AND, () -> formatParam(null, val2)));
}
@ -266,7 +313,7 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
@Override
public Children last(boolean condition, String lastSql) {
if (condition) {
this.lastSql.setStringValue(StringPool.SPACE + lastSql);
this.lastSql.setStringValue(this.lastSql.getStringValue() + StringPool.SPACE + lastSql);
}
return typedThis;
}
@ -282,11 +329,18 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
@Override
public Children first(boolean condition, String firstSql) {
if (condition) {
this.sqlFirst.setStringValue(firstSql);
this.sqlFirst.setStringValue(firstSql + StringPool.SPACE + this.sqlFirst.getStringValue());
}
return typedThis;
}
@Override
public Children around(boolean condition, String firstSql, String lastSql) {
this.first(condition, firstSql);
this.last(condition, lastSql);
return typedThis;
}
@Override
public Children exists(boolean condition, String existsSql, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(EXISTS,
@ -299,125 +353,119 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
}
@Override
public Children isNull(boolean condition, KProperty<?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IS_NULL));
public Children isNull(boolean condition, String alias, KProperty<?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), IS_NULL));
}
@Override
public Children isNotNull(boolean condition, KProperty<?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IS_NOT_NULL));
public Children isNotNull(boolean condition, String alias, KProperty<?> column) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), IS_NOT_NULL));
}
@Override
public Children in(boolean condition, KProperty<?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN, inExpression(coll)));
public Children in(boolean condition, String alias, KProperty<?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), IN, inExpression(coll)));
}
@Override
public Children in(boolean condition, KProperty<?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN, inExpression(values)));
public Children in(boolean condition, String alias, KProperty<?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), IN, inExpression(values)));
}
@Override
public Children notIn(boolean condition, KProperty<?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN, inExpression(coll)));
public Children notIn(boolean condition, String alias, KProperty<?> column, Collection<?> coll) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), NOT_IN, inExpression(coll)));
}
@Override
public Children notIn(boolean condition, KProperty<?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN, inExpression(values)));
public Children notIn(boolean condition, String alias, KProperty<?> column, Object... values) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), NOT_IN, inExpression(values)));
}
@Override
public Children inSql(boolean condition, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), IN,
public Children inSql(boolean condition, String alias, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), IN,
() -> String.format("(%s)", inValue)));
}
@Override
public Children notInSql(boolean condition, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), NOT_IN,
public Children notInSql(boolean condition, String alias, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), NOT_IN,
() -> String.format("(%s)", inValue)));
}
@Override
public Children gtSql(boolean condition, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), GT,
public Children gtSql(boolean condition, String alias, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), GT,
() -> String.format("(%s)", inValue)));
}
@Override
public Children geSql(boolean condition, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), GE,
public Children geSql(boolean condition, String alias, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), GE,
() -> String.format("(%s)", inValue)));
}
@Override
public Children ltSql(boolean condition, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), LT,
public Children ltSql(boolean condition, String alias, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), LT,
() -> String.format("(%s)", inValue)));
}
@Override
public Children leSql(boolean condition, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), LE,
public Children leSql(boolean condition, String alias, KProperty<?> column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), LE,
() -> String.format("(%s)", inValue)));
}
@Override
public Children groupBy(boolean condition, List<KProperty<?>> columns) {
public Children groupBy(boolean condition, String alias, List<KProperty<?>> columns) {
return maybeDo(condition, () -> {
if (CollectionUtils.isNotEmpty(columns)) {
String one = (StringPool.COMMA + columnsToString(index, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, columns));
final String finalOne = one;
final String finalOne = columnsToString(index, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, alias, columns);
appendSqlSegments(GROUP_BY, () -> finalOne);
}
});
}
@Override
public Children groupBy(boolean condition, KProperty<?> column, KProperty<?>... columns) {
public Children groupBy(boolean condition, String alias, KProperty<?>... columns) {
return maybeDo(condition, () -> {
String one = columnToString(index, column, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST);
if (ArrayUtils.isNotEmpty(columns)) {
one += (StringPool.COMMA + columnsToString(index, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, columns));
final String finalOne = columnsToString(index, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST, alias, columns);
appendSqlSegments(GROUP_BY, () -> finalOne);
}
final String finalOne = one;
appendSqlSegments(GROUP_BY, () -> finalOne);
});
}
@Override
public Children orderByAsc(boolean condition, List<KProperty<?>> columns) {
public Children orderByAsc(boolean condition, String alias, List<KProperty<?>> columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = ASC;
if (CollectionUtils.isNotEmpty(columns)) {
columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
columnToSqlSegment(index, alias, columnSqlInjectFilter(c)), ASC));
}
});
}
@Override
public Children orderByDesc(boolean condition, List<KProperty<?>> columns) {
public Children orderByDesc(boolean condition, String alias, List<KProperty<?>> columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = DESC;
if (CollectionUtils.isNotEmpty(columns)) {
columns.forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
columnToSqlSegment(index, alias, columnSqlInjectFilter(c)), DESC));
}
});
}
@Override
public Children orderBy(boolean condition, boolean isAsc, KProperty<?> column, KProperty<?>... columns) {
public Children orderBy(boolean condition, boolean isAsc, String alias, KProperty<?>... columns) {
return maybeDo(condition, () -> {
final SqlKeyword mode = isAsc ? ASC : DESC;
appendSqlSegments(ORDER_BY, columnToSqlSegment(index, column, false), mode);
if (ArrayUtils.isNotEmpty(columns)) {
Arrays.stream(columns).forEach(c -> appendSqlSegments(ORDER_BY,
columnToSqlSegment(index, columnSqlInjectFilter(c), false), mode));
columnToSqlSegment(index, alias, columnSqlInjectFilter(c)), mode));
}
});
}
@ -426,7 +474,7 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
* 字段 SQL 注入过滤处理子类重写实现过滤逻辑
*
* @param column 字段内容
* @return
* @return Children
*/
protected KProperty<?> columnSqlInjectFilter(KProperty<?> column) {
return column;
@ -463,8 +511,8 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
* 内部自用
* <p>拼接 LIKE 以及 </p>
*/
protected Children likeValue(boolean condition, SqlKeyword keyword, KProperty<?> column, Object val, SqlLike sqlLike) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), keyword,
protected Children likeValue(boolean condition, SqlKeyword keyword, String alias, KProperty<?> column, Object val, SqlLike sqlLike) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), keyword,
() -> formatParam(null, SqlUtils.concatLike(val, sqlLike))));
}
@ -481,18 +529,18 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
* @param sqlKeyword SQL 关键词
* @param val 条件值
*/
protected Children addCondition(boolean condition, KProperty<?> column, SqlKeyword sqlKeyword, Object val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), sqlKeyword,
protected Children addCondition(boolean condition, String alias, KProperty<?> column, SqlKeyword sqlKeyword, Object val) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), sqlKeyword,
() -> formatParam(null, val)));
}
protected <X, S> Children addCondition(boolean condition, KProperty<?> column, SqlKeyword sqlKeyword, KProperty<?> val) {
protected <X, S> Children addCondition(boolean condition, String alias, KProperty<?> column, SqlKeyword sqlKeyword, String rightAlias, KProperty<?> val) {
Class<X> c = (Class<X>) KtUtils.ref(column);
Class<S> v = (Class<S>) KtUtils.ref(val);
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, column, false), sqlKeyword,
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(index, alias, column), sqlKeyword,
isNo ?
columnToSqlSegmentS(index, val, v == c && v == joinClass) :
columnToSqlSegmentS(index, val, v == c)
columnToSqlSegmentS(index, rightAlias, val, v == c && v == joinClass) :
columnToSqlSegmentS(index, rightAlias, val, v == c)
));
}
@ -533,6 +581,7 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
* @param params 参数
* @return sql片段
*/
@SuppressWarnings("SameParameterValue")
protected final String formatSqlMaybeWithParam(String sqlStr, String mapping, Object... params) {
if (StringUtils.isBlank(sqlStr)) {
// todo 何时会这样?
@ -607,15 +656,17 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
paramNameSeq.set(0);
paramNameValuePairs.clear();
expression.clear();
lastSql.toEmpty();
sqlComment.toEmpty();
sqlFirst.toEmpty();
paramAlias.toNull();
if (Objects.nonNull(lastSql)) lastSql.toEmpty();
if (Objects.nonNull(sqlComment)) sqlComment.toEmpty();
if (Objects.nonNull(sqlFirst)) sqlFirst.toEmpty();
tableList.clear();
entityClass = null;
onWrappers.clear();
index = null;
isMain = true;
isNo = false;
ifExists = ConfigProperties.ifExists;
}
/**
@ -653,12 +704,8 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
return expression;
}
public Map<String, Object> getParamNameValuePairs() {
return paramNameValuePairs;
}
public String getParamAlias() {
return paramAlias == null ? Constants.WRAPPER : paramAlias.getStringValue();
return paramAlias.getStringValue() == null ? Constants.WRAPPER : paramAlias.getStringValue();
}
/**
@ -667,29 +714,28 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
* @param paramAlias 参数别名
* @return Children
*/
@SuppressWarnings("UnusedReturnValue")
public Children setParamAlias(String paramAlias) {
Assert.notEmpty(paramAlias, "paramAlias can not be empty!");
Assert.isTrue(CollectionUtils.isEmpty(paramNameValuePairs), "Please call this method before working!");
Assert.isNull(this.paramAlias, "Please do not call the method repeatedly!");
this.paramAlias = new SharedString(paramAlias);
this.paramAlias.setStringValue(paramAlias);
return typedThis;
}
/**
* 获取 columnName
*/
protected final ISqlSegment columnToSqlSegment(Integer index, KProperty<?> column, boolean isJoin) {
return () -> columnToString(index, column, isJoin, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST);
protected final ISqlSegment columnToSqlSegment(Integer index, String alias, KProperty<?> column) {
return () -> columnToString(index, alias, column, false, isNo ? PrefixEnum.ON_FIRST : PrefixEnum.CD_FIRST);
}
protected final ISqlSegment columnToSqlSegmentS(Integer index, KProperty<?> column, boolean isJoin) {
protected final ISqlSegment columnToSqlSegmentS(Integer index, String alias, KProperty<?> column, boolean isJoin) {
PrefixEnum prefixEnum;
if (isMain) {
prefixEnum = isNo ? PrefixEnum.ON_SECOND /* 理论上不可能有这种情况 */ : PrefixEnum.CD_SECOND;
} else {
prefixEnum = isNo ? PrefixEnum.ON_SECOND : PrefixEnum.CD_ON_SECOND;
}
return () -> columnToString(index, column, isJoin, prefixEnum);
return () -> columnToString(index, alias, column, isJoin, prefixEnum);
}
protected final ISqlSegment columnToSqlSegment(String column) {
@ -699,9 +745,7 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
/**
* 获取 columnName
*/
protected String columnToString(Integer index, Object column, boolean isJoin, PrefixEnum prefixEnum) {
return (String) column;
}
abstract String columnToString(Integer index, String alias, KProperty<?> column, boolean isJoin, PrefixEnum prefixEnum);
protected String columnToString(String column) {
if (checkSqlInjection && MPJSqlInjectionUtils.check(column)) {
@ -724,12 +768,16 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
*
* @param columns 多字段
*/
protected String columnsToString(Integer index, boolean isJoin, PrefixEnum prefixEnum, Object... columns) {
return Arrays.stream(columns).map(i -> this.columnToString(index, i, isJoin, prefixEnum)).collect(joining(StringPool.COMMA));
protected String columnsToString(Integer index, PrefixEnum prefixEnum, String alias, KProperty<?>... columns) {
return Arrays.stream(columns).map(i -> this.columnToString(index, alias, i, false, prefixEnum)).collect(joining(StringPool.COMMA));
}
protected String columnsToString(Integer index, PrefixEnum prefixEnum, String alias, List<KProperty<?>> columns) {
return columns.stream().map(i -> this.columnToString(index, alias, i, false, prefixEnum)).collect(joining(StringPool.COMMA));
}
@SuppressWarnings("MethodDoesntCallSuperMethod")
@Override
@SuppressWarnings("all")
public Children clone() {
return SerializationUtils.clone(typedThis);
}
@ -746,33 +794,33 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
/* ************************* on语句重载 *************************** */
@Override
public Children eq(boolean condition, KProperty<?> column, KProperty<?> val) {
return addCondition(condition, column, EQ, val);
public Children eq(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return addCondition(condition, alias, column, EQ, rightAlias, val);
}
@Override
public Children ne(boolean condition, KProperty<?> column, KProperty<?> val) {
return addCondition(condition, column, NE, val);
public Children ne(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return addCondition(condition, alias, column, NE, rightAlias, val);
}
@Override
public Children gt(boolean condition, KProperty<?> column, KProperty<?> val) {
return addCondition(condition, column, GT, val);
public Children gt(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return addCondition(condition, alias, column, GT, rightAlias, val);
}
@Override
public Children ge(boolean condition, KProperty<?> column, KProperty<?> val) {
return addCondition(condition, column, GE, val);
public Children ge(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return addCondition(condition, alias, column, GE, rightAlias, val);
}
@Override
public Children lt(boolean condition, KProperty<?> column, KProperty<?> val) {
return addCondition(condition, column, LT, val);
public Children lt(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return addCondition(condition, alias, column, LT, rightAlias, val);
}
@Override
public Children le(boolean condition, KProperty<?> column, KProperty<?> val) {
return addCondition(condition, column, LE, val);
public Children le(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return addCondition(condition, alias, column, LE, rightAlias, val);
}
/* ****************************************** **/
@ -857,11 +905,21 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
return likeValue(condition, LIKE, column, val, SqlLike.LEFT);
}
@Override
public Children notLikeLeft(boolean condition, String column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.LEFT);
}
@Override
public Children likeRight(boolean condition, String column, Object val) {
return likeValue(condition, LIKE, column, val, SqlLike.RIGHT);
}
@Override
public Children notLikeRight(boolean condition, String column, Object val) {
return likeValue(condition, NOT_LIKE, column, val, SqlLike.RIGHT);
}
@Override
public Children between(boolean condition, String column, Object val1, Object val2) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), BETWEEN,
@ -938,6 +996,12 @@ public abstract class KtAbstractWrapper<T, Children extends KtAbstractWrapper<T,
() -> String.format("(%s)", inValue)));
}
@Override
public Children eqSql(boolean condition, String column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), EQ,
() -> String.format("(%s)", inValue)));
}
@Override
public Children notInSql(boolean condition, String column, String inValue) {
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), NOT_IN,

View File

@ -5,10 +5,10 @@ import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.LogicInfoUtils;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.wrapper.interfaces.DeleteChain;
import java.util.ArrayList;
import java.util.Arrays;
@ -22,7 +22,7 @@ import java.util.stream.Collectors;
* @since 1.4.5
*/
@SuppressWarnings({"unused", "DuplicatedCode"})
public class KtDeleteJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtDeleteJoinWrapper<T>> {
public class KtDeleteJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtDeleteJoinWrapper<T>> implements DeleteChain<T> {
/**
* 删除表
@ -166,21 +166,19 @@ public class KtDeleteJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtDeleteJ
private void check(List<Class<?>> classList) {
Class<T> entityClass = getEntityClass();
TableInfo tableInfo = TableHelper.get(entityClass);
Asserts.hasTable(tableInfo, entityClass);
TableInfo tableInfo = TableHelper.getAssert(entityClass);
//检查
boolean mainLogic = AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo);
boolean mainLogic = AdapterHelper.getAdapter().mpjHasLogic(tableInfo);
boolean check = classList.stream().allMatch(t -> {
TableInfo ti = TableHelper.get(t);
Asserts.hasTable(ti, t);
return mainLogic == AdapterHelper.getTableInfoAdapter().mpjHasLogic(ti);
TableInfo ti = TableHelper.getAssert(t);
return mainLogic == AdapterHelper.getAdapter().mpjHasLogic(ti);
});
if (!check) {
throw ExceptionUtils.mpe("连表删除只适用于全部表(主表和副表)都是物理删除或全部都是逻辑删除, " +
"不支持同时存在物理删除和逻辑删除 [物理删除->(%s)] [逻辑删除->(%s)]",
classList.stream().filter(t -> !AdapterHelper.getTableInfoAdapter().mpjHasLogic(TableHelper.get(t)))
classList.stream().filter(t -> !AdapterHelper.getAdapter().mpjHasLogic(TableHelper.getAssert(t)))
.map(Class::getSimpleName).collect(Collectors.joining(StringPool.COMMA)),
classList.stream().filter(t -> AdapterHelper.getTableInfoAdapter().mpjHasLogic(TableHelper.get(t)))
classList.stream().filter(t -> AdapterHelper.getAdapter().mpjHasLogic(TableHelper.getAssert(t)))
.map(Class::getSimpleName).collect(Collectors.joining(StringPool.COMMA)));
}
}

View File

@ -7,12 +7,8 @@ import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.kt.interfaces.Query;
import com.github.yulichang.kt.interfaces.QueryLabel;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.KtWrapperUtils;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.support.ColumnCache;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.github.yulichang.wrapper.interfaces.Chain;
import com.github.yulichang.wrapper.interfaces.SelectWrapper;
import com.github.yulichang.wrapper.resultmap.Label;
@ -32,7 +28,7 @@ import java.util.stream.Collectors;
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings({"unused", "unchecked", "rawtypes"})
@SuppressWarnings({"unused", "unchecked", "rawtypes", "DuplicatedCode"})
public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapper<T>> implements
Query<KtLambdaWrapper<T>>, QueryLabel<KtLambdaWrapper<T>>, Chain<T>, SelectWrapper<T, KtLambdaWrapper<T>> {
@ -126,7 +122,7 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
* 不建议直接 new 该实例使用 JoinWrappers.lambda(UserDO.class)
*/
KtLambdaWrapper(T entity, Class<T> entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
TableList tableList, Integer index, String keyWord, Class<?> joinClass, String tableName) {
super.setEntity(entity);
@ -135,6 +131,7 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
this.sqlSelect = sqlSelect;
this.paramAlias = paramAlias;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
@ -205,11 +202,12 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
/**
* 子查询
*/
@SuppressWarnings("DuplicatedCode")
public KtLambdaWrapper<T> selectSub(Class<?> clazz, String st, Consumer<KtLambdaWrapper<?>> consumer, KProperty<?> alias) {
KtLambdaWrapper<?> wrapper = new KtLambdaWrapper(null, clazz, SharedString.emptyString(), paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
new TableList(), null, null, null, null) {
public KtLambdaWrapper<T> selectSub(Class<?> clazz, String st,
Consumer<KtLambdaWrapper<?>> consumer, KProperty<?> alias) {
KtLambdaWrapper<?> wrapper = new KtLambdaWrapper(null, clazz, SharedString.emptyString(), paramNameSeq,
paramNameValuePairs, new MergeSegments(), new SharedString(this.paramAlias.getStringValue()),
SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), new TableList(),
null, null, null, null) {
};
wrapper.tableList.setAlias(st);
wrapper.tableList.setRootClass(clazz);
@ -218,23 +216,29 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
wrapper.subTableAlias = st;
consumer.accept(wrapper);
addCustomWrapper(wrapper);
String sql = KtWrapperUtils.buildSubSqlByWrapper(clazz, wrapper, alias.getName());
this.selectColumns.add(new SelectString(sql, hasAlias, this.alias));
this.selectColumns.add(new SelectSub(() -> KtWrapperUtils.buildSubSqlByWrapper(
clazz, wrapper, alias.getName()), hasAlias, this.alias, alias.getName()));
return typedThis;
}
/**
* union
* <p>
* 推荐使用 union(Class&lt;U&gt; clazz, Consumer&lt;MPJLambdaWrapper&lt;U&gt;&gt; consumer)
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #union(Class, Consumer)
* @deprecated union 不支持子查询
*/
@SuppressWarnings("UnusedReturnValue")
@Deprecated
@SuppressWarnings("ALL")
public final KtLambdaWrapper<T> union(KtLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (KtLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ")
.append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
sb.append(" UNION ").append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
@ -244,17 +248,45 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
}
/**
* union all
* union
* <p>
* wrapper.union(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.8
*/
@SafeVarargs
public final <E, F> KtLambdaWrapper<T> unionAll(KtLambdaWrapper<T>... wrappers) {
public <U> KtLambdaWrapper<T> union(Class<U> clazz, Consumer<KtLambdaWrapper<U>> consumer) {
KtLambdaWrapper<U> unionWrapper = KtWrappers.query(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION " + KtWrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
/**
* union
* <p>
* 推荐使用 unionAll(Class&lt;U&gt; clazz, Consumer&lt;MPJLambdaWrapper&lt;U&gt;&gt; consumer)
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @see #unionAll(Class, Consumer)
* @deprecated union 不支持子查询
*/
@Deprecated
@SuppressWarnings("ALL")
public final KtLambdaWrapper<T> unionAll(KtLambdaWrapper<?>... wrappers) {
StringBuilder sb = new StringBuilder();
for (KtLambdaWrapper<?> wrapper : wrappers) {
addCustomWrapper(wrapper);
Class<?> entityClass = wrapper.getEntityClass();
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
sb.append(" UNION ALL ")
.append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
sb.append(" UNION ALL ").append(KtWrapperUtils.buildUnionSqlByWrapper(entityClass, wrapper));
}
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
@ -263,7 +295,28 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
return typedThis;
}
@SuppressWarnings("DuplicatedCode")
/**
* union
* <p>
* wrapper.unionAll(UserDO.class, union -> union.selectAll(UserDO.class))
*
* @param clazz union语句的主表类型
* @since 1.4.8
*/
public <U> KtLambdaWrapper<T> unionAll(Class<U> clazz, Consumer<KtLambdaWrapper<U>> consumer) {
KtLambdaWrapper<U> unionWrapper = KtWrappers.query(clazz);
addCustomWrapper(unionWrapper);
consumer.accept(unionWrapper);
String sb = " UNION ALL " + KtWrapperUtils.buildUnionSqlByWrapper(clazz, unionWrapper);
if (Objects.isNull(unionSql)) {
unionSql = SharedString.emptyString();
}
unionSql.setStringValue(unionSql.getStringValue() + sb);
return typedThis;
}
private void addCustomWrapper(KtLambdaWrapper<?> wrapper) {
if (Objects.isNull(wrapperIndex)) {
wrapperIndex = new AtomicInteger(0);
@ -281,7 +334,6 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
* 查询条件 SQL 片段
*/
@Override
@SuppressWarnings("DuplicatedCode")
public String getSqlSelect() {
if (StringUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumns)) {
String s = selectColumns.stream().map(i -> {
@ -350,7 +402,7 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
@Override
protected KtLambdaWrapper<T> instance(Integer index, String keyWord, Class<?> joinClass, String tableName) {
return new KtLambdaWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
new MergeSegments(), this.paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
this.tableList, index, keyWord, joinClass, tableName);
}
@ -358,7 +410,8 @@ public class KtLambdaWrapper<T> extends KtAbstractLambdaWrapper<T, KtLambdaWrapp
public void clear() {
super.clear();
selectDistinct = false;
sqlSelect.toNull();
sqlSelect.toEmpty();
if (Objects.nonNull(unionSql)) unionSql.toEmpty();
selectColumns.clear();
wrapperIndex = new AtomicInteger(0);
wrapperMap.clear();

View File

@ -7,10 +7,11 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.kt.interfaces.Update;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.wrapper.interfaces.UpdateChain;
import kotlin.reflect.KProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -29,7 +30,7 @@ import java.util.stream.Collectors;
*/
@SuppressWarnings({"unused", "DuplicatedCode"})
public class KtUpdateJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtUpdateJoinWrapper<T>>
implements Update<KtUpdateJoinWrapper<T>> {
implements Update<KtUpdateJoinWrapper<T>>, UpdateChain<T> {
/**
* SQL 更新字段内容例如name='1', age=2
*/
@ -114,7 +115,27 @@ public class KtUpdateJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtUpdateJ
if (Objects.isNull(updateSet)) {
updateSet = new ArrayList<>();
}
updateSet.add(new UpdateSet(column, val, mapping));
updateSet.add(new UpdateSet(column, val, mapping, false, null));
});
}
@Override
public KtUpdateJoinWrapper<T> setIncrBy(boolean condition, KProperty<?> column, Number val) {
return maybeDo(condition, () -> {
if (Objects.isNull(updateSet)) {
updateSet = new ArrayList<>();
}
updateSet.add(new UpdateSet(column, val, null, true, Constant.PLUS));
});
}
@Override
public KtUpdateJoinWrapper<T> setDecrBy(boolean condition, KProperty<?> column, Number val) {
return maybeDo(condition, () -> {
if (Objects.isNull(updateSet)) {
updateSet = new ArrayList<>();
}
updateSet.add(new UpdateSet(column, val, null, true, Constant.DASH));
});
}
@ -136,8 +157,15 @@ public class KtUpdateJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtUpdateJ
}
StringBuilder set = new StringBuilder(StringPool.EMPTY);
if (CollectionUtils.isNotEmpty(updateSet)) {
set = new StringBuilder(updateSet.stream().map(i -> tableList.getPrefixByClass(KtUtils.ref(i.getColumn())) +
Constants.DOT + getCache(i.getColumn()).getColumn() + Constants.EQUALS + formatParam(i.mapping, i.value))
set = new StringBuilder(updateSet.stream().map(i -> {
String col = tableList.getPrefixByClass(KtUtils.ref(i.getColumn())) +
Constants.DOT + getCache(i.getColumn()).getColumn();
if (i.incOrDnc) {
return col + Constants.EQUALS + col + i.cal + i.value;
} else {
return col + Constants.EQUALS + formatParam(i.mapping, i.value);
}
})
.collect(Collectors.joining(StringPool.COMMA)) + StringPool.COMMA);
}
if (CollectionUtils.isNotEmpty(sqlSet)) {
@ -199,15 +227,14 @@ public class KtUpdateJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtUpdateJ
private void getSqlByEntity(StringBuilder sb, boolean filterNull, List<Object> entityList) {
for (Object obj : entityList) {
Assert.isTrue(tableList.contain(obj.getClass()), "更新的实体不是主表或关联表 <%>", obj.getClass().getSimpleName());
TableInfo tableInfo = TableHelper.get(obj.getClass());
Asserts.hasTable(tableInfo, obj.getClass());
TableInfo tableInfo = TableHelper.getAssert(obj.getClass());
for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
continue;
}
Object val;
try {
Field field = AdapterHelper.getTableInfoAdapter().mpjGetField(fieldInfo, () -> {
Field field = AdapterHelper.getAdapter().mpjGetField(fieldInfo, () -> {
Field field1 = ReflectionKit.getFieldMap(obj.getClass()).get(fieldInfo.getProperty());
field1.setAccessible(true);
return field1;
@ -254,5 +281,9 @@ public class KtUpdateJoinWrapper<T> extends KtAbstractLambdaWrapper<T, KtUpdateJ
private Object value;
private String mapping;
private boolean incOrDnc;
private String cal;
}
}

View File

@ -13,17 +13,13 @@ import java.util.Map;
@SuppressWarnings("unused")
public interface Compare<Children> extends Serializable {
/**
* ignore
*/
default Children allEq(Map<KProperty<?>,?> params) {
default Children allEq(Map<KProperty<?>, ?> params) {
return allEq(params, true);
}
/**
* ignore
*/
default Children allEq(Map<KProperty<?>, ?> params, boolean null2IsNull) {
default Children allEq(Map<KProperty<?>, ?> params, boolean null2IsNull) {
return allEq(true, params, null2IsNull);
}
@ -35,15 +31,19 @@ public interface Compare<Children> extends Serializable {
* @param null2IsNull 是否参数为 null 自动执行 isNull 方法, false 则忽略这个字段\
* @return children
*/
Children allEq(boolean condition, Map<KProperty<?>, ?> params, boolean null2IsNull);
Children allEq(boolean condition, Map<KProperty<?>, ?> params, boolean null2IsNull);
/**
* ignore
*/
@SuppressWarnings("UnusedReturnValue")
default Children eq(KProperty<?> column, Object val) {
return eq(true, column, val);
default Children eq(KProperty<?> column, Object val) {
return eq(true, null, column, val);
}
default Children eq(String alias, KProperty<?> column, Object val) {
return eq(true, alias, column, val);
}
default Children eq(boolean condition, KProperty<?> column, Object val) {
return eq(condition, null, column, val);
}
/**
@ -54,13 +54,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children eq(boolean condition, KProperty<?> column, Object val);
Children eq(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children ne(KProperty<?> column, Object val) {
return ne(true, column, val);
default Children ne(KProperty<?> column, Object val) {
return ne(true, null, column, val);
}
default Children ne(String alias, KProperty<?> column, Object val) {
return ne(true, alias, column, val);
}
default Children ne(boolean condition, KProperty<?> column, Object val) {
return ne(condition, null, column, val);
}
/**
@ -71,13 +77,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children ne(boolean condition, KProperty<?> column, Object val);
Children ne(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children gt(KProperty<?> column, Object val) {
return gt(true, column, val);
default Children gt(KProperty<?> column, Object val) {
return gt(true, null, column, val);
}
default Children gt(String alias, KProperty<?> column, Object val) {
return gt(true, alias, column, val);
}
default Children gt(boolean condition, KProperty<?> column, Object val) {
return gt(condition, null, column, val);
}
/**
@ -88,13 +100,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children gt(boolean condition, KProperty<?> column, Object val);
Children gt(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children ge(KProperty<?> column, Object val) {
return ge(true, column, val);
default Children ge(KProperty<?> column, Object val) {
return ge(true, null, column, val);
}
default Children ge(String alias, KProperty<?> column, Object val) {
return ge(true, alias, column, val);
}
default Children ge(boolean condition, KProperty<?> column, Object val) {
return ge(condition, null, column, val);
}
/**
@ -105,13 +123,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children ge(boolean condition, KProperty<?> column, Object val);
Children ge(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children lt(KProperty<?> column, Object val) {
return lt(true, column, val);
default Children lt(KProperty<?> column, Object val) {
return lt(true, null, column, val);
}
default Children lt(String alias, KProperty<?> column, Object val) {
return lt(true, alias, column, val);
}
default Children lt(boolean condition, KProperty<?> column, Object val) {
return lt(condition, null, column, val);
}
/**
@ -122,13 +146,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children lt(boolean condition, KProperty<?> column, Object val);
Children lt(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children le(KProperty<?> column, Object val) {
return le(true, column, val);
return le(true, null, column, val);
}
default Children le(String alias, KProperty<?> column, Object val) {
return le(true, alias, column, val);
}
default Children le(boolean condition, KProperty<?> column, Object val) {
return le(condition, null, column, val);
}
/**
@ -139,13 +169,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children le(boolean condition, KProperty<?> column, Object val);
Children le(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children between(KProperty<?> column, Object val1, Object val2) {
return between(true, column, val1, val2);
default Children between(KProperty<?> column, Object val1, Object val2) {
return between(true, null, column, val1, val2);
}
default Children between(String alias, KProperty<?> column, Object val1, Object val2) {
return between(true, alias, column, val1, val2);
}
default Children between(boolean condition, KProperty<?> column, Object val1, Object val2) {
return between(condition, null, column, val1, val2);
}
/**
@ -157,13 +193,18 @@ public interface Compare<Children> extends Serializable {
* @param val2 值2
* @return children
*/
Children between(boolean condition, KProperty<?> column, Object val1, Object val2);
Children between(boolean condition, String alias, KProperty<?> column, Object val1, Object val2);
/**
* ignore
*/
default Children notBetween(KProperty<?> column, Object val1, Object val2) {
return notBetween(true, column, val1, val2);
default Children notBetween(KProperty<?> column, Object val1, Object val2) {
return notBetween(true, null, column, val1, val2);
}
default Children notBetween(String alias, KProperty<?> column, Object val1, Object val2) {
return notBetween(true, alias, column, val1, val2);
}
default Children notBetween(boolean condition, KProperty<?> column, Object val1, Object val2) {
return notBetween(condition, null, column, val1, val2);
}
/**
@ -175,13 +216,19 @@ public interface Compare<Children> extends Serializable {
* @param val2 值2
* @return children
*/
Children notBetween(boolean condition, KProperty<?> column, Object val1, Object val2);
Children notBetween(boolean condition, String alias, KProperty<?> column, Object val1, Object val2);
/**
* ignore
*/
default Children like(KProperty<?> column, Object val) {
return like(true, column, val);
default Children like(KProperty<?> column, Object val) {
return like(true, null, column, val);
}
default Children like(String alisa, KProperty<?> column, Object val) {
return like(true, alisa, column, val);
}
default Children like(boolean condition, KProperty<?> column, Object val) {
return like(condition, null, column, val);
}
/**
@ -192,13 +239,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children like(boolean condition, KProperty<?> column, Object val);
Children like(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children notLike(KProperty<?> column, Object val) {
return notLike(true, column, val);
default Children notLike(KProperty<?> column, Object val) {
return notLike(true, null, column, val);
}
default Children notLike(String alias, KProperty<?> column, Object val) {
return notLike(true, alias, column, val);
}
default Children notLike(boolean condition, KProperty<?> column, Object val) {
return notLike(condition, null, column, val);
}
/**
@ -209,13 +262,19 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children notLike(boolean condition, KProperty<?> column, Object val);
Children notLike(boolean condition, String alias, KProperty<?> column, Object val);
/**
* ignore
*/
default Children likeLeft(KProperty<?> column, Object val) {
return likeLeft(true, column, val);
default Children likeLeft(KProperty<?> column, Object val) {
return likeLeft(true, null, column, val);
}
default Children likeLeft(String alias, KProperty<?> column, Object val) {
return likeLeft(true, alias, column, val);
}
default Children likeLeft(boolean condition, KProperty<?> column, Object val) {
return likeLeft(condition, null, column, val);
}
/**
@ -226,15 +285,44 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children likeLeft(boolean condition, KProperty<?> column, Object val);
Children likeLeft(boolean condition, String alias, KProperty<?> column, Object val);
default Children notLikeLeft(KProperty<?> column, Object val) {
return notLikeLeft(true, null, column, val);
}
default Children notLikeLeft(String alias, KProperty<?> column, Object val) {
return notLikeLeft(true, alias, column, val);
}
default Children notLikeLeft(boolean condition, KProperty<?> column, Object val) {
return notLikeLeft(condition, null, column, val);
}
/**
* ignore
* LIKE '%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
default Children likeRight(KProperty<?> column, Object val) {
return likeRight(true, column, val);
Children notLikeLeft(boolean condition, String alias, KProperty<?> column, Object val);
default Children likeRight(KProperty<?> column, Object val) {
return likeRight(true, null, column, val);
}
default Children likeRight(String alias, KProperty<?> column, Object val) {
return likeRight(true, alias, column, val);
}
default Children likeRight(boolean condition, KProperty<?> column, Object val) {
return likeRight(condition, null, column, val);
}
/**
* LIKE '%'
*
@ -243,5 +331,30 @@ public interface Compare<Children> extends Serializable {
* @param val
* @return children
*/
Children likeRight(boolean condition, KProperty<?> column, Object val);
Children likeRight(boolean condition, String alias, KProperty<?> column, Object val);
default Children notLikeRight(KProperty<?> column, Object val) {
return notLikeRight(true, null, column, val);
}
default Children notLikeRight(String alias, KProperty<?> column, Object val) {
return notLikeRight(true, alias, column, val);
}
default Children notLikeRight(boolean condition, KProperty<?> column, Object val) {
return notLikeRight(condition, null, column, val);
}
/**
* LIKE '%'
*
* @param condition 执行条件
* @param column 字段
* @param val
* @return children
*/
Children notLikeRight(boolean condition, String alias, KProperty<?> column, Object val);
}

View File

@ -0,0 +1,115 @@
package com.github.yulichang.kt.interfaces;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import kotlin.reflect.KProperty;
import java.util.function.BiPredicate;
/**
* IfExists
*
* @author yulichang
* @since 1.4.9
*/
@SuppressWarnings("unused")
public interface CompareIfExists<Children> extends Compare<Children> {
BiPredicate<Object, IfExistsSqlKeyWordEnum> getIfExists();
default Children eqIfExists(KProperty<?> column, Object val) {
return eq(getIfExists().test(val, IfExistsSqlKeyWordEnum.EQ), null, column, val);
}
default Children eqIfExists(String alias, KProperty<?> column, Object val) {
return eq(getIfExists().test(val, IfExistsSqlKeyWordEnum.EQ), alias, column, val);
}
default Children neIfExists(KProperty<?> column, Object val) {
return ne(getIfExists().test(val, IfExistsSqlKeyWordEnum.NE), null, column, val);
}
default Children neIfExists(String alias, KProperty<?> column, Object val) {
return ne(getIfExists().test(val, IfExistsSqlKeyWordEnum.NE), alias, column, val);
}
default Children gtIfExists(KProperty<?> column, Object val) {
return gt(getIfExists().test(val, IfExistsSqlKeyWordEnum.GT), null, column, val);
}
default Children gtIfExists(String alias, KProperty<?> column, Object val) {
return gt(getIfExists().test(val, IfExistsSqlKeyWordEnum.GT), alias, column, val);
}
default Children geIfExists(KProperty<?> column, Object val) {
return ge(getIfExists().test(val, IfExistsSqlKeyWordEnum.GE), null, column, val);
}
default Children geIfExists(String alias, KProperty<?> column, Object val) {
return ge(getIfExists().test(val, IfExistsSqlKeyWordEnum.GE), alias, column, val);
}
default Children ltIfExists(KProperty<?> column, Object val) {
return lt(getIfExists().test(val, IfExistsSqlKeyWordEnum.LT), null, column, val);
}
default Children ltIfExists(String alias, KProperty<?> column, Object val) {
return lt(getIfExists().test(val, IfExistsSqlKeyWordEnum.LT), alias, column, val);
}
default Children leIfExists(KProperty<?> column, Object val) {
return le(getIfExists().test(val, IfExistsSqlKeyWordEnum.LE), null, column, val);
}
default Children leIfExists(String alias, KProperty<?> column, Object val) {
return le(getIfExists().test(val, IfExistsSqlKeyWordEnum.LE), alias, column, val);
}
default Children likeIfExists(KProperty<?> column, Object val) {
return like(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE), null, column, val);
}
default Children likeIfExists(String alisa, KProperty<?> column, Object val) {
return like(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE), alisa, column, val);
}
default Children notLikeIfExists(KProperty<?> column, Object val) {
return notLike(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE), null, column, val);
}
default Children notLikeIfExists(String alias, KProperty<?> column, Object val) {
return notLike(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE), alias, column, val);
}
default Children likeLeftIfExists(KProperty<?> column, Object val) {
return likeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_LEFT), null, column, val);
}
default Children likeLeftIfExists(String alias, KProperty<?> column, Object val) {
return likeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_LEFT), alias, column, val);
}
default Children notLikeLeftIfExists(KProperty<?> column, Object val) {
return notLikeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_LEFT), null, column, val);
}
default Children notLikeLeftIfExists(String alias, KProperty<?> column, Object val) {
return notLikeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_LEFT), alias, column, val);
}
default Children likeRightIfExists(KProperty<?> column, Object val) {
return likeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_RIGHT), null, column, val);
}
default Children likeRightIfExists(String alias, KProperty<?> column, Object val) {
return likeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_RIGHT), alias, column, val);
}
default Children notLikeRightIfExists(KProperty<?> column, Object val) {
return notLikeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_RIGHT), null, column, val);
}
default Children notLikeRightIfExists(String alias, KProperty<?> column, Object val) {
return notLikeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_RIGHT), alias, column, val);
}
}

View File

@ -12,15 +12,20 @@ import java.util.function.Consumer;
* <p>
* copy {@link com.baomidou.mybatisplus.core.conditions.interfaces.Func}
*/
@SuppressWarnings({"unused", "JavadocDeclaration"})
@SuppressWarnings("unused")
public interface Func<Children> extends Serializable {
/**
* ignore
*/
@SuppressWarnings("UnusedReturnValue")
default Children isNull(KProperty<?> column) {
return isNull(true, column);
return isNull(true, null, column);
}
default Children isNull(String alias, KProperty<?> column) {
return isNull(true, alias, column);
}
default Children isNull(boolean condition, KProperty<?> column) {
return isNull(condition, null, column);
}
/**
@ -31,13 +36,19 @@ public interface Func<Children> extends Serializable {
* @param column 字段
* @return children
*/
Children isNull(boolean condition, KProperty<?> column);
Children isNull(boolean condition, String alias, KProperty<?> column);
/**
* ignore
*/
default Children isNotNull(KProperty<?> column) {
return isNotNull(true, column);
return isNotNull(true, null, column);
}
default Children isNotNull(String alias, KProperty<?> column) {
return isNotNull(true, alias, column);
}
default Children isNotNull(boolean condition, KProperty<?> column) {
return isNotNull(condition, null, column);
}
/**
@ -48,13 +59,19 @@ public interface Func<Children> extends Serializable {
* @param column 字段
* @return children
*/
Children isNotNull(boolean condition, KProperty<?> column);
Children isNotNull(boolean condition, String alias, KProperty<?> column);
/**
* ignore
*/
default Children in(KProperty<?> column, Collection<?> coll) {
return in(true, column, coll);
return in(true, null, column, coll);
}
default Children in(String alias, KProperty<?> column, Collection<?> coll) {
return in(true, alias, column, coll);
}
default Children in(boolean condition, KProperty<?> column, Collection<?> coll) {
return in(condition, null, column, coll);
}
/**
@ -69,13 +86,19 @@ public interface Func<Children> extends Serializable {
* @param coll 数据集合
* @return children
*/
Children in(boolean condition, KProperty<?> column, Collection<?> coll);
Children in(boolean condition, String alias, KProperty<?> column, Collection<?> coll);
/**
* ignore
*/
default Children in(KProperty<?> column, Object... values) {
return in(true, column, values);
return in(true, null, column, values);
}
default Children in(String alias, KProperty<?> column, Object... values) {
return in(true, alias, column, values);
}
default Children in(boolean condition, KProperty<?> column, Object... values) {
return in(condition, null, column, values);
}
/**
@ -90,13 +113,19 @@ public interface Func<Children> extends Serializable {
* @param values 数据数组
* @return children
*/
Children in(boolean condition, KProperty<?> column, Object... values);
Children in(boolean condition, String alias, KProperty<?> column, Object... values);
/**
* ignore
*/
default Children notIn(KProperty<?> column, Collection<?> coll) {
return notIn(true, column, coll);
return notIn(true, null, column, coll);
}
default Children notIn(String alias, KProperty<?> column, Collection<?> coll) {
return notIn(true, alias, column, coll);
}
default Children notIn(boolean condition, KProperty<?> column, Collection<?> coll) {
return notIn(condition, null, column, coll);
}
/**
@ -108,13 +137,19 @@ public interface Func<Children> extends Serializable {
* @param coll 数据集合
* @return children
*/
Children notIn(boolean condition, KProperty<?> column, Collection<?> coll);
Children notIn(boolean condition, String alias, KProperty<?> column, Collection<?> coll);
/**
* ignore
*/
default Children notIn(KProperty<?> column, Object... value) {
return notIn(true, column, value);
return notIn(true, null, column, value);
}
default Children notIn(String alias, KProperty<?> column, Object... value) {
return notIn(true, alias, column, value);
}
default Children notIn(boolean condition, KProperty<?> column, Object... values) {
return notIn(condition, null, column, values);
}
/**
@ -126,13 +161,19 @@ public interface Func<Children> extends Serializable {
* @param values 数据数组
* @return children
*/
Children notIn(boolean condition, KProperty<?> column, Object... values);
Children notIn(boolean condition, String alias, KProperty<?> column, Object... values);
/**
* ignore
*/
default Children inSql(KProperty<?> column, String inValue) {
return inSql(true, column, inValue);
return inSql(true, null, column, inValue);
}
default Children inSql(String alias, KProperty<?> column, String inValue) {
return inSql(true, alias, column, inValue);
}
default Children inSql(boolean condition, KProperty<?> column, String inValue) {
return inSql(condition, null, column, inValue);
}
/**
@ -146,13 +187,19 @@ public interface Func<Children> extends Serializable {
* @param inValue sql语句
* @return children
*/
Children inSql(boolean condition, KProperty<?> column, String inValue);
Children inSql(boolean condition, String alias, KProperty<?> column, String inValue);
/**
* ignore
*/
default Children notInSql(KProperty<?> column, String inValue) {
return notInSql(true, column, inValue);
return notInSql(true, null, column, inValue);
}
default Children notInSql(String alias, KProperty<?> column, String inValue) {
return notInSql(true, alias, column, inValue);
}
default Children notInSql(boolean condition, KProperty<?> column, String inValue) {
return notInSql(condition, null, column, inValue);
}
/**
@ -166,26 +213,42 @@ public interface Func<Children> extends Serializable {
* @param inValue sql语句 ---&gt; 1,2,3,4,5,6 或者 select id from table where id &lt; 3
* @return children
*/
Children notInSql(boolean condition, KProperty<?> column, String inValue);
Children notInSql(boolean condition, String alias, KProperty<?> column, String inValue);
default Children gtSql(KProperty<?> column, String inValue) {
return gtSql(true, null, column, inValue);
}
default Children gtSql(String alias, KProperty<?> column, String inValue) {
return gtSql(true, alias, column, inValue);
}
default Children gtSql(boolean condition, KProperty<?> column, String inValue) {
return gtSql(condition, null, column, inValue);
}
/**
* 字段 &gt; ( sql语句 )
* <p>例1: gtSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: gtSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition
* @param column
* @param inValue
* @return
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children gtSql(boolean condition, KProperty<?> column, String inValue);
Children gtSql(boolean condition, String alias, KProperty<?> column, String inValue);
/**
* ignore
*/
default Children gtSql(KProperty<?> column, String inValue) {
return gtSql(true, column, inValue);
default Children geSql(KProperty<?> column, String inValue) {
return geSql(true, null, column, inValue);
}
default Children geSql(String alias, KProperty<?> column, String inValue) {
return geSql(true, alias, column, inValue);
}
default Children geSql(boolean condition, KProperty<?> column, String inValue) {
return geSql(condition, null, column, inValue);
}
/**
@ -193,18 +256,24 @@ public interface Func<Children> extends Serializable {
* <p>例1: geSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: geSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition
* @param column
* @param inValue
* @return
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children geSql(boolean condition, KProperty<?> column, String inValue);
Children geSql(boolean condition, String alias, KProperty<?> column, String inValue);
/**
* ignore
*/
default Children geSql(KProperty<?> column, String inValue) {
return geSql(true, column, inValue);
default Children ltSql(KProperty<?> column, String inValue) {
return ltSql(true, null, column, inValue);
}
default Children ltSql(String alias, KProperty<?> column, String inValue) {
return ltSql(true, alias, column, inValue);
}
default Children ltSql(boolean condition, KProperty<?> column, String inValue) {
return ltSql(condition, null, column, inValue);
}
/**
@ -212,18 +281,23 @@ public interface Func<Children> extends Serializable {
* <p>例1: ltSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: ltSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition
* @param column
* @param inValue
* @return
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children ltSql(boolean condition, KProperty<?> column, String inValue);
Children ltSql(boolean condition, String alias, KProperty<?> column, String inValue);
/**
* ignore
*/
default Children ltSql(KProperty<?> column, String inValue) {
return ltSql(true, column, inValue);
default Children leSql(KProperty<?> column, String inValue) {
return leSql(true, null, column, inValue);
}
default Children leSql(String alias, KProperty<?> column, String inValue) {
return leSql(true, alias, column, inValue);
}
default Children leSql(boolean condition, KProperty<?> column, String inValue) {
return leSql(condition, null, column, inValue);
}
/**
@ -231,44 +305,40 @@ public interface Func<Children> extends Serializable {
* <p>例1: leSql("id", "1, 2, 3, 4, 5, 6")</p>
* <p>例1: leSql("id", "select id from table where name = 'JunJun'")</p>
*
* @param condition
* @param column
* @param inValue
* @return
* @param condition 执行条件
* @param column 字段
* @param inValue sql语句
* @return children
*/
Children leSql(boolean condition, KProperty<?> column, String inValue);
Children leSql(boolean condition, String alias, KProperty<?> column, String inValue);
/**
* ignore
*/
default Children leSql(KProperty<?> column, String inValue) {
return leSql(true, column, inValue);
}
/**
* ignore
*/
default Children groupBy(KProperty<?> column) {
return groupBy(true, column);
}
/**
* ignore
*/
default Children groupBy(List<KProperty<?>> column) {
return groupBy(true, column);
return groupBy(true, null, column);
}
/**
* ignore
*/
Children groupBy(boolean condition, List<KProperty<?>> columns);
default Children groupBy(String alias, List<KProperty<?>> column) {
return groupBy(true, alias, column);
}
/**
* ignore
*/
default Children groupBy(KProperty<?> column, KProperty<?>... columns) {
return groupBy(true, column, columns);
default Children groupBy(boolean condition, List<KProperty<?>> columns) {
return groupBy(condition, null, columns);
}
Children groupBy(boolean condition, String alias, List<KProperty<?>> columns);
default Children groupBy(KProperty<?>... columns) {
return groupBy(true, null, columns);
}
default Children groupBy(String alias, KProperty<?>... columns) {
return groupBy(true, alias, columns);
}
default Children groupBy(boolean condition, KProperty<?>... columns) {
return groupBy(condition, null, columns);
}
/**
@ -276,36 +346,42 @@ public interface Func<Children> extends Serializable {
* <p>: groupBy("id", "name")</p>
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段数组
* @return children
*/
Children groupBy(boolean condition, KProperty<?> column, KProperty<?>... columns);
Children groupBy(boolean condition, String alias, KProperty<?>... columns);
/**
* ignore
*/
default Children orderByAsc(KProperty<?> column) {
return orderByAsc(true, column);
return orderByAsc(true, (String) null, column);
}
/**
* ignore
*/
default Children orderByAsc(String alias, KProperty<?> column) {
return orderByAsc(true, alias, column);
}
default Children orderByAsc(List<KProperty<?>> columns) {
return orderByAsc(true, columns);
return orderByAsc(true, null, columns);
}
/**
* ignore
*/
Children orderByAsc(boolean condition, List<KProperty<?>> columns);
default Children orderByAsc(String alias, List<KProperty<?>> columns) {
return orderByAsc(true, alias, columns);
}
/**
* ignore
*/
default Children orderByAsc(KProperty<?> column, KProperty<?>... columns) {
return orderByAsc(true, column, columns);
default Children orderByAsc(boolean condition, List<KProperty<?>> columns) {
return orderByAsc(condition, null, columns);
}
Children orderByAsc(boolean condition, String alias, List<KProperty<?>> columns);
default Children orderByAsc(KProperty<?>... columns) {
return orderByAsc(true, null, columns);
}
default Children orderByAsc(String alias, KProperty<?>... columns) {
return orderByAsc(true, alias, columns);
}
/**
@ -313,38 +389,38 @@ public interface Func<Children> extends Serializable {
* <p>: orderByAsc("id", "name")</p>
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段数组
* @return children
*/
default Children orderByAsc(boolean condition, KProperty<?> column, KProperty<?>... columns) {
return orderBy(condition, true, column, columns);
default Children orderByAsc(boolean condition, KProperty<?>... columns) {
return orderBy(condition, true, null, columns);
}
/**
* ignore
*/
default Children orderByDesc(KProperty<?> column) {
return orderByDesc(true, column);
default Children orderByAsc(boolean condition, String alias, KProperty<?>... columns) {
return orderBy(condition, true, alias, columns);
}
/**
* ignore
*/
default Children orderByDesc(List<KProperty<?>> columns) {
return orderByDesc(true, columns);
return orderByDesc(true, null, columns);
}
/**
* ignore
*/
Children orderByDesc(boolean condition, List<KProperty<?>> columns);
default Children orderByDesc(String alias, List<KProperty<?>> columns) {
return orderByDesc(true, alias, columns);
}
/**
* ignore
*/
default Children orderByDesc(KProperty<?> column, KProperty<?>... columns) {
return orderByDesc(true, column, columns);
default Children orderByDesc(boolean condition, List<KProperty<?>> columns) {
return orderByDesc(condition, null, columns);
}
Children orderByDesc(boolean condition, String alias, List<KProperty<?>> columns);
default Children orderByDesc(KProperty<?>... columns) {
return orderByDesc(true, null, columns);
}
default Children orderByDesc(String alias, KProperty<?>... columns) {
return orderByDesc(true, alias, columns);
}
/**
@ -352,12 +428,19 @@ public interface Func<Children> extends Serializable {
* <p>: orderByDesc("id", "name")</p>
*
* @param condition 执行条件
* @param column 单个字段
* @param columns 字段数组
* @return children
*/
default Children orderByDesc(boolean condition, KProperty<?> column, KProperty<?>... columns) {
return orderBy(condition, false, column, columns);
default Children orderByDesc(boolean condition, KProperty<?>... columns) {
return orderBy(condition, false, null, columns);
}
default Children orderByDesc(boolean condition, String alias, KProperty<?>... columns) {
return orderBy(condition, false, alias, columns);
}
default Children orderBy(boolean condition, boolean isAsc, KProperty<?>... columns) {
return orderBy(condition, isAsc, null, columns);
}
/**
@ -366,15 +449,12 @@ public interface Func<Children> extends Serializable {
*
* @param condition 执行条件
* @param isAsc 是否是 ASC 排序
* @param column 单个字段
* @param columns 字段数组
* @return children
*/
Children orderBy(boolean condition, boolean isAsc, KProperty<?> column, KProperty<?>... columns);
Children orderBy(boolean condition, boolean isAsc, String alias, KProperty<?>... columns);
/**
* ignore
*/
default Children having(String sqlHaving, Object... params) {
return having(true, sqlHaving, params);
}
@ -391,9 +471,7 @@ public interface Func<Children> extends Serializable {
*/
Children having(boolean condition, String sqlHaving, Object... params);
/**
* ignore
*/
default Children func(Consumer<Children> consumer) {
return func(true, consumer);
}

View File

@ -14,11 +14,33 @@ import java.io.Serializable;
*/
@SuppressWarnings("unused")
public interface OnCompare<Children> extends Serializable {
/**
* ignore
*/
default Children eq(KProperty<?> column, KProperty<?> val) {
return eq(true, column, val);
return eq(true, null, column, null, val);
}
default Children eq(String alias, KProperty<?> column, KProperty<?> val) {
return eq(true, alias, column, null, val);
}
default Children eq(KProperty<?> column, String rightAlias, KProperty<?> val) {
return eq(true, null, column, rightAlias, val);
}
default Children eq(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return eq(true, alias, column, rightAlias, val);
}
default Children eq(boolean condition, KProperty<?> column, KProperty<?> val) {
return eq(condition, null, column, null, val);
}
default Children eq(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return eq(condition, alias, column, null, val);
}
default Children eq(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return eq(condition, null, column, rightAlias, val);
}
/**
@ -29,13 +51,35 @@ public interface OnCompare<Children> extends Serializable {
* @param val
* @return children
*/
Children eq(boolean condition, KProperty<?> column, KProperty<?> val);
Children eq(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
/**
* ignore
*/
default Children ne(KProperty<?> column, KProperty<?> val) {
return ne(true, column, val);
return ne(true, null, column, null, val);
}
default Children ne(String alias, KProperty<?> column, KProperty<?> val) {
return ne(true, alias, column, null, val);
}
default Children ne(KProperty<?> column, String rightAlias, KProperty<?> val) {
return ne(true, null, column, rightAlias, val);
}
default Children ne(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ne(true, alias, column, rightAlias, val);
}
default Children ne(boolean condition, KProperty<?> column, KProperty<?> val) {
return ne(condition, null, column, null, val);
}
default Children ne(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return ne(condition, alias, column, null, val);
}
default Children ne(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ne(condition, null, column, rightAlias, val);
}
/**
@ -46,13 +90,35 @@ public interface OnCompare<Children> extends Serializable {
* @param val
* @return children
*/
Children ne(boolean condition, KProperty<?> column, KProperty<?> val);
Children ne(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
/**
* ignore
*/
default Children gt(KProperty<?> column, KProperty<?> val) {
return gt(true, column, val);
return gt(true, null, column, null, val);
}
default Children gt(String alias, KProperty<?> column, KProperty<?> val) {
return gt(true, alias, column, null, val);
}
default Children gt(KProperty<?> column, String rightAlias, KProperty<?> val) {
return gt(true, null, column, rightAlias, val);
}
default Children gt(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return gt(true, alias, column, rightAlias, val);
}
default Children gt(boolean condition, KProperty<?> column, KProperty<?> val) {
return gt(condition, null, column, null, val);
}
default Children gt(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return gt(condition, alias, column, null, val);
}
default Children gt(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return gt(condition, null, column, rightAlias, val);
}
/**
@ -63,13 +129,35 @@ public interface OnCompare<Children> extends Serializable {
* @param val
* @return children
*/
Children gt(boolean condition, KProperty<?> column, KProperty<?> val);
Children gt(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
/**
* ignore
*/
default Children ge(KProperty<?> column, KProperty<?> val) {
return ge(true, column, val);
return ge(true, null, column, null, val);
}
default Children ge(String alias, KProperty<?> column, KProperty<?> val) {
return ge(true, alias, column, null, val);
}
default Children ge(KProperty<?> column, String rightAlias, KProperty<?> val) {
return ge(true, null, column, rightAlias, val);
}
default Children ge(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ge(true, alias, column, rightAlias, val);
}
default Children ge(boolean condition, KProperty<?> column, KProperty<?> val) {
return ge(condition, null, column, null, val);
}
default Children ge(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return ge(condition, alias, column, null, val);
}
default Children ge(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return ge(condition, null, column, rightAlias, val);
}
/**
@ -80,13 +168,35 @@ public interface OnCompare<Children> extends Serializable {
* @param val
* @return children
*/
Children ge(boolean condition, KProperty<?> column, KProperty<?> val);
Children ge(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
/**
* ignore
*/
default Children lt(KProperty<?> column, KProperty<?> val) {
return lt(true, column, val);
return lt(true, null, column, null, val);
}
default Children lt(String alias, KProperty<?> column, KProperty<?> val) {
return lt(true, alias, column, null, val);
}
default Children lt(KProperty<?> column, String rightAlias, KProperty<?> val) {
return lt(true, null, column, rightAlias, val);
}
default Children lt(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return lt(true, alias, column, rightAlias, val);
}
default Children lt(boolean condition, KProperty<?> column, KProperty<?> val) {
return lt(condition, null, column, null, val);
}
default Children lt(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return lt(condition, alias, column, null, val);
}
default Children lt(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return lt(condition, null, column, rightAlias, val);
}
/**
@ -97,13 +207,35 @@ public interface OnCompare<Children> extends Serializable {
* @param val
* @return children
*/
Children lt(boolean condition, KProperty<?> column, KProperty<?> val);
Children lt(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
/**
* ignore
*/
default Children le(KProperty<?> column, KProperty<?> val) {
return le(true, column, val);
return le(true, null, column, null, val);
}
default Children le(String alias, KProperty<?> column, KProperty<?> val) {
return le(true, alias, column, null, val);
}
default Children le(KProperty<?> column, String rightAlias, KProperty<?> val) {
return le(true, null, column, rightAlias, val);
}
default Children le(String alias, KProperty<?> column, String rightAlias, KProperty<?> val) {
return le(true, alias, column, rightAlias, val);
}
default Children le(boolean condition, KProperty<?> column, KProperty<?> val) {
return le(condition, null, column, null, val);
}
default Children le(boolean condition, String alias, KProperty<?> column, KProperty<?> val) {
return le(condition, alias, column, null, val);
}
default Children le(boolean condition, KProperty<?> column, String rightAlias, KProperty<?> val) {
return le(condition, null, column, rightAlias, val);
}
/**
@ -114,5 +246,5 @@ public interface OnCompare<Children> extends Serializable {
* @param val
* @return children
*/
Children le(boolean condition, KProperty<?> column, KProperty<?> val);
Children le(boolean condition, String alias, KProperty<?> column, String rightAlias, KProperty<?> val);
}

View File

@ -4,7 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.github.yulichang.kt.segments.FuncArgs;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.Constant;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
@ -28,7 +28,7 @@ import java.util.stream.Collectors;
*
* @author yulichang
*/
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "DuplicatedCode"})
public interface Query<Children> extends Serializable {
@ -53,8 +53,7 @@ public interface Query<Children> extends Serializable {
*/
@Deprecated
default Children select(Class<?> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableHelper.get(entityClass);
Asserts.hasTable(info, entityClass);
TableInfo info = TableHelper.getAssert(entityClass);
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(entityClass);
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
i -> getSelectColum().add(new SelectNormal(cacheMap.get(i.getProperty()), getIndex(), isHasAlias(), getAlias())));
@ -73,8 +72,7 @@ public interface Query<Children> extends Serializable {
* @return children
*/
default Children selectFilter(Class<?> entityClass, Predicate<SelectCache> predicate) {
TableInfo info = TableHelper.get(entityClass);
Asserts.hasTable(info, entityClass);
TableInfo info = TableHelper.getAssert(entityClass);
List<SelectCache> cacheList = ColumnCache.getListField(entityClass);
cacheList.stream().filter(predicate).collect(Collectors.toList()).forEach(
i -> getSelectColum().add(new SelectNormal(i, getIndex(), isHasAlias(), getAlias())));
@ -90,7 +88,8 @@ public interface Query<Children> extends Serializable {
* @param columns
*/
default Children select(String... columns) {
getSelectColum().addAll(Arrays.stream(columns).map(i -> new SelectString(i, isHasAlias(), getAlias())).collect(Collectors.toList()));
getSelectColum().addAll(Arrays.stream(columns).map(i ->
new SelectString(i, null)).collect(Collectors.toList()));
return getChildren();
}
@ -100,7 +99,7 @@ public interface Query<Children> extends Serializable {
* @param column
*/
default Children selectAs(String column, KProperty<?> alias) {
getSelectColum().add(new SelectString(column + Constants.AS + alias.getName(), isHasAlias(), getAlias()));
getSelectColum().add(new SelectString(column + Constant.AS + alias.getName(), alias.getName()));
return getChildren();
}
@ -113,8 +112,7 @@ public interface Query<Children> extends Serializable {
Map<String, SelectCache> cacheMap = ColumnCache.getMapField(KtUtils.ref(column));
SelectCache cache = cacheMap.get(column.getName());
getSelectColum().add(new SelectString(
index + Constants.DOT + cache.getColumn() + Constants.AS + alias.getName(),
isHasAlias(), getAlias()));
index + Constants.DOT + cache.getColumn() + Constant.AS + alias.getName(), alias.getName()));
return getChildren();
}
@ -129,11 +127,12 @@ public interface Query<Children> extends Serializable {
* @return children
*/
default Children selectAsClass(Class<?> source, Class<?> tag) {
List<SelectCache> normalList = ColumnCache.getListField(source);
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(tag);
for (SelectCache cache : normalList) {
if (fieldMap.containsKey(cache.getColumProperty())) {
getSelectColum().add(new SelectNormal(cache, getIndex(), isHasAlias(), getAlias()));
Map<String, SelectCache> normalMap = ColumnCache.getMapField(source);
List<FieldCache> fieldList = MPJReflectionKit.getFieldList(tag);
for (FieldCache cache : fieldList) {
if (normalMap.containsKey(cache.getField().getName())) {
SelectCache selectCache = normalMap.get(cache.getField().getName());
getSelectColum().add(new SelectNormal(selectCache, getIndex(), isHasAlias(), getAlias()));
}
}
return getChildren();

View File

@ -26,6 +26,17 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.LEFT_JOIN, clazz, left, right);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.LEFT_JOIN, clazz, left, rightAlias, right);
}
/**
* left join 多条件
* <p>
@ -72,6 +83,17 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.LEFT_JOIN, clazz, alias, left, right);
}
/**
* left join
*
* @param clazz 关联的实体类
* @param left 条件
* @param right 条件
*/
default Children leftJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.LEFT_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* left join 多条件
* <p>
@ -114,6 +136,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.RIGHT_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.RIGHT_JOIN, clazz, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
@ -142,6 +171,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.RIGHT_JOIN, clazz, alias, left, right);
}
/**
* ignore 参考 left join
*/
default Children rightJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.RIGHT_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
@ -171,6 +207,14 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.INNER_JOIN, clazz, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.INNER_JOIN, clazz, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
@ -200,6 +244,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.INNER_JOIN, clazz, alias, on -> on.eq(left, right));
}
/**
* ignore 参考 left join
*/
default Children innerJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.INNER_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
@ -228,6 +279,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.FULL_JOIN, clazz, left, right);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.FULL_JOIN, clazz, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
@ -256,6 +314,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(Constant.FULL_JOIN, clazz, alias, left, right);
}
/**
* ignore 参考 left join
*/
default Children fullJoin(Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(Constant.FULL_JOIN, clazz, alias, left, rightAlias, right);
}
/**
* ignore 参考 left join
*/
@ -292,6 +357,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(keyWord, clazz, on -> on.eq(left, right));
}
/**
* ignore
*/
default Children join(String keyWord, Class<?> clazz, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(keyWord, clazz, on -> on.eq(left, rightAlias, right));
}
/**
* 自定义连表关键词
* <p>
@ -333,6 +405,13 @@ public interface QueryJoin<Children, Entity> extends MPJBaseJoin<Entity>, String
return join(keyWord, clazz, alias, on -> on.eq(left, right));
}
/**
* ignore
*/
default <T, X> Children join(String keyWord, Class<?> clazz, String alias, KProperty<?> left, String rightAlias, KProperty<?> right) {
return join(keyWord, clazz, alias, on -> on.eq(left, rightAlias, right));
}
/**
* 自定义连表关键词
* <p>

View File

@ -32,7 +32,7 @@ public interface QueryLabel<Children> {
* <p>
* 举例 UserDO AddressDO 为一对多关系 UserDTO 为结果类
* <pre>
* MPJLambdaQueryWrapper<UserDO> wrapper = new MPJLambdaQueryWrapper<UserDO>();
* MPJLambdaWrapper&lt;UserDO&gt; wrapper = new MPJLambdaWrapper&lt;UserDO&gt;();
* wrapper.selectAll(UserDO.class)
* .selectCollection(AddressDO.class, UserDTO::getAddressListDTO)
* .leftJoin(AddressDO.class, ...... )
@ -71,7 +71,7 @@ public interface QueryLabel<Children> {
* <p>
* 举例 UserDO AddressDO 为一对多关系 UserDTO 为结果类
* <pre>
* MPJLambdaQueryWrapper<UserDO> wrapper = new MPJLambdaQueryWrapper();
* MPJLambdaWrapper&lt;UserDO&gt; wrapper = new MPJLambdaWrapper();
* wrapper.selectAll(UserDO.class)
* .selectCollection(AddressDO.class, UserDTO::getAddressListDTO, map -> map
* .id(AddressDO::getId, AddressDTO::getId) //如果属性名一致 可以传一个

View File

@ -50,6 +50,18 @@ public interface Update<Children> extends Serializable {
*/
Children set(boolean condition, KProperty<?> column, Object val, String mapping);
default Children setIncrBy(KProperty<?> column, Number val) {
return setIncrBy(true, column, val);
}
Children setIncrBy(boolean condition, KProperty<?> column, Number val);
default Children setDecrBy(KProperty<?> column, Number val) {
return setDecrBy(true, column, val);
}
Children setDecrBy(boolean condition, KProperty<?> column, Number val);
/**
* ignore
*/

View File

@ -3,7 +3,6 @@ package com.github.yulichang.kt.resultmap;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.KtUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
@ -145,7 +144,7 @@ public class MybatisLabel<E, T> implements Label<T> {
/**
* 嵌套
*/
public Builder<E, T> collection(String prefix, Class<?> entityClass, KProperty<?> func) {
public Builder<E, T> collection(String prefix, Class<?> entityClass, KProperty<?> func) {
String dtoFieldName = func.getName();
Map<String, FieldCache> fieldMap = MPJReflectionKit.getFieldMap(KtUtils.ref(func));
FieldCache field = fieldMap.get(dtoFieldName);
@ -254,8 +253,7 @@ public class MybatisLabel<E, T> implements Label<T> {
}
private void autoBuild(boolean auto, Class<E> entityClass, Class<T> tagClass) {
TableInfo tableInfo = TableHelper.get(entityClass);
Asserts.hasTable(tableInfo, entityClass);
TableInfo tableInfo = TableHelper.getAssert(entityClass);
Map<String, FieldCache> tagMap = MPJReflectionKit.getFieldMap(tagClass);
if (auto && !tagMap.isEmpty()) {
List<SelectCache> listField = ColumnCache.getListField(entityClass);

View File

@ -16,7 +16,7 @@ import java.util.Arrays;
public class FuncArgs {
public SelectFunc.Arg[] accept(KProperty<?>... kProperty) {
return Arrays.stream(kProperty).map(i -> new SelectFunc.Arg(KtUtils.ref(i), i.getName())).toArray(SelectFunc.Arg[]::new);
return Arrays.stream(kProperty).map(i -> new SelectFunc.Arg(KtUtils.ref(i), i.getName(), false, null)).toArray(SelectFunc.Arg[]::new);
}
}

View File

@ -28,16 +28,16 @@ public class DeleteJoin extends MPJAbstractMethod {
@SuppressWarnings("DuplicatedCode")
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE_JOIN;
if (AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo)) {
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo)) {
String sql = String.format(sqlMethod.getSql(), sqlFirst(), mpjTableName(tableInfo), sqlAlias(), sqlFrom(),
mpjDeleteLogic(tableInfo), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
} else {
sqlMethod = SqlMethod.DELETE_JOIN;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), mpjDelete(), mpjTableName(tableInfo),
sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);
}
}

View File

@ -6,9 +6,11 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.adapter.v352.AbstractMethod352;
import com.github.yulichang.config.ConfigProperties;
import org.apache.ibatis.builder.SqlSourceBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
* @author yulichang
@ -82,4 +84,22 @@ public abstract class MPJAbstractMethod extends AbstractMethod352 implements MPJ
return "";
}
}
public String removeExtraWhitespaces(String sql) {
try {
return SqlSourceBuilder.removeExtraWhitespaces(sql);
} catch (Throwable t) {
StringTokenizer tokenizer = new StringTokenizer(sql);
StringBuilder builder = new StringBuilder();
boolean hasMoreTokens = tokenizer.hasMoreTokens();
while (hasMoreTokens) {
builder.append(tokenizer.nextToken());
hasMoreTokens = tokenizer.hasMoreTokens();
if (hasMoreTokens) {
builder.append(' ');
}
}
return builder.toString();
}
}
}

View File

@ -1,7 +1,6 @@
package com.github.yulichang.method;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@ -10,9 +9,9 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.annotation.DynamicTableName;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.VersionUtils;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@ -72,23 +71,19 @@ public interface MPJBaseMethod extends Constants {
*/
default String mpjSqlOrderBy(TableInfo tableInfo) {
/* 不存在排序字段,直接返回空 */
List<TableFieldInfo> orderByFields;
List<OrderFieldInfo> orderByFields;
try {
if (VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3") >= 0) {
orderByFields = tableInfo.getOrderByFields();
} else {
return StringPool.EMPTY;
}
orderByFields = AdapterHelper.getAdapter().mpjGetOrderField(tableInfo);
} catch (Exception e) {
return StringPool.EMPTY;
}
if (CollectionUtils.isEmpty(orderByFields)) {
return StringPool.EMPTY;
}
orderByFields.sort(Comparator.comparingInt(TableFieldInfo::getOrderBySort));
orderByFields.sort(Comparator.comparingInt(OrderFieldInfo::getSort));
String sql = NEWLINE + " ORDER BY " +
orderByFields.stream().map(tfi -> String.format("${ew.alias}.%s %s", tfi.getColumn(),
tfi.getOrderByType())).collect(joining(","));
tfi.getType())).collect(joining(","));
/* 当wrapper中传递了orderBy属性@orderBy注解失效 */
return SqlScriptUtils.convertIf(sql, String.format("%s == null or %s", WRAPPER,
WRAPPER_EXPRESSION_ORDER), true);
@ -112,7 +107,7 @@ public interface MPJBaseMethod extends Constants {
return filedSqlScript;
}
String newKeyProperty = newPrefix + tableInfo.getKeyProperty();
String keySqlScript = ConfigProperties.tableAlias + DOT + tableInfo.getKeyColumn() + EQUALS +
String keySqlScript = "${ew.alias}" + DOT + tableInfo.getKeyColumn() + EQUALS +
SqlScriptUtils.safeParam(newKeyProperty);
return SqlScriptUtils.convertIf(keySqlScript, String.format("%s != null", newKeyProperty), false)
+ NEWLINE + filedSqlScript;
@ -121,7 +116,7 @@ public interface MPJBaseMethod extends Constants {
default String getSqlWhere(TableFieldInfo tableFieldInfo, final String prefix) {
final String newPrefix = prefix == null ? EMPTY : prefix;
// 默认: AND column=#{prefix + el}
String sqlScript = " AND " + String.format(tableFieldInfo.getCondition(), ConfigProperties.tableAlias + DOT +
String sqlScript = " AND " + String.format(tableFieldInfo.getCondition(), "${ew.alias}" + DOT +
tableFieldInfo.getColumn(), newPrefix + tableFieldInfo.getEl());
// 查询的时候只判非空
return convertIf(tableFieldInfo, sqlScript, convertIfProperty(newPrefix, tableFieldInfo.getProperty()),
@ -231,7 +226,7 @@ public interface MPJBaseMethod extends Constants {
return tableInfo.getFieldList().stream()
.filter(i -> {
if (ignoreLogicDelFiled) {
return !(AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo) && i.isLogicDelete());
return !(AdapterHelper.getAdapter().mpjHasLogic(tableInfo) && i.isLogicDelete());
}
return true;
}).map(i -> mpjGetSqlSet(i, newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE));

View File

@ -27,7 +27,7 @@ public class SelectJoinCount extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_COUNT;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlCount(),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Long.class);
}
}

View File

@ -31,7 +31,7 @@ public class SelectJoinList extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_LIST;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlDistinct(), sqlSelectColumns(tableInfo, true),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), mpjSqlOrderBy(tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class);
}

View File

@ -32,7 +32,7 @@ public class SelectJoinMap extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAP;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlDistinct(), sqlSelectColumns(tableInfo, true),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class);
}

View File

@ -33,7 +33,7 @@ public class SelectJoinMaps extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlDistinct(), sqlSelectColumns(tableInfo, true),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), mpjSqlOrderBy(tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class);
}

View File

@ -33,7 +33,7 @@ public class SelectJoinMapsPage extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS_PAGE;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlDistinct(), sqlSelectColumns(tableInfo, true),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), mpjSqlOrderBy(tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class);
}

View File

@ -30,7 +30,7 @@ public class SelectJoinOne extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_ONE;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlDistinct(), sqlSelectColumns(tableInfo, true),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class);
}

View File

@ -31,7 +31,7 @@ public class SelectJoinPage extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_PAGE;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlDistinct(), sqlSelectColumns(tableInfo, true),
mpjTableName(tableInfo), sqlAlias(), sqlFrom(), sqlWhereEntityWrapper(true, tableInfo), mpjSqlOrderBy(tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, MPJResultType.class);
}

View File

@ -31,7 +31,7 @@ public class UpdateJoin extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.UPDATE_JOIN;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), mpjTableName(tableInfo), sqlAlias(), sqlFrom(),
mpjSqlSet(true, true, tableInfo, true, ENTITY, ENTITY_DOT), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
}
@ -64,7 +64,7 @@ public class UpdateJoin extends MPJAbstractMethod {
if (fieldStrategy == FieldStrategy.NEVER) {
return null;
}
if (AdapterHelper.getTableInfoAdapter().mpjIsPrimitive(tableFieldInfo) || fieldStrategy == FieldStrategy.IGNORED) {
if (AdapterHelper.getAdapter().mpjIsPrimitive(tableFieldInfo) || fieldStrategy == FieldStrategy.IGNORED) {
return sqlScript;
}
if (fieldStrategy == FieldStrategy.NOT_EMPTY && tableFieldInfo.isCharSequence()) {

View File

@ -30,7 +30,7 @@ public class UpdateJoinAndNull extends MPJAbstractMethod {
SqlMethod sqlMethod = SqlMethod.UPDATE_JOIN_AND_NULL;
String sql = String.format(sqlMethod.getSql(), sqlFirst(), mpjTableName(tableInfo), sqlAlias(), sqlFrom(),
mpjSqlSet(true, true, tableInfo, true, ENTITY, ENTITY_DOT), sqlWhereEntityWrapper(true, tableInfo), sqlComment());
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, removeExtraWhitespaces(sql), modelClass);
return this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
}

View File

@ -3,6 +3,7 @@ package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
@ -35,8 +36,12 @@ public class SelectList extends com.baomidou.mybatisplus.core.injector.methods.S
@Override
protected String sqlOrderBy(TableInfo table) {
String orderBy = super.sqlOrderBy(table);
if (StringUtils.isBlank(orderBy)) {
return orderBy;
}
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlOrderBy(table), mpjSqlOrderBy(table));
orderBy, mpjSqlOrderBy(table));
}
@Override

View File

@ -3,6 +3,7 @@ package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
@ -35,6 +36,10 @@ public class SelectMaps extends com.baomidou.mybatisplus.core.injector.methods.S
@Override
protected String sqlOrderBy(TableInfo table) {
String orderBy = super.sqlOrderBy(table);
if (StringUtils.isBlank(orderBy)) {
return orderBy;
}
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlOrderBy(table), mpjSqlOrderBy(table));
}

View File

@ -3,6 +3,7 @@ package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
@ -35,6 +36,10 @@ public class SelectMapsPage extends com.baomidou.mybatisplus.core.injector.metho
@Override
protected String sqlOrderBy(TableInfo table) {
String orderBy = super.sqlOrderBy(table);
if (StringUtils.isBlank(orderBy)) {
return orderBy;
}
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlOrderBy(table), mpjSqlOrderBy(table));
}

View File

@ -3,6 +3,7 @@ package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
@ -48,6 +49,16 @@ public class SelectObjs extends com.baomidou.mybatisplus.core.injector.methods.S
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlOrderBy(TableInfo table) {
String orderBy = super.sqlOrderBy(table);
if (StringUtils.isBlank(orderBy)) {
return orderBy;
}
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlOrderBy(table), mpjSqlOrderBy(table));
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",

View File

@ -3,6 +3,7 @@ package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
@ -45,6 +46,16 @@ public class SelectOne extends com.baomidou.mybatisplus.core.injector.methods.Se
selectColumns, mpjSqlSelectColumns() + StringPool.SPACE + selectColumns);
}
@Override
protected String sqlOrderBy(TableInfo table) {
String orderBy = super.sqlOrderBy(table);
if (StringUtils.isBlank(orderBy)) {
return orderBy;
}
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlOrderBy(table), mpjSqlOrderBy(table));
}
@Override
protected String sqlComment() {
return super.sqlComment() + StringPool.NEWLINE + SqlScriptUtils.convertIf("${ew.unionSql}", String.format("%s != null and (%s instanceof %s)",

View File

@ -3,6 +3,7 @@ package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
@ -35,6 +36,10 @@ public class SelectPage extends com.baomidou.mybatisplus.core.injector.methods.S
@Override
protected String sqlOrderBy(TableInfo table) {
String orderBy = super.sqlOrderBy(table);
if (StringUtils.isBlank(orderBy)) {
return orderBy;
}
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlOrderBy(table), mpjSqlOrderBy(table));
}

View File

@ -6,18 +6,22 @@ import com.baomidou.mybatisplus.core.conditions.query.Query;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.query.interfaces.CompareIfExists;
import com.github.yulichang.query.interfaces.StringJoin;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.ThrowOptional;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import lombok.Getter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@ -30,7 +34,8 @@ import java.util.stream.Collectors;
*/
@SuppressWarnings("unused")
public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambdaQueryWrapper<T>>
implements Query<MPJLambdaQueryWrapper<T>, T, SFunction<T, ?>>, StringJoin<MPJLambdaQueryWrapper<T>, T> {
implements Query<MPJLambdaQueryWrapper<T>, T, SFunction<T, ?>>, StringJoin<MPJLambdaQueryWrapper<T>, T>,
CompareIfExists<MPJLambdaQueryWrapper<T>, SFunction<T, ?>> {
/**
* 查询字段
@ -45,7 +50,8 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
/**
* 主表别名
*/
private final String alias = ConfigProperties.tableAlias;
@Getter
private String alias = ConfigProperties.tableAlias;
/**
* 查询的列
@ -61,6 +67,17 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
* 是否 select distinct
*/
private boolean selectDistinct = false;
/**
* 主表逻辑删除
*/
private boolean logicSql = true;
/**
* 动态表名
*/
private Function<String, String> tableNameFunc;
@Getter
private BiPredicate<Object, IfExistsSqlKeyWordEnum> ifExists = ConfigProperties.ifExists;
/**
* 不建议直接 new 该实例使用 Wrappers.lambdaQuery(entity)
@ -75,9 +92,10 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
MPJLambdaQueryWrapper(T entity, Class<T> entityClass, SharedString from, SharedString sqlSelect, AtomicInteger paramNameSeq,
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
List<String> selectColumns, List<String> ignoreColumns, boolean selectDistinct) {
List<String> selectColumns, List<String> ignoreColumns, boolean selectDistinct,
BiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
super.setEntity(entity);
super.setEntityClass(entityClass);
setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
@ -85,10 +103,11 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
this.from = from;
this.lastSql = lastSql;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
ThrowOptional.tryDo(() -> this.sqlFirst = sqlFirst).catchDo();
this.selectColumns = selectColumns;
this.ignoreColumns = ignoreColumns;
this.selectDistinct = selectDistinct;
this.ifExists = IfExists;
}
/**
@ -174,8 +193,7 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
*/
@Override
public MPJLambdaQueryWrapper<T> select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableHelper.get(entityClass);
Asserts.hasTable(info, entityClass);
TableInfo info = TableHelper.getAssert(entityClass);
selectColumns.addAll(info.getFieldList().stream().filter(predicate).map(c ->
alias + StringPool.DOT + c.getColumn()).collect(Collectors.toList()));
return typedThis;
@ -199,8 +217,7 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
*/
@SuppressWarnings("DuplicatedCode")
public final MPJLambdaQueryWrapper<T> selectAll(Class<?> clazz, String as) {
TableInfo info = TableHelper.get(clazz);
Asserts.hasTable(info, clazz);
TableInfo info = TableHelper.getAssert(clazz);
if (info.havePK()) {
selectColumns.add(as + StringPool.DOT + info.getKeyColumn());
}
@ -214,7 +231,8 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
*/
public MPJQueryWrapper<T> stringQuery() {
return new MPJQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs,
expression, sqlSelect, from, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns, selectDistinct);
expression, sqlSelect, from, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns,
selectDistinct, ifExists);
}
@Override
@ -241,15 +259,91 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
return from.getStringValue();
}
public String getAlias() {
return alias;
public MPJLambdaQueryWrapper<T> setAlias(String alias) {
Assert.isTrue(StringUtils.isNotBlank(alias), "别名不能为空");
this.alias = alias;
return typedThis;
}
/**
* 逻辑删除
*/
public String getSubLogicSql() {
return StringPool.EMPTY;
}
/**
* 关闭主表逻辑删除
*/
public MPJLambdaQueryWrapper<T> disableLogicDel() {
this.logicSql = false;
return typedThis;
}
/**
* 启用主表逻辑删除
*/
public MPJLambdaQueryWrapper<T> enableLogicDel() {
this.logicSql = true;
return typedThis;
}
/**
* 逻辑删除
*/
public boolean getLogicSql() {
return logicSql;
}
public boolean getSelectDistinct() {
return selectDistinct;
}
/**
* 动态表名
* 如果主表需要动态表名,主表实体必须添加 @DynamicTableName 注解
* 关联表则不需要 加不加注解都会生效
* <p>
*
* @see com.github.yulichang.annotation.DynamicTableName
*/
public MPJLambdaQueryWrapper<T> setTableName(Function<String, String> func) {
this.tableNameFunc = func;
return typedThis;
}
public String getTableName(String tableName) {
if (this.tableNameFunc == null) {
return tableName;
}
return this.tableNameFunc.apply(tableName);
}
@SuppressWarnings("DuplicatedCode")
public String getTableNameEnc(String tableName) {
String decode;
try {
decode = URLDecoder.decode(tableName, "UTF-8");
} catch (UnsupportedEncodingException e) {
decode = tableName;
}
if (this.tableNameFunc == null) {
return decode;
}
return this.tableNameFunc.apply(decode);
}
public MPJLambdaQueryWrapper<T> setIfExists(BiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
this.ifExists = IfExists;
return typedThis;
}
public MPJLambdaQueryWrapper<T> setIfExists(Predicate<Object> IfExists) {
this.ifExists = (o, k) -> IfExists.test(o);
return typedThis;
}
/**
* 用于生成嵌套 sql
* <p> sqlSelect selectColumn ignoreColumns from不向下传递</p>
@ -257,7 +351,34 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
@Override
protected MPJLambdaQueryWrapper<T> instance() {
return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), null, null, paramNameSeq, paramNameValuePairs,
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), null, null, selectDistinct);
new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
null, null, selectDistinct, ifExists);
}
@Override
public Class<T> getEntityClass() {
try {
return super.getEntityClass();
} catch (Throwable throwable) {
return null;
}
}
@Override
public MPJLambdaQueryWrapper<T> setEntityClass(Class<T> entityClass) {
try {
return super.setEntityClass(entityClass);
} catch (Throwable throwable) {
return this;
}
}
public SharedString getSqlFirstField() {
try {
return sqlSelect;
} catch (Throwable throwable) {
return SharedString.emptyString();
}
}
@Override
@ -267,6 +388,7 @@ public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambda
from.toNull();
selectColumns.clear();
ignoreColumns.clear();
ifExists = ConfigProperties.ifExists;
}
@Override

View File

@ -1,5 +1,6 @@
package com.github.yulichang.query;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.SharedString;
import com.baomidou.mybatisplus.core.conditions.query.Query;
@ -8,11 +9,14 @@ import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.query.interfaces.CompareIfExists;
import com.github.yulichang.query.interfaces.StringJoin;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.MPJSqlInjectionUtils;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.ThrowOptional;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import com.github.yulichang.wrapper.interfaces.Chain;
import lombok.Getter;
@ -23,20 +27,22 @@ import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* copy {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
* 推荐使用 JoinWrappers.<UserDO>queryJoin();构造
* 推荐使用 JoinWrappers.&lt;UserDO&gt;query();构造
*
* @author yulichang
* @see com.github.yulichang.toolkit.JoinWrappers
*/
@SuppressWarnings("unused")
public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapper<T>> implements
Query<MPJQueryWrapper<T>, T, String>, StringJoin<MPJQueryWrapper<T>, T>, Chain<T> {
Query<MPJQueryWrapper<T>, T, String>, StringJoin<MPJQueryWrapper<T>, T>, Chain<T>,
CompareIfExists<MPJQueryWrapper<T>, String> {
/**
* 查询字段
@ -83,13 +89,22 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
*/
private boolean checkSqlInjection = false;
@Getter
private BiPredicate<Object, IfExistsSqlKeyWordEnum> ifExists = ConfigProperties.ifExists;
public MPJQueryWrapper() {
super.initNeed();
}
public MPJQueryWrapper(Class<T> clazz) {
super.setEntityClass(clazz);
try {
super.setEntityClass(clazz);
} catch (NoSuchMethodError error) {
if (VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.3.0") > 0) {
throw error;
}
}
super.initNeed();
}
@ -107,9 +122,10 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments,
SharedString sqlSelect, SharedString from, SharedString lastSql,
SharedString sqlComment, SharedString sqlFirst,
List<String> selectColumns, List<String> ignoreColumns, boolean selectDistinct) {
List<String> selectColumns, List<String> ignoreColumns, boolean selectDistinct,
BiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
super.setEntity(entity);
super.setEntityClass(entityClass);
setEntityClass(entityClass);
this.paramNameSeq = paramNameSeq;
this.paramNameValuePairs = paramNameValuePairs;
this.expression = mergeSegments;
@ -117,10 +133,11 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
this.lastSql = lastSql;
this.from = from;
this.sqlComment = sqlComment;
this.sqlFirst = sqlFirst;
ThrowOptional.tryDo(() -> this.sqlFirst = sqlFirst).catchDo();
this.selectColumns = selectColumns;
this.ignoreColumns = ignoreColumns;
this.selectDistinct = selectDistinct;
this.ifExists = IfExists;
}
/**
@ -131,6 +148,16 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
return this;
}
public MPJQueryWrapper<T> setIfExists(BiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
this.ifExists = IfExists;
return this;
}
public MPJQueryWrapper<T> setIfExists(Predicate<Object> IfExists) {
this.ifExists = (o, k) -> IfExists.test(o);
return this;
}
@Override
protected String columnToString(String column) {
if (checkSqlInjection && MPJSqlInjectionUtils.check(column)) {
@ -187,8 +214,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
*/
@Override
public MPJQueryWrapper<T> select(Class<T> entityClass, Predicate<TableFieldInfo> predicate) {
TableInfo info = TableHelper.get(entityClass);
Asserts.hasTable(info, entityClass);
TableInfo info = TableHelper.getAssert(entityClass);
selectColumns.addAll(info.getFieldList().stream().filter(predicate).map(c ->
alias + StringPool.DOT + c.getSqlSelect()).collect(Collectors.toList()));
return typedThis;
@ -212,8 +238,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
*/
@SuppressWarnings({"DuplicatedCode", "UnusedReturnValue"})
public final MPJQueryWrapper<T> selectAll(Class<?> clazz, String as) {
TableInfo info = TableHelper.get(clazz);
Asserts.hasTable(info, clazz);
TableInfo info = TableHelper.getAssert(clazz);
if (ConfigProperties.tableInfoAdapter.mpjHasPK(info)) {
selectColumns.add(as + StringPool.DOT + info.getKeySqlSelect());
}
@ -307,6 +332,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
return this.tableNameFunc.apply(tableName);
}
@SuppressWarnings("DuplicatedCode")
public String getTableNameEnc(String tableName) {
String decode;
try {
@ -325,7 +351,33 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
*/
public MPJLambdaQueryWrapper<T> lambda() {
return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), from, sqlSelect, paramNameSeq, paramNameValuePairs,
expression, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns, selectDistinct);
expression, lastSql, sqlComment, getSqlFirstField(), selectColumns, ignoreColumns, selectDistinct, ifExists);
}
@Override
public Class<T> getEntityClass() {
try {
return super.getEntityClass();
} catch (Throwable throwable) {
return null;
}
}
@Override
public MPJQueryWrapper<T> setEntityClass(Class<T> entityClass) {
try {
return super.setEntityClass(entityClass);
} catch (Throwable throwable) {
return this;
}
}
public SharedString getSqlFirstField() {
try {
return sqlSelect;
} catch (Throwable throwable) {
return SharedString.emptyString();
}
}
/**
@ -335,7 +387,8 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
@Override
protected MPJQueryWrapper<T> instance() {
return new MPJQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, new MergeSegments(),
null, null, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), null, null, selectDistinct);
null, null, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
null, null, selectDistinct, ifExists);
}
@ -346,6 +399,7 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
from.toNull();
selectColumns.clear();
ignoreColumns.clear();
ifExists = ConfigProperties.ifExists;
}
@Override

View File

@ -0,0 +1,151 @@
package com.github.yulichang.query.interfaces;
import com.baomidou.mybatisplus.core.conditions.interfaces.Compare;
import com.github.yulichang.wrapper.enums.IfExistsSqlKeyWordEnum;
import java.util.function.BiPredicate;
/**
* 查询条件封装
* <p>比较值</p>
*
* @author yulichang
* @since 1.4.9
*/
@SuppressWarnings("unused")
public interface CompareIfExists<Children, R> extends Compare<Children, R> {
BiPredicate<Object, IfExistsSqlKeyWordEnum> getIfExists();
/**
* 等于 =
*
* @param column 字段
* @param val
* @return children
*/
default Children eqIfExists(R column, Object val) {
return eq(getIfExists().test(val, IfExistsSqlKeyWordEnum.EQ), column, val);
}
/**
* 不等于 &lt;&gt;
*
* @param column 字段
* @param val
* @return children
*/
default Children neIfExists(R column, Object val) {
return ne(getIfExists().test(val, IfExistsSqlKeyWordEnum.NE), column, val);
}
/**
* 大于 &gt;
*
* @param column 字段
* @param val
* @return children
*/
default Children gtIfExists(R column, Object val) {
return gt(getIfExists().test(val, IfExistsSqlKeyWordEnum.GT), column, val);
}
/**
* 大于等于 &gt;=
*
* @param column 字段
* @param val
* @return children
*/
default Children geIfExists(R column, Object val) {
return ge(getIfExists().test(val, IfExistsSqlKeyWordEnum.GE), column, val);
}
/**
* 小于 &lt;
*
* @param column 字段
* @param val
* @return children
*/
default Children ltIfExists(R column, Object val) {
return lt(getIfExists().test(val, IfExistsSqlKeyWordEnum.LT), column, val);
}
/**
* 小于等于 &lt;=
*
* @param column 字段
* @param val
* @return children
*/
default Children leIfExists(R column, Object val) {
return le(getIfExists().test(val, IfExistsSqlKeyWordEnum.LE), column, val);
}
/**
* LIKE '%%'
*
* @param column 字段
* @param val
* @return children
*/
default Children likeIfExists(R column, Object val) {
return like(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE), column, val);
}
/**
* NOT LIKE '%%'
*
* @param column 字段
* @param val
* @return children
*/
default Children notLikeIfExists(R column, Object val) {
return notLike(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE), column, val);
}
/**
* NOT LIKE '%'
*
* @param column 字段
* @param val
* @return children
*/
default Children notLikeLeftIfExists(R column, Object val) {
return notLikeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_LEFT), column, val);
}
/**
* NOT LIKE '%'
*
* @param column 字段
* @param val
* @return children
*/
default Children notLikeRightIfExists(R column, Object val) {
return notLikeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.NOT_LIKE_RIGHT), column, val);
}
/**
* LIKE '%'
*
* @param column 字段
* @param val
* @return children
*/
default Children likeLeftIfExists(R column, Object val) {
return likeLeft(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_LEFT), column, val);
}
/**
* LIKE '%'
*
* @param column 字段
* @param val
* @return children
*/
default Children likeRightIfExists(R column, Object val) {
return likeRight(getIfExists().test(val, IfExistsSqlKeyWordEnum.LIKE_RIGHT), column, val);
}
}

View File

@ -7,6 +7,10 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool;
*/
public interface Constant {
String PLUS = " + ";
String DASH = " - ";
String AS = " AS ";
String ON = " ON ";

View File

@ -0,0 +1,22 @@
package com.github.yulichang.toolkit;
import java.util.HashMap;
import java.util.Locale;
/**
* @author yulichang
* @see HashMap
* @since 1.4.8
*/
public class FieldStringMap<V> extends HashMap<String, V> {
@Override
public V get(Object key) {
return super.get(key == null ? null : ((String) key).toUpperCase(Locale.ENGLISH));
}
@Override
public boolean containsKey(Object key) {
return super.containsKey(key == null ? null : ((String) key).toUpperCase(Locale.ENGLISH));
}
}

View File

@ -13,7 +13,7 @@ import com.github.yulichang.wrapper.UpdateJoinWrapper;
public class JoinWrappers {
/**
* JoinWrappers.<UserDO>query()
* JoinWrappers.&lt;UserDO&gt;query()
*/
public static <T> MPJQueryWrapper<T> query() {
return new MPJQueryWrapper<>();
@ -34,14 +34,14 @@ public class JoinWrappers {
}
/**
* JoinWrappers.<UserDO>lambda()
* JoinWrappers.&lt;UserDO&gt;lambda()
*/
public static <T> MPJLambdaWrapper<T> lambda() {
return new MPJLambdaWrapper<>();
}
/**
* JoinWrappers.<UserDO>lambda("t")
* JoinWrappers.&lt;UserDO&gt;lambda("t")
*/
public static <T> MPJLambdaWrapper<T> lambda(String alias) {
return new MPJLambdaWrapper<>(alias);

View File

@ -16,12 +16,11 @@ import java.util.Optional;
* @author yulichang
* @since 1.4.6
*/
@SuppressWarnings("DuplicatedCode")
public class KtWrapperUtils {
@SuppressWarnings("DuplicatedCode")
public static String buildSubSqlByWrapper(Class<?> clazz, KtLambdaWrapper<?> wrapper, String alias) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
TableInfo tableInfo = TableHelper.getAssert(clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
@ -43,7 +42,7 @@ public class KtWrapperUtils {
return String.format(" (%s SELECT %s FROM %s %s %s %s %s %s %s) AS %s ",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
wrapper.getTableName(tableInfo.getTableName()),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
@ -53,10 +52,8 @@ public class KtWrapperUtils {
alias);
}
@SuppressWarnings("DuplicatedCode")
public static String buildUnionSqlByWrapper(Class<?> clazz, KtLambdaWrapper<?> wrapper) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
TableInfo tableInfo = TableHelper.getAssert(clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
@ -78,7 +75,7 @@ public class KtWrapperUtils {
return String.format(" %s SELECT %s FROM %s %s %s %s %s %s %s ",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
wrapper.getTableName(tableInfo.getTableName()),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
@ -94,7 +91,6 @@ public class KtWrapperUtils {
return SqlScriptUtils.safeParam(paramStr, null);
}
@SuppressWarnings("DuplicatedCode")
private static String getEntitySql(TableInfo tableInfo, KtLambdaWrapper<?> wrapper) {
Object obj = wrapper.getEntity();
if (Objects.isNull(obj)) {
@ -102,7 +98,7 @@ public class KtWrapperUtils {
}
StringBuilder sb = new StringBuilder(StringPool.EMPTY);
for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
continue;
}
Object val;
@ -126,6 +122,9 @@ public class KtWrapperUtils {
}
private static String mainLogic(boolean hasWhere, Class<?> clazz, KtLambdaWrapper<?> wrapper) {
if (!wrapper.getLogicSql()) {
return StringPool.EMPTY;
}
String info = LogicInfoUtils.getLogicInfo(null, clazz, true, wrapper.getAlias());
if (StringUtils.isNotBlank(info)) {
if (hasWhere) {

View File

@ -2,31 +2,24 @@ package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.support.*;
import com.github.yulichang.toolkit.support.IdeaProxyLambdaMeta;
import com.github.yulichang.toolkit.support.LambdaMeta;
import com.github.yulichang.toolkit.support.ReflectLambdaMeta;
import com.github.yulichang.toolkit.support.ShadowLambdaMeta;
import org.apache.ibatis.reflection.property.PropertyNamer;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;
/**
* copy {@link com.baomidou.mybatisplus.core.toolkit.LambdaUtils}
*/
@SuppressWarnings("unused")
public final class LambdaUtils {
public static <T> String getName(SFunction<T, ?> fn) {
LambdaMeta extract = extract(fn);
String name = PropertyNamer.methodToProperty(extract.getImplMethodName());
if (Character.isUpperCase(name.charAt(0))) {
Map<String, FieldCache> map = MPJReflectionKit.getFieldMap(extract.getInstantiatedClass());
if (map.containsKey(name)) {
return name;
} else {
return map.keySet().stream().filter(i -> i.equalsIgnoreCase(name)).findFirst().orElse(null);
}
}
return name;
return PropertyNamer.methodToProperty(extract.getImplMethodName());
}
@ -50,10 +43,11 @@ public final class LambdaUtils {
// 2. 反射读取
try {
Method method = func.getClass().getDeclaredMethod("writeReplace");
return new ReflectLambdaMeta((java.lang.invoke.SerializedLambda) ReflectionKit.setAccessible(method).invoke(func));
method.setAccessible(true);
return new ReflectLambdaMeta((SerializedLambda) method.invoke(func), func.getClass().getClassLoader());
} catch (Throwable e) {
// 3. 反射失败使用序列化的方式读取
return new ShadowLambdaMeta(SerializedLambda.extract(func));
return new ShadowLambdaMeta(com.github.yulichang.toolkit.support.SerializedLambda.extract(func));
}
}
}

View File

@ -53,8 +53,7 @@ public class LogicInfoUtils implements Constants {
private static String getLogicStr(String prefix, Class<?> clazz, boolean and, boolean invert) {
String logicStr;
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
TableInfo tableInfo = TableHelper.getAssert(clazz);
TableFieldInfo logicField = ConfigProperties.tableInfoAdapter.mpjGetLogicField(tableInfo);
if (ConfigProperties.tableInfoAdapter.mpjHasLogic(tableInfo) && Objects.nonNull(logicField)) {
final String notDeleteValue = logicField.getLogicNotDeleteValue();

View File

@ -8,11 +8,10 @@ import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 反射工具类
@ -23,7 +22,8 @@ import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("unused")
public final class MPJReflectionKit {
private static final Map<Class<?>, Map<String, FieldCache>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();
private static final Map<Class<?>, FieldStringMap<FieldCache>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();
private static final Map<Class<?>, List<FieldCache>> CLASS_FIELD_LIST_CACHE = new ConcurrentHashMap<>();
private static final Map<String, FieldCache> EMPTY_MAP = new HashMap<>();
@ -77,28 +77,32 @@ public final class MPJReflectionKit {
* @param clazz 反射类
*/
public static Map<String, FieldCache> getFieldMap(Class<?> clazz) {
return CLASS_FIELD_CACHE.computeIfAbsent(clazz, key -> getFieldList(key).stream().collect(Collectors.toMap(f ->
f.getField().getName().toUpperCase(Locale.ENGLISH), Function.identity(), (o, n) -> n, FieldStringMap::new)));
}
public static List<FieldCache> getFieldList(Class<?> clazz) {
if (clazz == null) {
return EMPTY_MAP;
return Collections.emptyList();
}
Map<String, FieldCache> fieldMap = CLASS_FIELD_CACHE.get(clazz);
if (fieldMap != null) {
return fieldMap;
List<FieldCache> fieldList = CLASS_FIELD_LIST_CACHE.get(clazz);
if (fieldList != null) {
return fieldList;
}
Map<String, Field> map = ReflectionKit.getFieldMap(clazz);
Map<String, FieldCache> cache = new HashMap<>();
map.forEach((key, value) -> {
List<Field> list = ReflectionKit.getFieldList(clazz);
List<FieldCache> cache = list.stream().map(f -> {
FieldCache fieldCache = new FieldCache();
fieldCache.setField(value);
fieldCache.setField(f);
try {
Reflector reflector = new Reflector(clazz);
Class<?> getterType = reflector.getGetterType(key);
fieldCache.setType(Objects.isNull(getterType) ? value.getType() : getterType);
Class<?> getterType = reflector.getGetterType(f.getName());
fieldCache.setType(Objects.isNull(getterType) ? f.getType() : getterType);
} catch (Throwable throwable) {
fieldCache.setType(value.getType());
fieldCache.setType(f.getType());
}
cache.put(key, fieldCache);
});
CLASS_FIELD_CACHE.put(clazz, cache);
return fieldCache;
}).collect(Collectors.toList());
CLASS_FIELD_LIST_CACHE.put(clazz, cache);
return cache;
}

View File

@ -598,10 +598,25 @@ public final class MPJStringUtils {
/**
* 过滤sql黑名单字符存在 SQL 注入去除空白内容
*/
Matcher matcher = REPLACE_BLANK.matcher(str);
str = matcher.replaceAll("");
str = replaceAllBlank(str);
}
return str;
}
/**
* 字符串去除空白内容
* <ul>
* <li>\n 回车</li>
* <li>\t 水平制表符</li>
* <li>\s 空格</li>
* <li>\r 换行</li>
* </ul>
*
* @param str 字符串
*/
public static String replaceAllBlank(String str) {
Matcher matcher = REPLACE_BLANK.matcher(str);
return matcher.replaceAll("");
}
}

View File

@ -13,7 +13,7 @@ import com.github.yulichang.wrapper.MPJLambdaWrapper;
public class MPJWrappers {
/**
* MPJWrappers.<UserDO>queryJoin()
* MPJWrappers.&lt;UserDO&gt;query()
*/
public static <T> MPJQueryWrapper<T> queryJoin() {
return new MPJQueryWrapper<>();
@ -28,7 +28,7 @@ public class MPJWrappers {
}
/**
* MPJWrappers.<UserDO>lambdaJoin()
* MPJWrappers.&lt;UserDO&gt;lambda()
*/
public static <T> MPJLambdaWrapper<T> lambdaJoin() {
return new MPJLambdaWrapper<>();

View File

@ -0,0 +1,9 @@
package com.github.yulichang.toolkit;
/**
* @author yulichang
* @since 1.4.7.2
*/
@SuppressWarnings("unused")
public class Ref<T> {
}

View File

@ -20,10 +20,8 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.toolkit.reflect.GenericTypeUtils;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@ -142,11 +140,11 @@ public final class ReflectionKit {
* 中间表实体重写父类属性 ` private transient Date createTime; `
*/
return fieldMap.values().stream()
/* 过滤静态属性 */
.filter(f -> !Modifier.isStatic(f.getModifiers()))
/* 过滤 transient关键字修饰的属性 */
.filter(f -> !Modifier.isTransient(f.getModifiers()))
.collect(Collectors.toList());
/* 过滤静态属性 */
.filter(f -> !Modifier.isStatic(f.getModifiers()))
/* 过滤 transient关键字修饰的属性 */
.filter(f -> !Modifier.isTransient(f.getModifiers()))
.collect(Collectors.toList());
});
}
@ -161,12 +159,12 @@ public final class ReflectionKit {
public static Map<String, Field> excludeOverrideSuperField(Field[] fields, List<Field> superFieldList) {
// 子类属性
Map<String, Field> fieldMap = Stream.of(fields).collect(toMap(Field::getName, identity(),
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new));
(u, v) -> {
throw new IllegalStateException(String.format("Duplicate key %s", u));
},
LinkedHashMap::new));
superFieldList.stream().filter(field -> !fieldMap.containsKey(field.getName()))
.forEach(f -> fieldMap.put(f.getName(), f));
.forEach(f -> fieldMap.put(f.getName(), f));
return fieldMap;
}
@ -186,17 +184,6 @@ public final class ReflectionKit {
return (clazz.isPrimitive() && clazz != void.class ? PRIMITIVE_TYPE_TO_WRAPPER_MAP.get(clazz) : clazz);
}
/**
* 设置可访问对象的可访问权限为 true
*
* @param object 可访问的对象
* @param <T> 类型
* @return 返回设置后的对象
*/
public static <T extends AccessibleObject> T setAccessible(T object) {
return AccessController.doPrivileged(new SetAccessibleAction<>(object));
}
public static <K, V> V computeIfAbsent(Map<K, V> concurrentHashMap, K key, Function<? super K, ? extends V> mappingFunction) {
V v = concurrentHashMap.get(key);
if (v != null) {

View File

@ -4,9 +4,12 @@ package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.ibatis.session.SqlSession;
import java.util.Objects;
import java.util.Optional;
/**
* spring容器工具类
@ -14,19 +17,26 @@ import java.util.Objects;
* @author yulichang
* @since 1.2.0
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class SpringContentUtils {
private static SpringContext springContext;
public SpringContentUtils(SpringContext springContext) {
SpringContentUtils.springContext = springContext;
public static void setSpringContext(SpringContext springContext) {
if (Objects.isNull(SpringContentUtils.springContext)) {
SpringContentUtils.springContext = springContext;
}
}
public static <T> T getBean(Class<T> clazz) {
return SpringContentUtils.springContext.getBean(clazz);
return Optional.ofNullable(springContext).map(c -> c.getBean(clazz)).orElse(null);
}
@SuppressWarnings("unchecked")
public static <T> void getBeansOfType(Class<T> clazz) {
Optional.ofNullable(springContext).ifPresent(c -> c.getBeansOfType(clazz));
}
@SuppressWarnings({"unchecked", "deprecation"})
public static <T> T getMapper(Class<?> clazz) {
if (Objects.isNull(springContext)) {
SqlSession session = SqlHelper.sqlSession(clazz);
@ -45,5 +55,7 @@ public class SpringContentUtils {
public interface SpringContext {
<T> T getBean(Class<T> clazz);
<T> void getBeansOfType(Class<T> clazz);
}
}

View File

@ -1,6 +1,5 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.github.yulichang.base.MPJBaseMapper;
@ -12,17 +11,10 @@ import java.util.function.Function;
* @since 1.4.4
*/
@SuppressWarnings("unchecked")
public class SqlHelper {
public final class SqlHelper {
public static <R, T> R exec(Class<T> entityClass, Function<BaseMapper<T>, R> function) {
Assert.notNull(entityClass,"请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
Object mapper = SpringContentUtils.getMapper(entityClass);
Assert.notNull(mapper, "mapper not init <%s>", entityClass.getSimpleName());
return function.apply((BaseMapper<T>) mapper);
}
public static <R, T> R execJoin(Class<T> entityClass, Function<MPJBaseMapper<T>, R> function) {
Assert.notNull(entityClass,"请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
public static <R, T> R exec(Class<T> entityClass, Function<MPJBaseMapper<T>, R> function) {
Assert.notNull(entityClass, "请使用 new MPJLambdaWrapper(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
Object mapper = SpringContentUtils.getMapper(entityClass);
Assert.notNull(mapper, "mapper not init <%s>", entityClass.getSimpleName());
Assert.isTrue(mapper instanceof MPJBaseMapper, "mapper <%s> not extends MPJBaseMapper ", entityClass.getSimpleName());

View File

@ -1,8 +1,10 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.github.yulichang.config.MPJInterceptorConfig;
import java.util.Map;
import java.util.Objects;
@ -14,6 +16,8 @@ import java.util.concurrent.ConcurrentHashMap;
*/
public class TableHelper {
private static boolean load = false;
private static final Map<Class<?>, TableInfo> TABLE_INFO_CACHE = new ConcurrentHashMap<>();
public static void init(Class<?> newClass, Class<?> oldClass) {
@ -46,10 +50,24 @@ public class TableHelper {
}
if (Objects.nonNull(info)) {
TABLE_INFO_CACHE.put(currentClass, info);
} else {
if (!load) {
SpringContentUtils.getBean(MPJInterceptorConfig.class);
SpringContentUtils.getBeansOfType(BaseMapper.class);
load = true;
return get(clazz);
}
}
return info;
} else {
return null;
}
}
public static TableInfo getAssert(Class<?> clazz) {
Objects.requireNonNull(clazz);
TableInfo tableInfo = get(clazz);
Asserts.hasTable(tableInfo, clazz);
return tableInfo;
}
}

View File

@ -0,0 +1,57 @@
package com.github.yulichang.toolkit;
import java.util.Objects;
import java.util.function.Consumer;
/**
* @author yulichang
* @since 1.4.9
*/
@SuppressWarnings("unused")
public class ThrowOptional {
private ThrowOptional() {
}
private DoSomething doSomething;
public static ThrowOptional tryDo(DoSomething doSomething) {
ThrowOptional optional = new ThrowOptional();
Objects.requireNonNull(doSomething);
optional.doSomething = doSomething;
return optional;
}
public void catchDo() {
try {
this.doSomething.doSomething();
} catch (Throwable ignored) {
}
}
public void catchDo(DoSomething doSomething) {
try {
this.doSomething.doSomething();
} catch (Throwable ignored) {
try {
doSomething.doSomething();
} catch (Throwable e) {
throw new RuntimeException(e);
}
}
}
public void catchDo(Consumer<Throwable> consumer) {
try {
this.doSomething.doSomething();
} catch (Throwable throwable) {
consumer.accept(throwable);
}
}
@FunctionalInterface
public interface DoSomething {
void doSomething() throws Throwable;
}
}

View File

@ -20,8 +20,7 @@ import java.util.Optional;
public class WrapperUtils {
public static <T> String buildSubSqlByWrapper(Class<T> clazz, MPJLambdaWrapper<T> wrapper, String alias) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
TableInfo tableInfo = TableHelper.getAssert(clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
@ -43,7 +42,7 @@ public class WrapperUtils {
return String.format(" (%s SELECT %s FROM %s %s %s %s %s %s %s) AS %s ",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
wrapper.getTableName(tableInfo.getTableName()),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
@ -54,8 +53,7 @@ public class WrapperUtils {
}
public static String buildUnionSqlByWrapper(Class<?> clazz, MPJLambdaWrapper<?> wrapper) {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, clazz);
TableInfo tableInfo = TableHelper.getAssert(clazz);
String first = Optional.ofNullable(wrapper.getSqlFirst()).orElse(StringPool.EMPTY);
boolean hasWhere = false;
String entityWhere = getEntitySql(tableInfo, wrapper);
@ -77,7 +75,7 @@ public class WrapperUtils {
return String.format(" %s SELECT %s FROM %s %s %s %s %s %s %s ",
first,
wrapper.getSqlSelect(),
tableInfo.getTableName(),
wrapper.getTableName(tableInfo.getTableName()),
wrapper.getAlias(),
wrapper.getFrom(),
mainLogic,
@ -100,7 +98,7 @@ public class WrapperUtils {
}
StringBuilder sb = new StringBuilder(StringPool.EMPTY);
for (TableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
if (AdapterHelper.getAdapter().mpjHasLogic(tableInfo) && fieldInfo.isLogicDelete()) {
continue;
}
Object val;
@ -124,6 +122,9 @@ public class WrapperUtils {
}
private static String mainLogic(boolean hasWhere, Class<?> clazz, MPJLambdaWrapper<?> wrapper) {
if (!wrapper.getLogicSql()) {
return StringPool.EMPTY;
}
String info = LogicInfoUtils.getLogicInfo(null, clazz, true, wrapper.getAlias());
if (StringUtils.isNotBlank(info)) {
if (hasWhere) {

View File

@ -2,12 +2,13 @@ package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.FieldStringMap;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.wrapper.segments.SelectCache;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
@ -23,15 +24,15 @@ public class ColumnCache {
private static final Map<Class<?>, List<SelectCache>> LIST_CACHE = new ConcurrentHashMap<>();
private static final Map<Class<?>, Map<String, SelectCache>> MAP_CACHE = new ConcurrentHashMap<>();
private static final Map<Class<?>, FieldStringMap<SelectCache>> MAP_CACHE = new ConcurrentHashMap<>();
public static List<SelectCache> getListField(Class<?> clazz) {
return LIST_CACHE.computeIfAbsent(clazz, c -> {
TableInfo tableInfo = TableHelper.get(clazz);
Asserts.hasTable(tableInfo, c);
TableInfo tableInfo = TableHelper.getAssert(clazz);
List<SelectCache> list = new ArrayList<>();
if (ConfigProperties.tableInfoAdapter.mpjHasPK(tableInfo)) {
list.add(new SelectCache(clazz, true, tableInfo.getKeyColumn(), tableInfo.getKeyType(), tableInfo.getKeyProperty(), null));
list.add(new SelectCache(clazz, true, tableInfo.getKeyColumn(), tableInfo.getKeyType(),
tableInfo.getKeyProperty(), null));
}
list.addAll(tableInfo.getFieldList().stream().filter(TableFieldInfo::isSelect).map(f -> new SelectCache(clazz, false, f.getColumn(), f.getPropertyType(), f.getProperty(), f)).collect(Collectors.toList()));
return list;
@ -39,6 +40,8 @@ public class ColumnCache {
}
public static Map<String, SelectCache> getMapField(Class<?> clazz) {
return MAP_CACHE.computeIfAbsent(clazz, c -> getListField(c).stream().collect(Collectors.toMap(SelectCache::getColumProperty, Function.identity(), (i, j) -> j)));
return MAP_CACHE.computeIfAbsent(clazz, c -> getListField(c).stream().collect(Collectors.toMap(
i -> i.getColumProperty().toUpperCase(Locale.ENGLISH),
Function.identity(), (i, j) -> j, FieldStringMap::new)));
}
}

View File

@ -15,11 +15,10 @@
*/
package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandleProxies;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Executable;
import java.lang.reflect.Proxy;
/**
@ -28,35 +27,14 @@ import java.lang.reflect.Proxy;
* Create by hcl at 2021/5/17
*/
public class IdeaProxyLambdaMeta implements LambdaMeta {
private static final Field FIELD_MEMBER_NAME;
private static final Field FIELD_MEMBER_NAME_CLAZZ;
private static final Field FIELD_MEMBER_NAME_NAME;
static {
try {
Class<?> classDirectMethodHandle = Class.forName("java.lang.invoke.DirectMethodHandle");
FIELD_MEMBER_NAME = ReflectionKit.setAccessible(classDirectMethodHandle.getDeclaredField("member"));
Class<?> classMemberName = Class.forName("java.lang.invoke.MemberName");
FIELD_MEMBER_NAME_CLAZZ = ReflectionKit.setAccessible(classMemberName.getDeclaredField("clazz"));
FIELD_MEMBER_NAME_NAME = ReflectionKit.setAccessible(classMemberName.getDeclaredField("name"));
} catch (ClassNotFoundException | NoSuchFieldException e) {
throw new MybatisPlusException(e);
}
}
private final Class<?> clazz;
private final String name;
public IdeaProxyLambdaMeta(Proxy func) {
InvocationHandler handler = Proxy.getInvocationHandler(func);
try {
Object dmh = ReflectionKit.setAccessible(handler.getClass().getDeclaredField("val$target")).get(handler);
Object member = FIELD_MEMBER_NAME.get(dmh);
clazz = (Class<?>) FIELD_MEMBER_NAME_CLAZZ.get(member);
name = (String) FIELD_MEMBER_NAME_NAME.get(member);
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new MybatisPlusException(e);
}
MethodHandle dmh = MethodHandleProxies.wrapperInstanceTarget(func);
Executable executable = MethodHandles.reflectAs(Executable.class, dmh);
clazz = executable.getDeclaringClass();
name = executable.getName();
}
@Override

View File

@ -16,36 +16,22 @@
package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.toolkit.ClassUtils;
import com.github.yulichang.toolkit.ReflectionKit;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
/**
* Created by hcl at 2021/5/14
*/
public class ReflectLambdaMeta implements LambdaMeta {
private static final Field FIELD_CAPTURING_CLASS;
static {
Field fieldCapturingClass;
try {
Class<SerializedLambda> aClass = SerializedLambda.class;
fieldCapturingClass = ReflectionKit.setAccessible(aClass.getDeclaredField("capturingClass"));
} catch (Throwable e) {
// 解决高版本 jdk 的问题 gitee: https://gitee.com/baomidou/mybatis-plus/issues/I4A7I5
fieldCapturingClass = null;
}
FIELD_CAPTURING_CLASS = fieldCapturingClass;
}
private final SerializedLambda lambda;
public ReflectLambdaMeta(SerializedLambda lambda) {
private final ClassLoader classLoader;
public ReflectLambdaMeta(SerializedLambda lambda, ClassLoader classLoader) {
this.lambda = lambda;
this.classLoader = classLoader;
}
@Override
@ -57,19 +43,7 @@ public class ReflectLambdaMeta implements LambdaMeta {
public Class<?> getInstantiatedClass() {
String instantiatedMethodType = lambda.getInstantiatedMethodType();
String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(StringPool.SEMICOLON)).replace(StringPool.SLASH, StringPool.DOT);
return ClassUtils.toClassConfident(instantiatedType, getCapturingClassClassLoader());
}
private ClassLoader getCapturingClassClassLoader() {
// 如果反射失败使用默认的 classloader
if (FIELD_CAPTURING_CLASS == null) {
return null;
}
try {
return ((Class<?>) FIELD_CAPTURING_CLASS.get(lambda)).getClassLoader();
} catch (IllegalAccessException e) {
throw new MybatisPlusException(e);
}
return ClassUtils.toClassConfident(instantiatedType, this.classLoader);
}
}

View File

@ -5,10 +5,10 @@ import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.toolkit.Asserts;
import com.github.yulichang.toolkit.LogicInfoUtils;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.TableList;
import com.github.yulichang.wrapper.interfaces.DeleteChain;
import java.util.ArrayList;
import java.util.Arrays;
@ -21,7 +21,7 @@ import java.util.stream.Collectors;
* @author yulichang
* @since 1.4.5
*/
public class DeleteJoinWrapper<T> extends MPJAbstractLambdaWrapper<T, DeleteJoinWrapper<T>> {
public class DeleteJoinWrapper<T> extends JoinAbstractLambdaWrapper<T, DeleteJoinWrapper<T>> implements DeleteChain<T> {
/**
* 删除表
@ -100,6 +100,7 @@ public class DeleteJoinWrapper<T> extends MPJAbstractLambdaWrapper<T, DeleteJoin
* 获取删除的表
*/
@Override
@SuppressWarnings("DuplicatedCode")
public String getDeleteLogicSql() {
if (StringUtils.isNotBlank(this.deleteSql.getStringValue())) {
return this.deleteSql.getStringValue();
@ -153,6 +154,7 @@ public class DeleteJoinWrapper<T> extends MPJAbstractLambdaWrapper<T, DeleteJoin
/**
* 删除表
*/
@SuppressWarnings("DuplicatedCode")
public DeleteJoinWrapper<T> delete(Class<?>... deleteClass) {
Class<T> entityClass = getEntityClass();
Assert.notNull(entityClass, "缺少主表类型, 请使用 new MPJLambdaWrapper<>(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");
@ -164,28 +166,28 @@ public class DeleteJoinWrapper<T> extends MPJAbstractLambdaWrapper<T, DeleteJoin
return typedThis;
}
@SuppressWarnings("DuplicatedCode")
private void check(List<Class<?>> classList) {
Class<T> entityClass = getEntityClass();
TableInfo tableInfo = TableHelper.get(entityClass);
Asserts.hasTable(tableInfo, entityClass);
TableInfo tableInfo = TableHelper.getAssert(entityClass);
//检查
boolean mainLogic = AdapterHelper.getTableInfoAdapter().mpjHasLogic(tableInfo);
boolean mainLogic = AdapterHelper.getAdapter().mpjHasLogic(tableInfo);
boolean check = classList.stream().allMatch(t -> {
TableInfo ti = TableHelper.get(t);
Asserts.hasTable(ti, t);
return mainLogic == AdapterHelper.getTableInfoAdapter().mpjHasLogic(ti);
TableInfo ti = TableHelper.getAssert(t);
return mainLogic == AdapterHelper.getAdapter().mpjHasLogic(ti);
});
if (!check) {
throw ExceptionUtils.mpe("连表删除只适用于全部表(主表和副表)都是物理删除或全部都是逻辑删除, " +
"不支持同时存在物理删除和逻辑删除 [物理删除->(%s)] [逻辑删除->(%s)]",
classList.stream().filter(t -> !AdapterHelper.getTableInfoAdapter().mpjHasLogic(TableHelper.get(t)))
classList.stream().filter(t -> !AdapterHelper.getAdapter().mpjHasLogic(TableHelper.getAssert(t)))
.map(Class::getSimpleName).collect(Collectors.joining(StringPool.COMMA)),
classList.stream().filter(t -> AdapterHelper.getTableInfoAdapter().mpjHasLogic(TableHelper.get(t)))
classList.stream().filter(t -> AdapterHelper.getAdapter().mpjHasLogic(TableHelper.getAssert(t)))
.map(Class::getSimpleName).collect(Collectors.joining(StringPool.COMMA)));
}
}
private void check(){
@SuppressWarnings("DuplicatedCode")
private void check() {
if (CollectionUtils.isNotEmpty(tableList.getAll())) {
Class<T> entityClass = getEntityClass();
Assert.notNull(entityClass, "缺少主表类型, 请使用 new MPJLambdaWrapper<>(主表.class) 或 JoinWrappers.lambda(主表.class) 构造方法");

Some files were not shown because too many files have changed in this diff Show More