diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/AptAbstractWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/AptAbstractWrapper.java index 1b82c6b..d307cc6 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/AptAbstractWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/AptAbstractWrapper.java @@ -389,10 +389,10 @@ public abstract class AptAbstractWrapper extends AptAbstractWrapper if (ArrayUtils.isEmpty(apply.getValues())) { formatSql = sql; } else { - formatSql = formatSqlMaybeWithParam(sql, null, apply.getValues()); + formatSql = formatSqlMaybeWithParam(sql, apply.getValues()); } getSelectColum().add(new SelectApt(apply.getColumns(), () -> formatSql, alias)); return typedThis; diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/JoinAbstractWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/JoinAbstractWrapper.java index 33d3aa0..cad61c8 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/JoinAbstractWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/apt/JoinAbstractWrapper.java @@ -33,6 +33,8 @@ import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*; @@ -281,7 +283,7 @@ public abstract class JoinAbstractWrapper appendSqlSegments(APPLY, - () -> formatSqlMaybeWithParam(applySql, null, values))); + () -> formatSqlMaybeWithParam(applySql, values))); } public Children applyFunc(String applySql, MFunction consumerFunction, Object... values) { @@ -294,7 +296,7 @@ public abstract class JoinAbstractWrapper { AptConsumer apply = consumerFunction.apply(new AptConsumer()); return formatSqlMaybeWithParam(String.format(applySql, - Arrays.stream(apply.getColumns()).map(this::columnToString).toArray()), null, + Arrays.stream(apply.getColumns()).map(this::columnToString).toArray()), ArrayUtils.isNotEmpty(values) ? values : apply.getValues()); })); } @@ -333,7 +335,7 @@ public abstract class JoinAbstractWrapper appendSqlSegments(EXISTS, - () -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, null, values)))); + () -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, values)))); } @Override @@ -481,7 +483,7 @@ public abstract class JoinAbstractWrapper appendSqlSegments(HAVING, - () -> formatSqlMaybeWithParam(sqlHaving, null, params))); + () -> formatSqlMaybeWithParam(sqlHaving, params))); } @Override @@ -573,21 +575,27 @@ public abstract class JoinAbstractWrapper * 支持 "{0}" 这种,或者 "sql {0} sql" 这种 * - * @param sqlStr 可能是sql片段 - * @param mapping 例如: "javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler" 这种 - * @param params 参数 + * @param sqlStr 可能是sql片段 + * @param params 参数 * @return sql片段 */ - @SuppressWarnings("SameParameterValue") - protected final String formatSqlMaybeWithParam(String sqlStr, String mapping, Object... params) { + protected final String formatSqlMaybeWithParam(String sqlStr, Object... params) { if (StrUtils.isBlank(sqlStr)) { - // todo 何时会这样? return null; } if (ArrayUtils.isNotEmpty(params)) { for (int i = 0; i < params.length; ++i) { - final String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; - sqlStr = sqlStr.replace(target, formatParam(mapping, params[i])); + String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; + if (sqlStr.contains(target)) { + sqlStr = sqlStr.replace(target, formatParam(null, params[i])); + } else { + Matcher matcher = Pattern.compile("[{]" + i + ",[a-zA-Z0-9.,=]+}").matcher(sqlStr); + if (!matcher.find()) { + throw ExceptionUtils.mpe("Please check the syntax correctness! sql not contains: \"%s\"", target); + } + String group = matcher.group(); + sqlStr = sqlStr.replace(group, formatParam(group.substring(target.length(), group.length() - 1), params[i])); + } } } return sqlStr; diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtAbstractLambdaWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtAbstractLambdaWrapper.java index dc4e06d..04cc688 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtAbstractLambdaWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtAbstractLambdaWrapper.java @@ -435,10 +435,10 @@ public abstract class KtAbstractLambdaWrapper appendSqlSegments(APPLY, - () -> formatSqlMaybeWithParam(applySql, null, values))); + () -> formatSqlMaybeWithParam(applySql, values))); } public Children applyFunc(String applySql, Function consumerFunction, Object... values) { @@ -316,7 +318,8 @@ public abstract class KtAbstractWrapper appendSqlSegments(APPLY, () -> formatSqlMaybeWithParam(String.format(applySql, Arrays.stream(consumerFunction.apply(new FuncArgs())).map(func -> - columnToString(index, null, (KProperty) func.getProperty(), false, PrefixEnum.CD_FIRST)).toArray()), null, values))); + columnToString(index, null, (KProperty) func.getProperty(), + false, PrefixEnum.CD_FIRST)).toArray()), values))); } @Override @@ -353,7 +356,7 @@ public abstract class KtAbstractWrapper appendSqlSegments(EXISTS, - () -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, null, values)))); + () -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, values)))); } @Override @@ -492,7 +495,7 @@ public abstract class KtAbstractWrapper appendSqlSegments(HAVING, - () -> formatSqlMaybeWithParam(sqlHaving, null, params))); + () -> formatSqlMaybeWithParam(sqlHaving, params))); } @Override @@ -591,21 +594,28 @@ public abstract class KtAbstractWrapper * 支持 "{0}" 这种,或者 "sql {0} sql" 这种 * - * @param sqlStr 可能是sql片段 - * @param mapping 例如: "javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler" 这种 - * @param params 参数 + * @param sqlStr 可能是sql片段 + * @param params 参数 * @return sql片段 */ @SuppressWarnings("SameParameterValue") - protected final String formatSqlMaybeWithParam(String sqlStr, String mapping, Object... params) { + protected final String formatSqlMaybeWithParam(String sqlStr, Object... params) { if (StrUtils.isBlank(sqlStr)) { - // todo 何时会这样? return null; } if (ArrayUtils.isNotEmpty(params)) { for (int i = 0; i < params.length; ++i) { - final String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; - sqlStr = sqlStr.replace(target, formatParam(mapping, params[i])); + String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; + if (sqlStr.contains(target)) { + sqlStr = sqlStr.replace(target, formatParam(null, params[i])); + } else { + Matcher matcher = Pattern.compile("[{]" + i + ",[a-zA-Z0-9.,=]+}").matcher(sqlStr); + if (!matcher.find()) { + throw ExceptionUtils.mpe("Please check the syntax correctness! sql not contains: \"%s\"", target); + } + String group = matcher.group(); + sqlStr = sqlStr.replace(group, formatParam(group.substring(target.length(), group.length() - 1), params[i])); + } } } return sqlStr; diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtLambdaWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtLambdaWrapper.java index 3ebf9a2..c2a7f43 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtLambdaWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/extension/kt/KtLambdaWrapper.java @@ -243,7 +243,7 @@ public class KtLambdaWrapper extends KtAbstractLambdaWrapper formatSql, apply.getFuncArg(), isHasAlias(), getAlias())); diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java index e348b5b..30ee74e 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJLambdaQueryWrapper.java @@ -24,6 +24,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -391,10 +393,33 @@ public class MPJLambdaQueryWrapper extends AbstractLambdaWrapper join(String keyWord, boolean condition, String joinSql) { + public MPJLambdaQueryWrapper join(String keyWord, boolean condition, String joinSql, Object... args) { if (condition) { - from.setStringValue(from.getStringValue() + keyWord + joinSql); + from.setStringValue(from.getStringValue() + keyWord + mpjFormatSqlMaybeWithParam(joinSql, args)); } return typedThis; } + + @SuppressWarnings("DuplicatedCode") + protected final String mpjFormatSqlMaybeWithParam(String sqlStr, Object... params) { + if (StrUtils.isBlank(sqlStr)) { + return null; + } + if (ArrayUtils.isNotEmpty(params)) { + for (int i = 0; i < params.length; ++i) { + String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; + if (sqlStr.contains(target)) { + sqlStr = sqlStr.replace(target, formatParam(null, params[i])); + } else { + Matcher matcher = Pattern.compile("[{]" + i + ",[a-zA-Z0-9.,=]+}").matcher(sqlStr); + if (!matcher.find()) { + throw ExceptionUtils.mpe("Please check the syntax correctness! sql not contains: \"%s\"", target); + } + String group = matcher.group(); + sqlStr = sqlStr.replace(group, formatParam(group.substring(target.length(), group.length() - 1), params[i])); + } + } + } + return sqlStr; + } } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java index 463417c..7e78db7 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/MPJQueryWrapper.java @@ -31,6 +31,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiPredicate; import java.util.function.Function; import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; /** @@ -408,10 +410,34 @@ public class MPJQueryWrapper extends AbstractWrapper join(String keyWord, boolean condition, String joinSql) { + public MPJQueryWrapper join(String keyWord, boolean condition, String joinSql, Object... params) { if (condition) { - from.setStringValue(from.getStringValue() + StringPool.SPACE + keyWord + StringPool.SPACE + joinSql); + from.setStringValue(from.getStringValue() + StringPool.SPACE + keyWord + + StringPool.SPACE + mpjFormatSqlMaybeWithParam(joinSql, params)); } return typedThis; } + + @SuppressWarnings("DuplicatedCode") + protected final String mpjFormatSqlMaybeWithParam(String sqlStr, Object... params) { + if (StrUtils.isBlank(sqlStr)) { + return null; + } + if (ArrayUtils.isNotEmpty(params)) { + for (int i = 0; i < params.length; ++i) { + String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; + if (sqlStr.contains(target)) { + sqlStr = sqlStr.replace(target, formatParam(null, params[i])); + } else { + Matcher matcher = Pattern.compile("[{]" + i + ",[a-zA-Z0-9.,=]+}").matcher(sqlStr); + if (!matcher.find()) { + throw ExceptionUtils.mpe("Please check the syntax correctness! sql not contains: \"%s\"", target); + } + String group = matcher.group(); + sqlStr = sqlStr.replace(group, formatParam(group.substring(target.length(), group.length() - 1), params[i])); + } + } + } + return sqlStr; + } } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/interfaces/StringJoin.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/interfaces/StringJoin.java index 378db91..3d82518 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/interfaces/StringJoin.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/query/interfaces/StringJoin.java @@ -16,10 +16,19 @@ public interface StringJoin extends MPJBaseJoin { return leftJoin(true, joinSql); } + default Children leftJoin(String joinSql, Object... args) { + return leftJoin(true, joinSql, args); + } + + default Children leftJoin(boolean condition, String joinSql) { return join(Constant.LEFT_JOIN, condition, joinSql); } + default Children leftJoin(boolean condition, String joinSql, Object... args) { + return join(Constant.LEFT_JOIN, condition, joinSql, args); + } + /** * right join @@ -28,10 +37,17 @@ public interface StringJoin extends MPJBaseJoin { return rightJoin(true, joinSql); } + default Children rightJoin(String joinSql, Object... args) { + return rightJoin(true, joinSql, args); + } + default Children rightJoin(boolean condition, String joinSql) { return join(Constant.RIGHT_JOIN, condition, joinSql); } + default Children rightJoin(boolean condition, String joinSql, Object... args) { + return join(Constant.RIGHT_JOIN, condition, joinSql, args); + } /** * inner join @@ -40,10 +56,18 @@ public interface StringJoin extends MPJBaseJoin { return innerJoin(true, joinSql); } + default Children innerJoin(String joinSql, Object... args) { + return innerJoin(true, joinSql, args); + } + default Children innerJoin(boolean condition, String joinSql) { return join(Constant.INNER_JOIN, condition, joinSql); } + default Children innerJoin(boolean condition, String joinSql, Object... args) { + return join(Constant.INNER_JOIN, condition, joinSql, args); + } + /** * full join */ @@ -51,9 +75,23 @@ public interface StringJoin extends MPJBaseJoin { return fullJoin(true, joinSql); } + default Children fullJoin(String joinSql, Object... args) { + return fullJoin(true, joinSql, args); + } + default Children fullJoin(boolean condition, String joinSql) { return join(Constant.FULL_JOIN, condition, joinSql); } - Children join(String keyWord, boolean condition, String joinSql); + default Children fullJoin(boolean condition, String joinSql, Object... args) { + return join(Constant.FULL_JOIN, condition, joinSql, args); + } + + default Children join(String keyWord, boolean condition, String joinSql) { + return join(keyWord, condition, joinSql, new Object[0]); + } + + default Children join(String keyWord, boolean condition, String joinSql, Object... args){ + return null; + } } diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/JoinAbstractLambdaWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/JoinAbstractLambdaWrapper.java index c69a334..ca42acb 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/JoinAbstractLambdaWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/JoinAbstractLambdaWrapper.java @@ -488,10 +488,10 @@ public abstract class JoinAbstractLambdaWrapper appendSqlSegments(APPLY, - () -> formatSqlMaybeWithParam(applySql, null, values))); + () -> formatSqlMaybeWithParam(applySql, values))); } public Children applyFunc(String applySql, MFunction consumerFunction, Object... values) { @@ -415,7 +417,7 @@ public abstract class JoinAbstractWrapper appendSqlSegments(EXISTS, - () -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, null, values)))); + () -> String.format("(%s)", formatSqlMaybeWithParam(existsSql, values)))); } @Override @@ -727,7 +729,7 @@ public abstract class JoinAbstractWrapper appendSqlSegments(HAVING, - () -> formatSqlMaybeWithParam(sqlHaving, null, params))); + () -> formatSqlMaybeWithParam(sqlHaving, params))); } @Override @@ -831,21 +833,27 @@ public abstract class JoinAbstractWrapper * 支持 "{0}" 这种,或者 "sql {0} sql" 这种 * - * @param sqlStr 可能是sql片段 - * @param mapping 例如: "javaType=int,jdbcType=NUMERIC,typeHandler=xxx.xxx.MyTypeHandler" 这种 - * @param params 参数 + * @param sqlStr 可能是sql片段 + * @param params 参数 * @return sql片段 */ - @SuppressWarnings("SameParameterValue") - protected final String formatSqlMaybeWithParam(String sqlStr, String mapping, Object... params) { + protected final String formatSqlMaybeWithParam(String sqlStr, Object... params) { if (StrUtils.isBlank(sqlStr)) { - // todo 何时会这样? return null; } if (ArrayUtils.isNotEmpty(params)) { for (int i = 0; i < params.length; ++i) { - final String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; - sqlStr = sqlStr.replace(target, formatParam(mapping, params[i])); + String target = Constants.LEFT_BRACE + i + Constants.RIGHT_BRACE; + if (sqlStr.contains(target)) { + sqlStr = sqlStr.replace(target, formatParam(null, params[i])); + } else { + Matcher matcher = Pattern.compile("[{]" + i + ",[a-zA-Z0-9.,=]+}").matcher(sqlStr); + if (!matcher.find()) { + throw ExceptionUtils.mpe("Please check the syntax correctness! sql not contains: \"%s\"", target); + } + String group = matcher.group(); + sqlStr = sqlStr.replace(group, formatParam(group.substring(target.length(), group.length() - 1), params[i])); + } } } return sqlStr; diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java index cf4a320..7867483 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/MPJLambdaWrapper.java @@ -231,7 +231,7 @@ public class MPJLambdaWrapper extends JoinAbstractLambdaWrapper formatSql, funcConsumer.getArgs(), isHasAlias(), getAlias())); diff --git a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/UpdateJoinWrapper.java b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/UpdateJoinWrapper.java index d4eae6b..45d6bf6 100644 --- a/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/UpdateJoinWrapper.java +++ b/mybatis-plus-join-core/src/main/java/com/github/yulichang/wrapper/UpdateJoinWrapper.java @@ -165,7 +165,7 @@ public class UpdateJoinWrapper extends JoinAbstractLambdaWrapper tableList.getPrefixByClass(LambdaUtils.getEntityClass(f)) + Constants.DOT + getCache(f).getColumn()).toArray()); - return formatSqlMaybeWithParam(col, null, i.args); + return formatSqlMaybeWithParam(col, i.args); } else { String col = tableList.getPrefixByClass(LambdaUtils.getEntityClass(i.getColumn())) + Constants.DOT + getCache(i.getColumn()).getColumn(); diff --git a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/unit/JoinTest.java b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/unit/JoinTest.java index aff25e2..900777b 100644 --- a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/unit/JoinTest.java +++ b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/unit/JoinTest.java @@ -92,6 +92,38 @@ public class JoinTest { .list(UserDTO.class); } + @Test + void joinTest2() { + ThreadLocalUtils.set(""" + SELECT + t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, + t.address_id, t.address_id2, t.del, t.create_by, t.update_by + FROM `user` t + LEFT JOIN address t1 ON t1.id > ? + WHERE t.del = false AND (t.id <= ?) + """); + JoinWrappers.lambda(UserDO.class) + .selectAll() + .leftJoin("address t1 on t1.id > {0}", 0) + .le(AddressDO::getId, 10000) + .list(UserDTO.class); + + ThreadLocalUtils.set(""" + SELECT + t.id, t.pid, t.`name`, t.`json`, t.sex, t.head_img, t.create_time, + t.address_id, t.address_id2, t.del, t.create_by, t.update_by + FROM `user` t + LEFT JOIN address t1 ON t1.id > 0 + WHERE t.del = false AND (t.id <= ?) + """); + JoinWrappers.lambda(UserDO.class) + .selectAll() + .leftJoin("address t1 on t1.id > 0") + .le(AddressDO::getId, 10000) + .list(UserDTO.class); + } + + @Test @SuppressWarnings("deprecation")