mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 09:08:24 +08:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
d32f3ec83d
15
changes.txt
15
changes.txt
@ -1,3 +1,18 @@
|
||||
mybatis-flex v1.4.1 20230620:
|
||||
新增:分页查询 Page 对象添加否优化 count 查询的选项,感谢 @王帅
|
||||
新增:添加 LogicDeleteProcessor.java 用于构建自定义的逻辑删除功能
|
||||
优化:完善后添加类的相关注释、版权信息等内容,感谢 @王帅
|
||||
优化:QueryColumn 添加构造方法 QueryColumn(String tableName, String name)
|
||||
修复:Oracle 下的 as 关键字错误的问题
|
||||
修复:多表联查时,逻辑删除字段和租户字段,只过滤主表,未过滤子表的问题 #I7EV67
|
||||
修复:低版本 spring-cloud 使用 bootstrap.yml 拉取不到 nacos 中多数据源配置的问题,感谢 @王帅
|
||||
修复:使用 druid-spring-boot-starter 时 mybatis-flex 多数据源不生效,感谢 @王帅
|
||||
文档:更新 APT 文档,添加实体类不在同一个包说明,感谢 @王帅
|
||||
文档:添加找不到依赖 faq 说明,感谢 @王帅
|
||||
文档:逻辑删除添加关于 LogicDeleteProcessor 的相关文档
|
||||
|
||||
|
||||
|
||||
mybatis-flex v1.4.0 20230618:
|
||||
新增:LogicDeleteManager,用于处理跳过逻辑删除的场景
|
||||
新增:BaseMapper 新增 insertWithPk 方法,用于插入带有主键的 Entity 数据
|
||||
|
||||
@ -54,6 +54,51 @@ SELECT * FROM tb_account where id = ? and is_delete = 0
|
||||
- selectCountBy**
|
||||
- paginate
|
||||
|
||||
同时,比如 Left Join 或者子查询等,若 **子表也设置了逻辑删除字段**, 那么子表也会添加相应的逻辑删除条件,例如:
|
||||
|
||||
```java
|
||||
QueryWrapper query1 = QueryWrapper.create()
|
||||
.select()
|
||||
.from(ACCOUNT)
|
||||
.leftJoin(ARTICLE).as("a").on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
|
||||
.where(ACCOUNT.AGE.ge(10));
|
||||
```
|
||||
其执行的 SQL 如下:
|
||||
|
||||
```sql
|
||||
SELECT * FROM `tb_account`
|
||||
LEFT JOIN `tb_article` AS `a` ON `tb_account`.`id` = `a`.`account_id`
|
||||
WHERE `tb_account`.`age` >= 10
|
||||
AND `tb_account`.`is_delete` = 0 AND `a`.`is_delete` = 0
|
||||
```
|
||||
自动添加上 `tb_account.is_delete = 0 AND a.is_delete = 0` 条件。
|
||||
|
||||
示例 2:
|
||||
|
||||
```java
|
||||
QueryWrapper query2 = QueryWrapper.create()
|
||||
.select()
|
||||
.from(ACCOUNT)
|
||||
.leftJoin(
|
||||
//子查询
|
||||
select().from(ARTICLE).where(ARTICLE.ID.ge(100))
|
||||
).as("a").on(
|
||||
ACCOUNT.ID.eq(raw("a.id"))
|
||||
)
|
||||
.where(ACCOUNT.AGE.ge(10));
|
||||
```
|
||||
其执行的 SQL 如下:
|
||||
|
||||
```sql
|
||||
SELECT * FROM `tb_account`
|
||||
LEFT JOIN (
|
||||
SELECT * FROM `tb_article` WHERE `id` >= 100 AND `is_delete` = 0
|
||||
) AS `a`
|
||||
ON `tb_account`.`id` = a.id
|
||||
WHERE `tb_account`.`age` >= 10 AND `tb_account`.`is_delete` = 0
|
||||
```
|
||||
|
||||
|
||||
## 逻辑删除的默认值配置
|
||||
|
||||
在某些场景下,我们可能希望数据库存入的逻辑删除中的值并非 0 和 1,比如可能是 true 和 false 等,那么,我们可以通过配置 `FlexGlobalConfig`
|
||||
@ -81,4 +126,39 @@ LogicDeleteManager.execWithoutLogicDelete(() ->
|
||||
accountMapper.deleteById(1)
|
||||
);
|
||||
```
|
||||
以上代码中,`accountMapper` 会直接对 `Account` 数据进行物理删除,忽略逻辑删除字段配置。
|
||||
以上代码中,`accountMapper` 会直接对 `Account` 数据进行物理删除,忽略逻辑删除字段配置。
|
||||
|
||||
## 自定义逻辑删除处理功能
|
||||
|
||||
在社区中,有许多用户提出希望使用时间类型,当删除时,设置删除字段为`当前时间`,当正常时,设置为 `0` 或者 `null`。
|
||||
那么,我们可以通过 `LogicDeleteManager` 设置一个新的 `LogicDeleteProcessor`:
|
||||
|
||||
`LogicDeleteProcessor` 接口的内容如下:
|
||||
|
||||
```java
|
||||
public interface LogicDeleteProcessor {
|
||||
|
||||
/**
|
||||
* 用户构建查询正常数据的条件
|
||||
* @param logicColumn
|
||||
* @param dialect
|
||||
*/
|
||||
String buildLogicNormalCondition(String logicColumn, IDialect dialect);
|
||||
|
||||
/**
|
||||
* 用户与构建删除数据时的内容
|
||||
* @param logicColumn
|
||||
* @param dialect
|
||||
*/
|
||||
String buildLogicDeletedSet(String logicColumn, IDialect dialect);
|
||||
|
||||
/**
|
||||
* 用于构建通过 QueryWrapper 查询数据时的内容
|
||||
* @param queryWrapper
|
||||
* @param tableInfo
|
||||
*/
|
||||
void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo);
|
||||
}
|
||||
```
|
||||
|
||||
具体实现可以参考:[DefaultLogicDeleteProcessorImpl](https://gitee.com/mybatis-flex/mybatis-flex/blob/main/mybatis-flex-core/src/main/java/com/mybatisflex/core/logicdelete/DefaultLogicDeleteProcessorImpl.java)
|
||||
@ -8,7 +8,7 @@ MyBatis-Flex 使用了 APT 技术,这两个类是自动生成的。
|
||||
## 阿里镜像找不到依赖?
|
||||
|
||||
```txt
|
||||
Could not find artifact com.mybatis-flex:mybatis-flex-spring-boot-starter:pom:1.4.0
|
||||
Could not find artifact com.mybatis-flex:mybatis-flex-spring-boot-starter:pom:1.4.1
|
||||
in alimaven (http://maven.aliyun.com/nexus/content/groups/public/)
|
||||
```
|
||||
|
||||
@ -43,9 +43,7 @@ in alimaven (http://maven.aliyun.com/nexus/content/groups/public/)
|
||||
HikariCP 的 5.x 版本。
|
||||
- 2、主动添加了 MyBatis 或者 `mybatis-spring-boot-starter` 的依赖,导致版本不匹配。使用 SpringBoot
|
||||
的情况下,应该引用 `mybatis-flex-spring-boot-starter` 就可以了,不需要再添加其他 MyBatis 依赖。
|
||||
- 3、使用了 `druid-spring-boot-starter` 依赖,导致 flex 的 DataSource 无法被接管。应该使用 `druid`
|
||||
就可以了,不要用 `druid-spring-boot-starter`。
|
||||
- 4、使用了 `MyBatis-Plus` 或者 `pagehelper-spring-boot-starter` 而被这些框架优先初始化 MyBatis, MyBatis-Flex 未得到初始化。
|
||||
- 3、使用了 `MyBatis-Plus` 或者 `pagehelper-spring-boot-starter` 而被这些框架优先初始化 MyBatis, MyBatis-Flex 未得到初始化。
|
||||
|
||||
## SpringBoot 项目,启动报错 Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
|
||||
|
||||
@ -126,31 +124,6 @@ spring:
|
||||
> 若把数据源配置到 `mybatis-flex.datasource` 下,使用 mybatis-flex 的数据源发现机制,
|
||||
> 使用 druid 则可以不用配置 type,更多文档参考:[多数据源章节](./core/multi-datasource.md)。
|
||||
|
||||
## 使用 `druid-spring-boot-starter`,出现无法启动 或者 数据源识别错误的问题
|
||||
|
||||
在 MyBatis-Flex 不能使用 "druid-spring-boot-starter" 依赖,只能使用 "druid" 。
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid-spring-boot-starter</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
需要把以上的依赖,修改如下:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
> 原因是:druid-spring-boot-starter 内的 DruidDataSourceAutoConfigure 会去自动加载 spring.datasource 下的配置,当使用 MyBatis-Flex 的多数据源时,
|
||||
> 这个配置已经不存在了。
|
||||
|
||||
## 与 PageHelper 集成出现错误
|
||||
|
||||
在社区中,一些老的项目在使用到了开源项目 PageHelper,用于解决 xml 的分页问题,在和 MyBatis-flex 整合使用中,出现了一些错误,
|
||||
|
||||
@ -27,12 +27,12 @@ Maven示例:
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@ -46,7 +46,7 @@ Gradle示例:
|
||||
```groovy
|
||||
// file: build.gradle
|
||||
ext {
|
||||
mybatis_flex_version = '1.4.0'
|
||||
mybatis_flex_version = '1.4.1'
|
||||
}
|
||||
dependencies {
|
||||
implementation("com.mybatis-flex:mybatis-flex-core:${mybatis_flex_version}")
|
||||
|
||||
@ -12,12 +12,12 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@ -28,12 +28,12 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
``````
|
||||
@ -44,12 +44,12 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
@ -70,7 +70,7 @@
|
||||
<path>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
|
||||
@ -214,7 +214,7 @@ pom.xml 添加 `annotationProcessorPaths` 配置,
|
||||
```
|
||||
dependencies {
|
||||
...
|
||||
annotationProcessor 'com.mybatis-flex:mybatis-flex-processor:1.4.0'
|
||||
annotationProcessor 'com.mybatis-flex:mybatis-flex-processor:1.4.1'
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-codegen</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -22,13 +22,13 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-annotation</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -676,7 +676,7 @@ public interface BaseMapper<T> {
|
||||
// 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的
|
||||
if (page.getTotalRow() < 0) {
|
||||
QueryWrapper countQueryWrapper;
|
||||
if (page.isOptimizeCountSql()) {
|
||||
if (page.needOptimizeCountQuery()) {
|
||||
countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper);
|
||||
} else {
|
||||
countQueryWrapper = MapperUtil.rawCountQueryWrapper(queryWrapper);
|
||||
@ -688,7 +688,7 @@ public interface BaseMapper<T> {
|
||||
return page;
|
||||
}
|
||||
|
||||
queryWrapper.limit(page.getOffset(), page.getPageSize());
|
||||
queryWrapper.limit(page.offset(), page.getPageSize());
|
||||
|
||||
List<R> records;
|
||||
if (asType != null) {
|
||||
|
||||
@ -23,7 +23,7 @@ public class FlexConsts {
|
||||
private FlexConsts() {}
|
||||
|
||||
public static final String NAME = "MyBatis-Flex";
|
||||
public static final String VERSION = "1.4.0";
|
||||
public static final String VERSION = "1.4.1";
|
||||
|
||||
public static final String DEFAULT_PRIMARY_FIELD = "id";
|
||||
|
||||
|
||||
@ -15,11 +15,11 @@
|
||||
*/
|
||||
package com.mybatisflex.core.dialect.impl;
|
||||
|
||||
import com.mybatisflex.core.FlexGlobalConfig;
|
||||
import com.mybatisflex.core.dialect.IDialect;
|
||||
import com.mybatisflex.core.dialect.KeywordWrap;
|
||||
import com.mybatisflex.core.dialect.LimitOffsetProcessor;
|
||||
import com.mybatisflex.core.exception.FlexExceptions;
|
||||
import com.mybatisflex.core.logicdelete.LogicDeleteManager;
|
||||
import com.mybatisflex.core.query.*;
|
||||
import com.mybatisflex.core.row.Row;
|
||||
import com.mybatisflex.core.row.RowCPI;
|
||||
@ -491,7 +491,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
|
||||
@Override
|
||||
public String forDeleteEntityById(TableInfo tableInfo) {
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip();
|
||||
Object[] tenantIdArgs = tableInfo.buildTenantIdArgs();
|
||||
//正常删除
|
||||
if (StringUtil.isBlank(logicDeleteColumn)) {
|
||||
@ -508,7 +508,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
String[] primaryKeys = tableInfo.getPrimaryKeys();
|
||||
|
||||
sql.append(UPDATE).append(tableInfo.getWrapSchemaAndTableName(this));
|
||||
sql.append(SET).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicDeletedValue());
|
||||
sql.append(SET).append(buildLogicDeletedSet(logicDeleteColumn));
|
||||
sql.append(WHERE);
|
||||
for (int i = 0; i < primaryKeys.length; i++) {
|
||||
if (i > 0) {
|
||||
@ -517,7 +517,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
sql.append(wrap(primaryKeys[i])).append(EQUALS_PLACEHOLDER);
|
||||
}
|
||||
|
||||
sql.append(AND).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicNormalValue());
|
||||
sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn));
|
||||
|
||||
//租户ID
|
||||
if (ArrayUtil.isNotEmpty(tenantIdArgs)) {
|
||||
@ -530,7 +530,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
|
||||
@Override
|
||||
public String forDeleteEntityBatchByIds(TableInfo tableInfo, Object[] primaryValues) {
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip();
|
||||
Object[] tenantIdArgs = tableInfo.buildTenantIdArgs();
|
||||
|
||||
//正常删除
|
||||
@ -548,7 +548,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append(UPDATE);
|
||||
sql.append(tableInfo.getWrapSchemaAndTableName(this));
|
||||
sql.append(SET).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicDeletedValue());
|
||||
sql.append(SET).append(buildLogicDeletedSet(logicDeleteColumn));
|
||||
sql.append(WHERE);
|
||||
sql.append(BRACKET_LEFT);
|
||||
|
||||
@ -580,7 +580,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
}
|
||||
}
|
||||
|
||||
sql.append(BRACKET_RIGHT).append(AND).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicNormalValue());
|
||||
sql.append(BRACKET_RIGHT).append(AND).append(buildLogicNormalCondition(logicDeleteColumn));
|
||||
|
||||
if (ArrayUtil.isNotEmpty(tenantIdArgs)) {
|
||||
sql.append(AND).append(wrap(tableInfo.getTenantIdColumn())).append(IN).append(buildQuestion(tenantIdArgs.length));
|
||||
@ -592,7 +592,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
@Override
|
||||
public String forDeleteEntityBatchByQuery(TableInfo tableInfo, QueryWrapper queryWrapper) {
|
||||
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip();
|
||||
|
||||
//正常删除
|
||||
if (StringUtil.isBlank(logicDeleteColumn)) {
|
||||
@ -608,7 +608,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
//ignore selectColumns
|
||||
StringBuilder sqlBuilder = new StringBuilder(UPDATE).append(forHint(CPI.getHint(queryWrapper)));
|
||||
sqlBuilder.append(tableInfo.getWrapSchemaAndTableName(this));
|
||||
sqlBuilder.append(SET).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicDeletedValue());
|
||||
sqlBuilder.append(SET).append(buildLogicDeletedSet(logicDeleteColumn));
|
||||
|
||||
|
||||
buildJoinSql(sqlBuilder, queryWrapper, allTables);
|
||||
@ -661,9 +661,9 @@ public class CommonsDialectImpl implements IDialect {
|
||||
}
|
||||
|
||||
//逻辑删除条件,已删除的数据不能被修改
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip();
|
||||
if (StringUtil.isNotBlank(logicDeleteColumn)) {
|
||||
sql.append(AND).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicNormalValue());
|
||||
sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn));
|
||||
}
|
||||
|
||||
|
||||
@ -812,9 +812,9 @@ public class CommonsDialectImpl implements IDialect {
|
||||
}
|
||||
|
||||
//逻辑删除的情况下,需要添加逻辑删除的条件
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip();
|
||||
if (StringUtil.isNotBlank(logicDeleteColumn)) {
|
||||
sql.append(AND).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicNormalValue());
|
||||
sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn));
|
||||
}
|
||||
|
||||
//多租户
|
||||
@ -834,7 +834,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
sql.append(WHERE);
|
||||
String[] primaryKeys = tableInfo.getPrimaryKeys();
|
||||
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumn();
|
||||
String logicDeleteColumn = tableInfo.getLogicDeleteColumnOrSkip();
|
||||
Object[] tenantIdArgs = tableInfo.buildTenantIdArgs();
|
||||
if (StringUtil.isNotBlank(logicDeleteColumn) || ArrayUtil.isNotEmpty(tenantIdArgs)) {
|
||||
sql.append(BRACKET_LEFT);
|
||||
@ -872,7 +872,7 @@ public class CommonsDialectImpl implements IDialect {
|
||||
|
||||
|
||||
if (StringUtil.isNotBlank(logicDeleteColumn)) {
|
||||
sql.append(AND).append(wrap(logicDeleteColumn)).append(EQUALS).append(getLogicNormalValue());
|
||||
sql.append(AND).append(buildLogicNormalCondition(logicDeleteColumn));
|
||||
}
|
||||
|
||||
if (ArrayUtil.isNotEmpty(tenantIdArgs)) {
|
||||
@ -973,24 +973,14 @@ public class CommonsDialectImpl implements IDialect {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
protected Object getLogicNormalValue() {
|
||||
Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete();
|
||||
if (normalValueOfLogicDelete instanceof Number
|
||||
|| normalValueOfLogicDelete instanceof Boolean) {
|
||||
return normalValueOfLogicDelete;
|
||||
}
|
||||
return SINGLE_QUOTE + normalValueOfLogicDelete + SINGLE_QUOTE;
|
||||
protected String buildLogicNormalCondition(String logicColumn) {
|
||||
return LogicDeleteManager.getProcessor().buildLogicNormalCondition(logicColumn,this);
|
||||
}
|
||||
|
||||
|
||||
protected Object getLogicDeletedValue() {
|
||||
Object deletedValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getDeletedValueOfLogicDelete();
|
||||
if (deletedValueOfLogicDelete instanceof Number
|
||||
|| deletedValueOfLogicDelete instanceof Boolean) {
|
||||
return deletedValueOfLogicDelete;
|
||||
}
|
||||
return SINGLE_QUOTE + deletedValueOfLogicDelete + SINGLE_QUOTE;
|
||||
protected String buildLogicDeletedSet(String logicColumn) {
|
||||
return LogicDeleteManager.getProcessor().buildLogicDeletedSet(logicColumn,this);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.core.logicdelete;
|
||||
|
||||
import com.mybatisflex.core.FlexGlobalConfig;
|
||||
import com.mybatisflex.core.constant.SqlConsts;
|
||||
import com.mybatisflex.core.dialect.IDialect;
|
||||
import com.mybatisflex.core.query.QueryCondition;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.table.TableInfo;
|
||||
|
||||
import static com.mybatisflex.core.constant.SqlConsts.EQUALS;
|
||||
import static com.mybatisflex.core.constant.SqlConsts.SINGLE_QUOTE;
|
||||
|
||||
public class DefaultLogicDeleteProcessorImpl implements LogicDeleteProcessor {
|
||||
|
||||
@Override
|
||||
public String buildLogicNormalCondition(String logicColumn, IDialect dialect) {
|
||||
return dialect.wrap(logicColumn) + EQUALS + getLogicNormalValue();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String buildLogicDeletedSet(String logicColumn, IDialect dialect) {
|
||||
return dialect.wrap(logicColumn) + EQUALS + getLogicDeletedValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo) {
|
||||
queryWrapper.and(QueryCondition.create(tableInfo.getSchema(), tableInfo.getTableName(), tableInfo.getLogicDeleteColumn()
|
||||
, SqlConsts.EQUALS
|
||||
, FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete()));
|
||||
}
|
||||
|
||||
|
||||
protected Object getLogicNormalValue() {
|
||||
Object normalValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete();
|
||||
if (normalValueOfLogicDelete instanceof Number
|
||||
|| normalValueOfLogicDelete instanceof Boolean) {
|
||||
return normalValueOfLogicDelete;
|
||||
}
|
||||
return SINGLE_QUOTE + normalValueOfLogicDelete + SINGLE_QUOTE;
|
||||
}
|
||||
|
||||
|
||||
protected Object getLogicDeletedValue() {
|
||||
Object deletedValueOfLogicDelete = FlexGlobalConfig.getDefaultConfig().getDeletedValueOfLogicDelete();
|
||||
if (deletedValueOfLogicDelete instanceof Number
|
||||
|| deletedValueOfLogicDelete instanceof Boolean) {
|
||||
return deletedValueOfLogicDelete;
|
||||
}
|
||||
return SINGLE_QUOTE + deletedValueOfLogicDelete + SINGLE_QUOTE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,11 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.core.logicdelete;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class LogicDeleteManager {
|
||||
|
||||
private static LogicDeleteProcessor processor = new DefaultLogicDeleteProcessorImpl();
|
||||
private static final ThreadLocal<Boolean> skipFlags = new ThreadLocal<>();
|
||||
|
||||
public static LogicDeleteProcessor getProcessor() {
|
||||
return processor;
|
||||
}
|
||||
|
||||
public static void setProcessor(LogicDeleteProcessor processor) {
|
||||
LogicDeleteManager.processor = processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳过逻辑删除字段处理,直接进行数据库物理操作
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.core.logicdelete;
|
||||
|
||||
import com.mybatisflex.core.dialect.IDialect;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.core.table.TableInfo;
|
||||
|
||||
public interface LogicDeleteProcessor {
|
||||
|
||||
/**
|
||||
* 用户构建查询正常数据的条件
|
||||
* @param logicColumn
|
||||
* @param dialect
|
||||
*/
|
||||
String buildLogicNormalCondition(String logicColumn, IDialect dialect);
|
||||
|
||||
/**
|
||||
* 用户与构建删除数据时的内容
|
||||
* @param logicColumn
|
||||
* @param dialect
|
||||
*/
|
||||
String buildLogicDeletedSet(String logicColumn, IDialect dialect);
|
||||
|
||||
/**
|
||||
* 用于构建通过 QueryWrapper 查询数据时的内容
|
||||
* @param queryWrapper
|
||||
* @param tableInfo
|
||||
*/
|
||||
void buildQueryCondition(QueryWrapper queryWrapper, TableInfo tableInfo);
|
||||
}
|
||||
|
||||
|
||||
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.mybatisflex.core.paginate;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页接口。
|
||||
*
|
||||
* @param <T> 数据类型
|
||||
* @author 王帅
|
||||
* @since 2023-06-18
|
||||
*/
|
||||
public interface IPage<T> extends Serializable {
|
||||
|
||||
/**
|
||||
* 获取当前页码。
|
||||
*
|
||||
* @return 页码
|
||||
*/
|
||||
int getPageNumber();
|
||||
|
||||
/**
|
||||
* 设置当前页码。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
*/
|
||||
void setPageNumber(int pageNumber);
|
||||
|
||||
/**
|
||||
* 获取当前每页数据数量。
|
||||
*
|
||||
* @return 每页数据数量
|
||||
*/
|
||||
int getPageSize();
|
||||
|
||||
/**
|
||||
* 设置当前每页数据数量。
|
||||
*
|
||||
* @param pageSize 每页数据数量
|
||||
*/
|
||||
void setPageSize(int pageSize);
|
||||
|
||||
/**
|
||||
* 获取数据总数。
|
||||
*
|
||||
* @return 数据总数
|
||||
*/
|
||||
long getTotalRow();
|
||||
|
||||
/**
|
||||
* 设置数据总数。
|
||||
*
|
||||
* @param totalRow 数据总数
|
||||
*/
|
||||
void setTotalRow(long totalRow);
|
||||
|
||||
/**
|
||||
* 获取当前页的数据。
|
||||
*
|
||||
* @return 当前页的数据
|
||||
*/
|
||||
List<T> getRecords();
|
||||
|
||||
/**
|
||||
* 设置当前页的数据。
|
||||
*
|
||||
* @param records 当前页的数据
|
||||
*/
|
||||
void setRecords(List<T> records);
|
||||
|
||||
/**
|
||||
* 获取当前分页偏移量。
|
||||
*
|
||||
* @return 偏移量
|
||||
*/
|
||||
default int getOffset() {
|
||||
return getPageSize() * (getPageNumber() - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否自动优化 COUNT 查询语句(默认优化)。
|
||||
*
|
||||
* @return {@code true} 优化,{@code false} 不优化
|
||||
*/
|
||||
default boolean isOptimizeCountSql() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置是否自动优化 COUNT 查询语句。
|
||||
*
|
||||
* @param optimizeCountSql 是否优化
|
||||
*/
|
||||
default void setOptimizeCountSql(boolean optimizeCountSql) {
|
||||
// 默认总是优化
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取总页数。
|
||||
*
|
||||
* @return 总页数
|
||||
*/
|
||||
default long getTotalPage() {
|
||||
// 实时计算总页数
|
||||
int pageSize = getPageSize();
|
||||
if (pageSize == 0) {
|
||||
return 0L;
|
||||
}
|
||||
long totalRow = getTotalRow();
|
||||
long totalPage = totalRow / pageSize;
|
||||
if (totalRow % pageSize != 0) {
|
||||
totalPage++;
|
||||
}
|
||||
return totalPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置总页数。
|
||||
*
|
||||
* @param totalPage 总页数
|
||||
*/
|
||||
default void setTotalPage(long totalPage) {
|
||||
// 总页数是实时计算的,所以这里设置了也没用。
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在上一页。
|
||||
*
|
||||
* @return {@code true} 存在上一页,{@code false} 不存在上一页
|
||||
*/
|
||||
default boolean hasPrevious() {
|
||||
return getPageNumber() > 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在下一页。
|
||||
*
|
||||
* @return {@code true} 存在下一页,{@code false} 不存在下一页
|
||||
*/
|
||||
default boolean hasNext() {
|
||||
return getPageNumber() < getTotalPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前页是否为空。
|
||||
*
|
||||
* @return {@code true} 空页,{@code false} 非空页
|
||||
*/
|
||||
default boolean isEmpty() {
|
||||
return getTotalRow() == 0 || getPageNumber() > getTotalPage();
|
||||
}
|
||||
|
||||
}
|
||||
@ -15,12 +15,18 @@
|
||||
*/
|
||||
package com.mybatisflex.core.paginate;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Page<T> implements IPage<T> {
|
||||
/**
|
||||
* 分页对象
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
*/
|
||||
public class Page<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static final int INIT_VALUE = -1;
|
||||
@ -31,7 +37,7 @@ public class Page<T> implements IPage<T> {
|
||||
private long totalPage = INIT_VALUE;
|
||||
private long totalRow = INIT_VALUE;
|
||||
|
||||
private boolean optimizeCountSql = true;
|
||||
private boolean optimizeCountQuery = true;
|
||||
|
||||
public static <T> Page<T> of(int pageNumber, int pageSize) {
|
||||
return new Page<>(pageNumber, pageSize);
|
||||
@ -56,7 +62,6 @@ public class Page<T> implements IPage<T> {
|
||||
this.setTotalRow(totalRow);
|
||||
}
|
||||
|
||||
|
||||
public Page(List<T> records, int pageNumber, int pageSize, long totalRow) {
|
||||
this.setRecords(records);
|
||||
this.setPageNumber(pageNumber);
|
||||
@ -65,22 +70,22 @@ public class Page<T> implements IPage<T> {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isOptimizeCountSql() {
|
||||
return optimizeCountSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOptimizeCountSql(boolean optimizeCountSql) {
|
||||
this.optimizeCountSql = optimizeCountSql;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 获取当前页的数据。
|
||||
*
|
||||
* @return 当前页的数据
|
||||
*/
|
||||
public List<T> getRecords() {
|
||||
return records;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 设置当前页的数据。
|
||||
*
|
||||
* @param records 当前页的数据
|
||||
*/
|
||||
public void setRecords(List<T> records) {
|
||||
if (records == null) {
|
||||
records = Collections.emptyList();
|
||||
@ -88,12 +93,21 @@ public class Page<T> implements IPage<T> {
|
||||
this.records = records;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 获取当前页码。
|
||||
*
|
||||
* @return 页码
|
||||
*/
|
||||
public int getPageNumber() {
|
||||
return pageNumber;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 设置当前页码。
|
||||
*
|
||||
* @param pageNumber 页码
|
||||
*/
|
||||
public void setPageNumber(int pageNumber) {
|
||||
if (pageNumber < 1) {
|
||||
throw new IllegalArgumentException("pageNumber must greater than or equal 1,current value is: " + pageNumber);
|
||||
@ -102,12 +116,21 @@ public class Page<T> implements IPage<T> {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 获取当前每页数据数量。
|
||||
*
|
||||
* @return 每页数据数量
|
||||
*/
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 设置当前每页数据数量。
|
||||
*
|
||||
* @param pageSize 每页数据数量
|
||||
*/
|
||||
public void setPageSize(int pageSize) {
|
||||
if (pageSize < 0) {
|
||||
throw new IllegalArgumentException("pageSize must greater than or equal 0,current value is: " + pageSize);
|
||||
@ -116,22 +139,39 @@ public class Page<T> implements IPage<T> {
|
||||
this.calcTotalPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 获取数据总数。
|
||||
*
|
||||
* @return 数据总数
|
||||
*/
|
||||
public long getTotalPage() {
|
||||
return totalPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 设置总页数。
|
||||
*
|
||||
* @param totalPage 总页数
|
||||
*/
|
||||
public void setTotalPage(long totalPage) {
|
||||
this.totalPage = totalPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* 获取数据总数。
|
||||
*
|
||||
* @return 数据总数
|
||||
*/
|
||||
public long getTotalRow() {
|
||||
return totalRow;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 设置数据总数。
|
||||
*
|
||||
* @param totalRow 数据总数
|
||||
*/
|
||||
public void setTotalRow(long totalRow) {
|
||||
this.totalRow = totalRow;
|
||||
this.calcTotalPage();
|
||||
@ -148,17 +188,67 @@ public class Page<T> implements IPage<T> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 当前页是否为空。
|
||||
*
|
||||
* @return {@code true} 空页,{@code false} 非空页
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return getTotalRow() == 0 || getPageNumber() > getTotalPage();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
/**
|
||||
* 是否存在下一页。
|
||||
*
|
||||
* @return {@code true} 存在下一页,{@code false} 不存在下一页
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return getTotalPage() != 0 && getPageNumber() < getTotalPage();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否存在上一页。
|
||||
*
|
||||
* @return {@code true} 存在上一页,{@code false} 不存在上一页
|
||||
*/
|
||||
public boolean hasPrevious() {
|
||||
return getPageNumber() > 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前分页偏移量。
|
||||
*
|
||||
* @return 偏移量
|
||||
*/
|
||||
public int offset() {
|
||||
return getPageSize() * (getPageNumber() - 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置是否自动优化 COUNT 查询语句。
|
||||
*
|
||||
* @param optimizeCountQuery 是否优化
|
||||
*/
|
||||
public void setOptimizeCountQuery(boolean optimizeCountQuery) {
|
||||
this.optimizeCountQuery = optimizeCountQuery;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 是否自动优化 COUNT 查询语句(默认优化)。
|
||||
*
|
||||
* @return {@code true} 优化,{@code false} 不优化
|
||||
*/
|
||||
public boolean needOptimizeCountQuery() {
|
||||
return optimizeCountQuery;
|
||||
}
|
||||
|
||||
|
||||
public <R> Page<R> map(Function<? super T, ? extends R> mapper) {
|
||||
Page<R> newPage = new Page<>();
|
||||
newPage.pageNumber = pageNumber;
|
||||
|
||||
@ -423,9 +423,9 @@ public class EntitySqlProvider {
|
||||
if (CollectionUtil.isNotEmpty(queryTables)) {
|
||||
tableInfos = new ArrayList<>();
|
||||
for (QueryTable queryTable : queryTables) {
|
||||
String tableName = queryTable.getName();
|
||||
if (StringUtil.isNotBlank(tableName)) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofTableName(tableName);
|
||||
String tableNameWithSchema = queryTable.getNameWithSchema();
|
||||
if (StringUtil.isNotBlank(tableNameWithSchema)) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofTableName(tableNameWithSchema);
|
||||
if (tableInfo != null) {
|
||||
tableInfos.add(tableInfo);
|
||||
}
|
||||
|
||||
@ -71,6 +71,10 @@ public class QueryTable implements CloneSupport<QueryTable> {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNameWithSchema() {
|
||||
return StringUtil.isNotBlank(schema) ? schema + "." + name : name;
|
||||
}
|
||||
|
||||
|
||||
public QueryTable as(String alias) {
|
||||
this.alias = alias;
|
||||
@ -84,8 +88,7 @@ public class QueryTable implements CloneSupport<QueryTable> {
|
||||
if (StringUtil.isNotBlank(alias)
|
||||
&& StringUtil.isNotBlank(table.alias)
|
||||
&& (Objects.equals(alias, table.alias))) {
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
return Objects.equals(name, table.name);
|
||||
}
|
||||
|
||||
@ -441,7 +441,7 @@ public interface RowMapper {
|
||||
// 一般的分页场景中,只有第一页的时候有必要去查询总量,第二页以后是不需要的
|
||||
if (page.getTotalRow() < 0) {
|
||||
QueryWrapper countQueryWrapper;
|
||||
if (page.isOptimizeCountSql()) {
|
||||
if (page.needOptimizeCountQuery()) {
|
||||
countQueryWrapper = MapperUtil.optimizeCountQueryWrapper(queryWrapper);
|
||||
} else {
|
||||
countQueryWrapper = MapperUtil.rawCountQueryWrapper(queryWrapper);
|
||||
@ -453,7 +453,7 @@ public interface RowMapper {
|
||||
return page;
|
||||
}
|
||||
|
||||
queryWrapper.limit(page.getOffset(), page.getPageSize());
|
||||
queryWrapper.limit(page.offset(), page.getPageSize());
|
||||
|
||||
page.setRecords(selectListByQuery(schema, tableName, queryWrapper));
|
||||
|
||||
|
||||
@ -128,6 +128,10 @@ public class TableInfo {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public String getTableNameWithSchema() {
|
||||
return StringUtil.isNotBlank(schema) ? schema + "." + tableName : tableName;
|
||||
}
|
||||
|
||||
public String getWrapSchemaAndTableName(IDialect dialect) {
|
||||
if (StringUtil.isNotBlank(schema)) {
|
||||
return dialect.wrap(dialect.getRealSchema(schema)) + "." + dialect.wrap(dialect.getRealTable(tableName));
|
||||
@ -164,10 +168,14 @@ public class TableInfo {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
public String getLogicDeleteColumn() {
|
||||
public String getLogicDeleteColumnOrSkip() {
|
||||
return LogicDeleteManager.getLogicDeleteColumn(logicDeleteColumn);
|
||||
}
|
||||
|
||||
public String getLogicDeleteColumn() {
|
||||
return logicDeleteColumn;
|
||||
}
|
||||
|
||||
public void setLogicDeleteColumn(String logicDeleteColumn) {
|
||||
this.logicDeleteColumn = logicDeleteColumn;
|
||||
}
|
||||
@ -624,6 +632,7 @@ public class TableInfo {
|
||||
}
|
||||
|
||||
private static final String APPEND_CONDITIONS_FLAG = "appendConditions";
|
||||
private static final String APPEND_JOIN_FLAG = "appendJoins";
|
||||
|
||||
public void appendConditions(Object entity, QueryWrapper queryWrapper) {
|
||||
|
||||
@ -666,9 +675,8 @@ public class TableInfo {
|
||||
}
|
||||
|
||||
//逻辑删除
|
||||
if (StringUtil.isNotBlank(getLogicDeleteColumn())) {
|
||||
queryWrapper.and(QueryCondition.create(schema, tableName, logicDeleteColumn, SqlConsts.EQUALS
|
||||
, FlexGlobalConfig.getDefaultConfig().getNormalValueOfLogicDelete()));
|
||||
if (StringUtil.isNotBlank(getLogicDeleteColumnOrSkip())) {
|
||||
LogicDeleteManager.getProcessor().buildQueryCondition(queryWrapper, this);
|
||||
}
|
||||
|
||||
//多租户
|
||||
@ -689,6 +697,31 @@ public class TableInfo {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//join
|
||||
if (!Boolean.TRUE.equals(CPI.getContext(queryWrapper, APPEND_JOIN_FLAG))) {
|
||||
List<Join> joins = CPI.getJoins(queryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(joins)) {
|
||||
for (Join join : joins) {
|
||||
QueryTable joinQueryTable = CPI.getJoinQueryTable(join);
|
||||
if (joinQueryTable instanceof SelectQueryTable) {
|
||||
QueryWrapper childQuery = ((SelectQueryTable) joinQueryTable).getQueryWrapper();
|
||||
doAppendConditions(entity, childQuery);
|
||||
} else {
|
||||
String nameWithSchema = joinQueryTable.getNameWithSchema();
|
||||
if (StringUtil.isNotBlank(nameWithSchema)) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofTableName(nameWithSchema);
|
||||
if (tableInfo != null) {
|
||||
CPI.putContext(queryWrapper, APPEND_CONDITIONS_FLAG, Boolean.FALSE);
|
||||
CPI.putContext(queryWrapper, APPEND_JOIN_FLAG, Boolean.TRUE);
|
||||
tableInfo.appendConditions(entity, queryWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//union
|
||||
List<UnionWrapper> unions = CPI.getUnions(queryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(unions)) {
|
||||
@ -704,9 +737,17 @@ public class TableInfo {
|
||||
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
|
||||
if (queryTables != null && !queryTables.isEmpty()) {
|
||||
for (QueryTable queryTable : queryTables) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofTableName(queryTable.getName());
|
||||
if (tableInfo != null) {
|
||||
tableInfo.appendConditions(entity, queryWrapper);
|
||||
if (queryTable instanceof SelectQueryTable) {
|
||||
QueryWrapper childQuery = ((SelectQueryTable) queryTable).getQueryWrapper();
|
||||
doAppendConditions(entity, childQuery);
|
||||
} else {
|
||||
String nameWithSchema = queryTable.getNameWithSchema();
|
||||
if (StringUtil.isNotBlank(nameWithSchema)) {
|
||||
TableInfo tableInfo = TableInfoFactory.ofTableName(nameWithSchema);
|
||||
if (tableInfo != null) {
|
||||
tableInfo.appendConditions(entity, queryWrapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -986,7 +1027,7 @@ public class TableInfo {
|
||||
* @param entityObject
|
||||
*/
|
||||
public void initLogicDeleteValueIfNecessary(Object entityObject) {
|
||||
if (StringUtil.isBlank(getLogicDeleteColumn())) {
|
||||
if (StringUtil.isBlank(getLogicDeleteColumnOrSkip())) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -101,7 +101,7 @@ public class TableInfoFactory {
|
||||
public static TableInfo ofEntityClass(Class<?> entityClass) {
|
||||
return MapUtil.computeIfAbsent(entityTableMap, entityClass, aClass -> {
|
||||
TableInfo tableInfo = createTableInfo(entityClass);
|
||||
tableInfoMap.put(tableInfo.getTableName(), tableInfo);
|
||||
tableInfoMap.put(tableInfo.getTableNameWithSchema(), tableInfo);
|
||||
return tableInfo;
|
||||
});
|
||||
}
|
||||
|
||||
@ -55,10 +55,10 @@ public class AccountSqlTester {
|
||||
TableManager.setDynamicTableProcessor(new DynamicTableProcessor() {
|
||||
@Override
|
||||
public String process(String tableName) {
|
||||
return tableName+"_01";
|
||||
return tableName + "_01";
|
||||
}
|
||||
});
|
||||
TableManager.setDynamicTableProcessor(original -> original+"_01");
|
||||
TableManager.setDynamicTableProcessor(original -> original + "_01");
|
||||
|
||||
System.out.println(query.toSQL());
|
||||
}
|
||||
@ -72,8 +72,8 @@ public class AccountSqlTester {
|
||||
.where(ACCOUNT01.ID.ge(100))
|
||||
.and(ACCOUNT.SEX.eq(1));
|
||||
|
||||
TableManager.setDynamicTableProcessor(original -> original+"_01");
|
||||
TableManager.setDynamicTableProcessor(original -> original+"_01");
|
||||
TableManager.setDynamicTableProcessor(original -> original + "_01");
|
||||
TableManager.setDynamicTableProcessor(original -> original + "_01");
|
||||
|
||||
System.out.println(query.toSQL());
|
||||
}
|
||||
@ -263,6 +263,8 @@ public class AccountSqlTester {
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
|
||||
//https://gitee.com/mybatis-flex/mybatis-flex/issues/I7EAY9
|
||||
@Test
|
||||
public void testGroup_I7EAY9() {
|
||||
QueryWrapper query = QueryWrapper.create()
|
||||
@ -330,6 +332,10 @@ public class AccountSqlTester {
|
||||
System.out.println(sql);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testOrderBySql() {
|
||||
QueryWrapper queryWrapper = QueryWrapper.create()
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-annotation</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
|
||||
* <p>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.audit.MessageCollector;
|
||||
import com.mybatisflex.core.query.QueryWrapper;
|
||||
import com.mybatisflex.mapper.ArticleMapper;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
|
||||
import static com.mybatisflex.core.query.QueryMethods.raw;
|
||||
import static com.mybatisflex.core.query.QueryMethods.select;
|
||||
import static com.mybatisflex.test.table.AccountTableDef.ACCOUNT;
|
||||
import static com.mybatisflex.test.table.ArticleTableDef.ARTICLE;
|
||||
|
||||
/**
|
||||
* test https://gitee.com/mybatis-flex/mybatis-flex/issues/I7EV67
|
||||
*/
|
||||
public class JoinWithDeleteColumnTestStarter {
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataSource dataSource = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("schema.sql")
|
||||
.addScript("data.sql")
|
||||
.build();
|
||||
|
||||
MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance()
|
||||
.setDataSource(dataSource)
|
||||
.addMapper(AccountMapper.class)
|
||||
.addMapper(MyAccountMapper.class)
|
||||
.addMapper(ArticleMapper.class)
|
||||
.start();
|
||||
|
||||
//开启审计功能
|
||||
AuditManager.setAuditEnable(true);
|
||||
|
||||
//设置 SQL 审计收集器
|
||||
MessageCollector collector = new ConsoleMessageCollector();
|
||||
AuditManager.setMessageCollector(collector);
|
||||
|
||||
|
||||
AccountMapper accountMapper = bootstrap.getMapper(AccountMapper.class);
|
||||
|
||||
QueryWrapper query1 = QueryWrapper.create()
|
||||
.select()
|
||||
.from(ACCOUNT)
|
||||
.leftJoin(ARTICLE).as("a").on(
|
||||
ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID)
|
||||
)
|
||||
.where(ACCOUNT.AGE.ge(10));
|
||||
|
||||
List<AccountDTO> accountDTOS1 = accountMapper.selectListByQueryAs(query1, AccountDTO.class);
|
||||
System.out.println(accountDTOS1);
|
||||
|
||||
System.out.println(">>>>>>>>>");
|
||||
|
||||
QueryWrapper query2 = QueryWrapper.create()
|
||||
.select()
|
||||
.from(ACCOUNT)
|
||||
.leftJoin(
|
||||
select().from(ARTICLE).where(ARTICLE.ID.ge(100))
|
||||
).as("a").on(
|
||||
ACCOUNT.ID.eq(raw("a.id"))
|
||||
)
|
||||
.where(ACCOUNT.AGE.ge(10));
|
||||
|
||||
List<AccountDTO> accountDTOS2 = accountMapper.selectListByQueryAs(query2, AccountDTO.class);
|
||||
System.out.println(accountDTOS2);
|
||||
|
||||
}
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -144,7 +144,7 @@ class UserMapperTest {
|
||||
.leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID));
|
||||
System.err.println(queryWrapper.toSQL());
|
||||
Page<UserVO> page = Page.of(1, 1);
|
||||
page.setOptimizeCountSql(false);
|
||||
page.setOptimizeCountQuery(false);
|
||||
int pageNumber = 0;
|
||||
do {
|
||||
page.setPageNumber(page.getPageNumber() + 1);
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring-boot-starter</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>mybatis-flex-test</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -20,13 +20,13 @@
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-core</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-spring</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>parent</artifactId>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
@ -60,7 +60,7 @@
|
||||
<path>
|
||||
<groupId>com.mybatis-flex</groupId>
|
||||
<artifactId>mybatis-flex-processor</artifactId>
|
||||
<version>1.4.0</version>
|
||||
<version>1.4.1</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user