fix 对一查询参数类型错误

This commit is contained in:
yulichang 2023-02-23 14:18:30 +08:00
parent 11db738c62
commit bfab4f289e
33 changed files with 523 additions and 187 deletions

View File

@ -0,0 +1,52 @@
<?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 https://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>1.4.2.2</version>
</parent>
<artifactId>mybatis-plus-join-adapter-base</artifactId>
<version>1.4.2.2</version>
<name>mybatis-plus-join-adapter-base</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-extension</artifactId>
<version>3.5.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,18 @@
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;
public interface IAdapter {
boolean mpjHasLogic(TableInfo tableInfo);
boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo);
TableFieldInfo mpjGetLogicField(TableInfo tableInfo);
boolean mpjHasPK(TableInfo tableInfo);
Configuration mpjGetConfiguration(TableInfo tableInfo);
}

View File

@ -0,0 +1,39 @@
package com.github.yulichang.adapter.v33x;
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.IAdapter;
import org.apache.ibatis.session.Configuration;
import java.util.Objects;
public class AdapterV33x implements IAdapter {
@Override
public boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isLogicDelete();
}
@Override
public boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.getPropertyType().isPrimitive();
}
@Override
public TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getFieldList().stream().filter(f -> Objects.nonNull(f.getLogicDeleteValue())
|| Objects.nonNull(f.getLogicNotDeleteValue())).findFirst().orElse(null);
}
@Override
public boolean mpjHasPK(TableInfo tableInfo) {
return StringUtils.isNotBlank(tableInfo.getKeyProperty()) ||
StringUtils.isNotBlank(tableInfo.getKeyColumn());
}
@Override
public Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
}

View File

@ -49,6 +49,11 @@
<artifactId>mybatis-plus-join-annotation</artifactId>
<version>1.4.2.2</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-adapter-v33x</artifactId>
<version>1.4.2.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>

View File

@ -0,0 +1,34 @@
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.IAdapter;
import org.apache.ibatis.session.Configuration;
public class Adapter implements IAdapter {
@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();
}
}

View File

@ -0,0 +1,16 @@
package com.github.yulichang.adapter;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.github.yulichang.adapter.base.IAdapter;
import com.github.yulichang.adapter.v33x.AdapterV33x;
public class AdapterHelper {
public static IAdapter getAdapter() {
String version = MybatisPlusVersion.getVersion();
if (version.startsWith("3.3.")) {
return new AdapterV33x();
}
return new Adapter();
}
}

View File

@ -1,12 +1,32 @@
package com.github.yulichang.config;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.adapter.base.IAdapter;
/**
* @author yulichang
* @since 1.3.7
*/
public class ConfigProperties {
/**
* 是否开启副表逻辑删除
*/
public static boolean subTableLogic = true;
/**
* 是否开启 ms 缓存
*/
public static boolean msCache = true;
/**
* 表别名
*/
public static String tableAlias = "t";
/**
* 字段名重复时前缀
*/
public static String joinPrefix = "join";
/**
* 适配器
*/
public static IAdapter adapter = AdapterHelper.getAdapter();
}

View File

@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.JR;
import java.util.Objects;
@ -22,19 +21,23 @@ import static java.util.stream.Collectors.joining;
public interface MPJBaseMethod extends Constants {
default String mpjSqlWhereEntityWrapper(boolean newLine, TableInfo table) {
if (JR.mpjHasLogic(table)) {
if (ConfigProperties.adapter.mpjHasLogic(table)) {
String sqlScript = getAllSqlWhere(table, true, true, WRAPPER_ENTITY_DOT);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
sqlScript += NEWLINE;
sqlScript += SqlScriptUtils.convertIf(getLogicDeleteSql(table, true, true), String.format("%s.logicSql", WRAPPER), true);
sqlScript += SqlScriptUtils.convertIf(getLogicDeleteSql(table, true, true),
String.format("%s.logicSql", WRAPPER), true);
if (ConfigProperties.subTableLogic) {
sqlScript += (NEWLINE + String.format("${%s.subLogicSql}", WRAPPER));
}
sqlScript += SqlScriptUtils.convertIf(String.format("AND ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFNORMAL), true);
sqlScript += SqlScriptUtils.convertIf(String.format("AND ${%s}", WRAPPER_SQLSEGMENT),
String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFNORMAL), true);
sqlScript += NEWLINE;
sqlScript = SqlScriptUtils.convertWhere(sqlScript);
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFNORMAL), true);
sqlScript = SqlScriptUtils.convertChoose(String.format("%s != null", WRAPPER), sqlScript, table.getLogicDeleteSql(false, true));
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT),
String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFNORMAL), true);
sqlScript = SqlScriptUtils.convertChoose(String.format("%s != null", WRAPPER), sqlScript,
table.getLogicDeleteSql(false, true));
return newLine ? NEWLINE + sqlScript : sqlScript;
} else {
String sqlScript = getAllSqlWhere(table, false, true, WRAPPER_ENTITY_DOT);
@ -44,9 +47,11 @@ public interface MPJBaseMethod extends Constants {
sqlScript += (String.format("${%s.subLogicSql}", WRAPPER) + NEWLINE);
}
String s = SqlScriptUtils.convertIf("AND", WRAPPER_NONEMPTYOFNORMAL, true);
sqlScript += SqlScriptUtils.convertIf(s + String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFWHERE), true);
sqlScript += SqlScriptUtils.convertIf(s + String.format(" ${%s}", WRAPPER_SQLSEGMENT),
String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFWHERE), true);
sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFWHERE), true);
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT),
String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFWHERE), true);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER), true);
return newLine ? NEWLINE + sqlScript : sqlScript;
}
@ -61,7 +66,7 @@ public interface MPJBaseMethod extends Constants {
String filedSqlScript = tableInfo.getFieldList().stream()
.filter(i -> {
if (ignoreLogicDelFiled) {
return !(JR.mpjHasLogic(tableInfo) && i.isLogicDelete());
return !(ConfigProperties.adapter.mpjHasLogic(tableInfo) && i.isLogicDelete());
}
return true;
})
@ -70,7 +75,8 @@ public interface MPJBaseMethod extends Constants {
return filedSqlScript;
}
String newKeyProperty = newPrefix + tableInfo.getKeyProperty();
String keySqlScript = ConfigProperties.tableAlias + DOT + tableInfo.getKeyColumn() + EQUALS + SqlScriptUtils.safeParam(newKeyProperty);
String keySqlScript = ConfigProperties.tableAlias + DOT + tableInfo.getKeyColumn() + EQUALS +
SqlScriptUtils.safeParam(newKeyProperty);
return SqlScriptUtils.convertIf(keySqlScript, String.format("%s != null", newKeyProperty), false)
+ NEWLINE + filedSqlScript;
}
@ -78,16 +84,18 @@ 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 + tableFieldInfo.getColumn(), newPrefix + tableFieldInfo.getEl());
String sqlScript = " AND " + String.format(tableFieldInfo.getCondition(), ConfigProperties.tableAlias + DOT +
tableFieldInfo.getColumn(), newPrefix + tableFieldInfo.getEl());
// 查询的时候只判非空
return convertIf(tableFieldInfo, sqlScript, convertIfProperty(newPrefix, tableFieldInfo.getProperty()), tableFieldInfo.getWhereStrategy());
return convertIf(tableFieldInfo, sqlScript, convertIfProperty(newPrefix, tableFieldInfo.getProperty()),
tableFieldInfo.getWhereStrategy());
}
default String convertIf(TableFieldInfo tableFieldInfo, final String sqlScript, final String property, final FieldStrategy fieldStrategy) {
if (fieldStrategy == FieldStrategy.NEVER) {
return null;
}
if (JR.mpjIsPrimitive(tableFieldInfo) || fieldStrategy == FieldStrategy.IGNORED) {
if (ConfigProperties.adapter.mpjIsPrimitive(tableFieldInfo) || fieldStrategy == FieldStrategy.IGNORED) {
return sqlScript;
}
if (fieldStrategy == FieldStrategy.NOT_EMPTY && tableFieldInfo.isCharSequence()) {
@ -103,7 +111,7 @@ public interface MPJBaseMethod extends Constants {
default String getLogicDeleteSql(TableInfo tableInfo, boolean startWithAnd, boolean isWhere) {
if (JR.mpjHasLogic(tableInfo)) {
if (ConfigProperties.adapter.mpjHasLogic(tableInfo)) {
String logicDeleteSql = formatLogicDeleteSql(tableInfo, isWhere);
if (startWithAnd) {
logicDeleteSql = " AND " + logicDeleteSql;
@ -115,12 +123,16 @@ public interface MPJBaseMethod extends Constants {
default String formatLogicDeleteSql(TableInfo tableInfo, boolean isWhere) {
final String value = isWhere ? JR.mpjGetLogicField(tableInfo).getLogicNotDeleteValue() : JR.mpjGetLogicField(tableInfo).getLogicDeleteValue();
final String value = isWhere ? ConfigProperties.adapter.mpjGetLogicField(tableInfo).getLogicNotDeleteValue() :
ConfigProperties.adapter.mpjGetLogicField(tableInfo).getLogicDeleteValue();
if (isWhere) {
if (NULL.equalsIgnoreCase(value)) {
return "${ew.alias}." + JR.mpjGetLogicField(tableInfo).getColumn() + " IS NULL";
return "${ew.alias}." + ConfigProperties.adapter.mpjGetLogicField(tableInfo).getColumn() +
" IS NULL";
} else {
return "${ew.alias}." + JR.mpjGetLogicField(tableInfo).getColumn() + EQUALS + String.format(JR.mpjGetLogicField(tableInfo).isCharSequence() ? "'%s'" : "%s", value);
return "${ew.alias}." + ConfigProperties.adapter.mpjGetLogicField(tableInfo).getColumn() +
EQUALS + String.format(ConfigProperties.adapter.mpjGetLogicField(tableInfo).isCharSequence() ?
"'%s'" : "%s", value);
}
}
final String targetStr = "${ew.alias}." + tableInfo.getLogicDeleteFieldInfo().getColumn() + EQUALS;

View File

@ -1,64 +0,0 @@
package com.github.yulichang.toolkit;
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.Objects;
@SuppressWarnings("Convert2MethodRef")
public class JR {
@SuppressWarnings("JavaReflectionMemberAccess")
public static boolean mpjHasLogic(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.isWithLogicDelete(), () -> {
try {
Field field = TableInfo.class.getDeclaredField("logicDelete");
field.setAccessible(true);
return (boolean) field.get(tableInfo);
} catch (Exception ee) {
throw new RuntimeException(ee);
}
});
}
public static boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tryThrowable(() -> tableFieldInfo.isPrimitive(), () -> tableFieldInfo.getPropertyType().isPrimitive());
}
public static TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.getLogicDeleteFieldInfo(), () -> tableInfo.getFieldList().stream().filter(f ->
Objects.nonNull(f.getLogicNotDeleteValue()) ||
Objects.nonNull(f.getLogicDeleteValue())).findFirst().orElse(null));
}
public static boolean mpjHasPK(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.havePK(), () -> Objects.nonNull(tableInfo.getKeyProperty()));
}
public static Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.getConfiguration(), () -> {
try {
Field field = TableInfo.class.getDeclaredField("configuration");
field.setAccessible(true);
return (Configuration) field.get(tableInfo);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
private static <T> T tryThrowable(F<T> fn, F<T> orElse) {
try {
return fn.apply();
} catch (Throwable throwable) {
return orElse.apply();
}
}
@FunctionalInterface
public interface F<T> {
T apply();
}
}

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.config.ConfigProperties;
import java.util.Map;
import java.util.Objects;
@ -35,8 +36,8 @@ public class LogicInfoUtils implements Constants {
String logicStr;
TableInfo tableInfo = TableHelper.get(clazz);
Assert.notNull(tableInfo, "table not find by class <%s>", clazz.getSimpleName());
TableFieldInfo logicField = JR.mpjGetLogicField(tableInfo);
if (JR.mpjHasLogic(tableInfo) && Objects.nonNull(logicField)) {
TableFieldInfo logicField = ConfigProperties.adapter.mpjGetLogicField(tableInfo);
if (ConfigProperties.adapter.mpjHasLogic(tableInfo) && Objects.nonNull(logicField)) {
final String value = logicField.getLogicNotDeleteValue();
if (NULL.equalsIgnoreCase(value)) {
logicStr = " AND " + prefix + DOT + logicField.getColumn() + " IS NULL";

View File

@ -2,7 +2,7 @@ package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.github.yulichang.toolkit.JR;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.wrapper.segments.SelectCache;
@ -30,7 +30,7 @@ public class ColumnCache {
TableInfo tableInfo = TableHelper.get(clazz);
Assert.notNull(tableInfo, "table not find by class <%s>", c.getSimpleName());
List<SelectCache> list = new ArrayList<>();
if (JR.mpjHasPK(tableInfo)) {
if (ConfigProperties.adapter.mpjHasPK(tableInfo)) {
list.add(new SelectCache(clazz, true, tableInfo.getKeyColumn(), tableInfo.getKeyType(), tableInfo.getKeyProperty(), null));
}
list.addAll(tableInfo.getFieldList().stream().map(f -> new SelectCache(clazz, false, f.getColumn(), f.getPropertyType(), f.getProperty(), f)).collect(Collectors.toList()));

View File

@ -1,6 +1,7 @@
package com.github.yulichang.wrapper.interfaces;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.LambdaUtils;
import com.github.yulichang.toolkit.MPJReflectionKit;
@ -10,7 +11,6 @@ import com.github.yulichang.wrapper.resultmap.MybatisLabel;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
@SuppressWarnings({"unchecked", "unused"})
public interface QueryLabel<Children> {
@ -123,14 +123,14 @@ public interface QueryLabel<Children> {
return selectAssociation(null, child, dtoField);
}
default <S, C, F> Children selectAssociation(Integer index, Class<C> child, SFunction<S, F> dtoField) {
default <S, C, F> Children selectAssociation(String prefix, Class<C> child, SFunction<S, F> dtoField) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
Map<String, Field> fieldMap = MPJReflectionKit.getFieldMap(dtoClass);
Field field = fieldMap.get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<C, F> builder;
builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
builder = new MybatisLabel.Builder<>(StringUtils.isBlank(prefix) ? null : prefix,
dtoFieldName, child, field.getType(), (Class<F>) field.getType(), true);
addLabel(builder.build());
return getChildren();
@ -146,13 +146,13 @@ public interface QueryLabel<Children> {
return selectAssociation(null, child, dtoField, collection);
}
default <S, C, F> Children selectAssociation(Integer index, Class<C> child, SFunction<S, F> dtoField,
default <S, C, F> Children selectAssociation(String prefix, Class<C> child, SFunction<S, F> dtoField,
MFunc<MybatisLabel.Builder<C, F>> collection) {
String dtoFieldName = LambdaUtils.getName(dtoField);
Class<S> dtoClass = LambdaUtils.getEntityClass(dtoField);
Field field = MPJReflectionKit.getFieldMap(dtoClass).get(dtoFieldName);
Assert.isFalse(Collection.class.isAssignableFrom(field.getType()), "association 不支持集合类");
MybatisLabel.Builder<C, F> builder = new MybatisLabel.Builder<>(Objects.isNull(index) ? null : index.toString(),
MybatisLabel.Builder<C, F> builder = new MybatisLabel.Builder<>(StringUtils.isBlank(prefix) ? null : prefix,
dtoFieldName, child, field.getType(), (Class<F>) field.getType(), false);
MybatisLabel.Builder<C, F> cfBuilder = collection.apply(builder);
addLabel(cfBuilder.build());

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.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.toolkit.JR;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.TableHelper;
import lombok.Getter;
import org.apache.ibatis.session.Configuration;
@ -57,7 +57,7 @@ public class SelectCache {
if (this.hasTypeHandle) {
TableInfo info = TableHelper.get(clazz);
Assert.notNull(info, "table not find by class <%s>", clazz.getSimpleName());
this.typeHandler = getTypeHandler(JR.mpjGetConfiguration(info), tableFieldInfo);
this.typeHandler = getTypeHandler(ConfigProperties.adapter.mpjGetConfiguration(info), tableFieldInfo);
} else {
this.typeHandler = null;
}

View File

@ -19,6 +19,7 @@
<module>test-join</module>
<module>test-collection</module>
<module>test-mapping</module>
<module>test-springboot3-jdk17</module>
</modules>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
@ -75,7 +76,7 @@
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<version>1.18.26</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
@ -91,12 +92,13 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.0</version>
<version>2.14.2</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
<!-- <version>3.3.0</version>-->
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>

View File

@ -8,6 +8,7 @@ import org.springframework.context.annotation.Configuration;
/**
* mybatis-plus配置
*/
@Configuration
public class MybatisPlusConfig {

View File

@ -0,0 +1,19 @@
package com.github.yulichang.test.collection.dto;
import lombok.Data;
@Data
public class TableDTO {
private Integer id;
private String name;
private Integer aid1;
private Integer aid2;
private TableADTO table1;
private TableADTO table2;
}

View File

@ -0,0 +1,19 @@
package com.github.yulichang.test.collection.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("table_t")
public class TableT {
@TableId
private Integer id;
private Integer aid1;
private Integer aid2;
private String name;
}

View File

@ -0,0 +1,10 @@
package com.github.yulichang.test.collection.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.test.collection.entity.TableT;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface TableTMapper extends MPJBaseMapper<TableT> {
}

View File

@ -27,3 +27,7 @@ insert into table_e (id, did, `name`) values (1, 1, 'tableE1');
insert into table_e (id, did, `name`) values (2, 1, 'tableE2');
insert into table_e (id, did, `name`) values (3, 2, 'tableE3');
DELETE FROM table_t;
insert into table_t (id, aid1, aid2, `name`) values (1, 1, 2, 'tableT1');
insert into table_t (id, aid1, aid2, `name`) values (2, 1, 2, 'tableT2');
insert into table_t (id, aid1, aid2, `name`) values (3, 2, 3, 'tableT3');

View File

@ -46,3 +46,13 @@ create table table_e
`did` int not null,
`name` varchar(255) null
);
DROP TABLE IF EXISTS table_t;
create table table_t
(
id int auto_increment
primary key,
`aid1` int not null,
`aid2` int not null,
`name` varchar(255) null
);

View File

@ -1,11 +1,9 @@
package com.github.yulichang.test.collection;
import com.github.yulichang.test.collection.dto.TableADTO;
import com.github.yulichang.test.collection.dto.TableBDTO;
import com.github.yulichang.test.collection.dto.TableCDTO;
import com.github.yulichang.test.collection.dto.TableDDTO;
import com.github.yulichang.test.collection.dto.*;
import com.github.yulichang.test.collection.entity.*;
import com.github.yulichang.test.collection.mapper.TableAMapper;
import com.github.yulichang.test.collection.mapper.TableTMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
@ -28,6 +26,8 @@ class CollectionTest {
@Resource
private TableAMapper tableAMapper;
@Resource
private TableTMapper tableMapper;
@Resource
private SqlSessionFactory sqlSessionFactory;
/**
@ -82,4 +82,19 @@ class CollectionTest {
List<TableADTO> dtos1 = tableAMapper.selectJoinList(TableADTO.class, wrapper1);
System.out.println(1);
}
/**
* 映射同一张表多次
*/
@Test
void testRepeat() {
MPJLambdaWrapper<TableT> wrapper = new MPJLambdaWrapper<TableT>()
.selectAll(TableT.class)
.selectAssociation("t1", TableA.class, TableDTO::getTable1)
.selectAssociation("t2", TableA.class, TableDTO::getTable2)
.leftJoin(TableA.class, TableA::getId, TableT::getAid1)
.leftJoin(TableA.class, TableA::getId, TableT::getAid2);
List<TableDTO> dtos = tableMapper.selectJoinList(TableDTO.class, wrapper);
System.out.println(1);
}
}

View File

@ -0,0 +1,17 @@
//package com.github.yulichang.test.join.config;
//
//import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
///**
// * mp 3.3.x
// */
//@Configuration
//public class MPConfig {
//
// @Bean
// public PaginationInterceptor mybatisPlusInterceptor() {
// return new PaginationInterceptor();
// }
//}

View File

@ -1,75 +1,75 @@
package com.github.yulichang.test.join.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.github.yulichang.test.join.util.ThreadLocalUtils;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.sql.SQLException;
import java.util.Objects;
/**
* mybatis-plus配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor page = new PaginationInnerInterceptor(DbType.H2);
page.setOptimizeJoin(false);
interceptor.addInnerInterceptor(page);
interceptor.addInnerInterceptor(new SqlInterceptor());
return interceptor;
}
/**
* 校验sql
*/
public static class SqlInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
String sql = boundSql.getSql();
String s = ThreadLocalUtils.get();
if (StringUtils.isNotBlank(s) && !Objects.equals(formatSql(sql), formatSql(s))) {
System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql));
System.err.println("预期sql: " + SqlSourceBuilder.removeExtraWhitespaces(s));
throw new RuntimeException("sql error");
}
InnerInterceptor.super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
}
private String formatSql(String sql) {
if (StringUtils.isBlank(sql)) {
return sql;
}
sql = sql.replaceAll("\n", "");
sql = sql.replaceAll("\r", "");
sql = sql.replaceAll("\t", "");
return dg(sql);
}
private String dg(String str) {
if (str.contains(" ")) {
str = str.replaceAll(" ", "");
return dg(str);
}
return str;
}
}
}
//package com.github.yulichang.test.join.config;
//
//import com.baomidou.mybatisplus.annotation.DbType;
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
//import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
//import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
//import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
//import com.github.yulichang.test.join.util.ThreadLocalUtils;
//import org.apache.ibatis.builder.SqlSourceBuilder;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//
//import java.sql.SQLException;
//import java.util.Objects;
//
///**
// * mybatis-plus配置
// */
//@Configuration
//public class MybatisPlusConfig {
//
// /**
// * 分页插件
// */
// @Bean
// public MybatisPlusInterceptor mybatisPlusInterceptor() {
// MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// PaginationInnerInterceptor page = new PaginationInnerInterceptor(DbType.H2);
// page.setOptimizeJoin(false);
// interceptor.addInnerInterceptor(page);
// interceptor.addInnerInterceptor(new SqlInterceptor());
// return interceptor;
// }
//
// /**
// * 校验sql
// */
// public static class SqlInterceptor implements InnerInterceptor {
//
// @Override
// public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
// String sql = boundSql.getSql();
// String s = ThreadLocalUtils.get();
// if (StringUtils.isNotBlank(s) && !Objects.equals(formatSql(sql), formatSql(s))) {
// System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql));
// System.err.println("预期sql: " + SqlSourceBuilder.removeExtraWhitespaces(s));
// throw new RuntimeException("sql error");
// }
// InnerInterceptor.super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
// }
//
// private String formatSql(String sql) {
// if (StringUtils.isBlank(sql)) {
// return sql;
// }
// sql = sql.replaceAll("\n", "");
// sql = sql.replaceAll("\r", "");
// sql = sql.replaceAll("\t", "");
// return dg(sql);
// }
//
// private String dg(String str) {
// if (str.contains(" ")) {
// str = str.replaceAll(" ", "");
// return dg(str);
// }
// return str;
// }
// }
//}

View File

@ -42,5 +42,7 @@ public class UserDTO {
private List<AddressDTO> addressList;
private List<Integer> addressIds;
private List<UserDO> children;
}

View File

@ -8,12 +8,14 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName("address")
public class AddressDO {
public class AddressDO implements Serializable {
@TableId
private Integer id;

View File

@ -8,12 +8,14 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName("area")
public class AreaDO {
public class AreaDO implements Serializable {
@TableId
private Integer id;

View File

@ -11,6 +11,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@ -20,7 +21,7 @@ import java.util.Map;
@Accessors(chain = true)
@EqualsAndHashCode
@TableName(value = "`user`", autoResultMap = true)
public class UserDO {
public class UserDO implements Serializable {
@TableId
private Integer id;

View File

@ -5,9 +5,11 @@ import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("user_dto")
public class UserDto {
public class UserDto implements Serializable {
@TableId
private Integer id;

View File

@ -3,11 +3,12 @@ package com.github.yulichang.test.join.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.io.Serializable;
import java.util.List;
@Mapper
@SuppressWarnings("unused")
public interface MyBaseMapper<T> extends MPJBaseMapper<T> {
public interface MyBaseMapper<T extends Serializable> extends MPJBaseMapper<T> {
int insertBatchSomeColumn(List<T> entityList);
}

View File

@ -74,7 +74,6 @@ class LambdaWrapperTest {
" AND t2.del = false\n" +
" AND (t.id <= ?)\n" +
"ORDER BY t.id DESC");
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.selectCollection(AddressDO.class, UserDTO::getAddressList, addr -> addr
@ -89,6 +88,42 @@ class LambdaWrapperTest {
list.forEach(System.out::println);
}
@Test
void testJoinField() {
ThreadLocalUtils.set("SELECT t.id,\n" +
" t.pid,\n" +
" t.`name`,\n" +
" t.`json`,\n" +
" t.sex,\n" +
" t.head_img,\n" +
" t.create_time,\n" +
" t.address_id,\n" +
" t.address_id2,\n" +
" t.del,\n" +
" t.create_by,\n" +
" t.update_by,\n" +
" t1.id AS joina_id\n" +
"FROM `user` t\n" +
" LEFT JOIN address t1 ON (t1.user_id = t.id)\n" +
"WHERE t.del = false\n" +
" AND t1.del = false\n" +
" AND (t.id <= ?)\n" +
"ORDER BY t.id DESC");
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.selectCollection(AddressDO.class, UserDTO::getAddressIds, e -> e
.id(AddressDO::getId))
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.le(UserDO::getId, 10000)
.orderByDesc(UserDO::getId);
List<UserDTO> list = userMapper.selectJoinList(UserDTO.class, wrapper);
assert list.get(0).getAddressIds() != null;
list.forEach(System.out::println);
}
@Test
void testJoin1() {
@ -197,12 +232,14 @@ class LambdaWrapperTest {
"WHERE t.id = ?\n" +
" AND t.del = false\n" +
" AND (t.id <= ?)\n" +
"ORDER BY t.id ASC, t.name ASC");
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.setEntity(new UserDO() {{
"ORDER BY t.id ASC, t.`name` ASC");
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>(new UserDO() {{
setId(1);
}})
.selectAll(UserDO.class)
// .setEntity(new UserDO() {{
// setId(1);
// }})
.le(UserDO::getId, 100)
.orderByAsc(UserDO::getId, UserDO::getName);
@ -265,7 +302,7 @@ class LambdaWrapperTest {
" AND ua.del = false\n" +
" AND ub.del = false\n" +
" AND uc.del = false\n" +
" AND (ua.head_img = tt.name AND tt.id = ua.id)");
" AND (ua.head_img = tt.`name` AND tt.id = ua.id)");
MPJLambdaWrapper<UserDO> w = new MPJLambdaWrapper<UserDO>("tt")
.selectAll(UserDO.class)
.leftJoin(UserDO.class, "ua", UserDO::getId, UserDO::getPid, ext -> ext
@ -599,6 +636,18 @@ class LambdaWrapperTest {
page.getRecords().forEach(System.out::println);
}
/**
* 忽略个别查询字段
*/
@Test
void test8() {
ThreadLocalUtils.set("SELECT t.`name` FROM `user` t WHERE t.del=false AND (t.`name` = ?)");
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.select(UserDO::getName)
.eq(UserDO::getName, "ref");
userMapper.selectList(wrapper);
}
/**
* 关联查询返回map

View File

@ -0,0 +1,35 @@
package com.github.yulichang.test.mapping.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.github.yulichang.annotation.EntityMapping;
import com.github.yulichang.test.mapping.enums.Sex;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class UU {
private Integer id;
private Integer pid;
private Map<String, String> name;
private Sex sex;
private String headImg;
private Integer addressId;
private Boolean del;
@TableField(exist = false)
@EntityMapping(thisField = "pid", joinField = "id")
private UserDO pUser;
@TableField(exist = false)
@EntityMapping(thisField = "id", joinField = "pid")
private List<UserDO> userList;
}

View File

@ -1,8 +1,10 @@
package com.github.yulichang.test.mapping;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.test.mapping.entity.AddressDO;
import com.github.yulichang.test.mapping.entity.UserDO;
import com.github.yulichang.test.mapping.mapper.UserMapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@ -21,7 +23,16 @@ class MappingTest {
@Test
public void test() {
List<UserDO> dos = userMapper.selectListDeep(new QueryWrapper<>());
List<UserDO> dos = userMapper.selectRelation(e -> e.selectList(new QueryWrapper<>()), true);
System.out.println(1);
}
@Test
public void testJoin() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.selectAll(UserDO.class)
.leftJoin(AddressDO.class, AddressDO::getId, UserDO::getAddressId);
List<UserDO> dos = userMapper.selectRelation(e -> e.selectList(wrapper), true);
System.out.println(1);
}
}

View File

@ -31,6 +31,7 @@
<modules>
<module>mybatis-plus-join-boot-starter</module>
<module>mybatis-plus-join-adapter</module>
<module>mybatis-plus-join-core</module>
<module>mybatis-plus-join-annotation</module>
<module>mybatis-plus-join-test</module>