mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
fix: 修复apt问题
This commit is contained in:
parent
f8e51aa958
commit
658bb2bb59
@ -1,6 +1,8 @@
|
||||
package com.github.yulichang.apt;
|
||||
|
||||
public interface BaseColumn<T> {
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface BaseColumn<T> extends Serializable {
|
||||
|
||||
Class<T> getColumnClass();
|
||||
|
||||
|
@ -3,11 +3,12 @@ package com.github.yulichang.apt;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Column {
|
||||
public class Column implements Serializable {
|
||||
|
||||
private BaseColumn<?> root;
|
||||
|
||||
|
@ -1,51 +1,70 @@
|
||||
package com.github.yulichang.toolkit;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
|
||||
import com.github.yulichang.apt.BaseColumn;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class TableMap<K, V> {
|
||||
public class TableMap implements Serializable {
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private TableMap parent;
|
||||
|
||||
@Getter
|
||||
private final K root;
|
||||
private final BaseColumn<?> root;
|
||||
|
||||
@Getter
|
||||
private final String rootAlias;
|
||||
@Setter
|
||||
private String rootAlias;
|
||||
|
||||
private final Map<K, V> map = new HashMap<>();
|
||||
private final Map<BaseColumn<?>, String> tableMap = new LinkedHashMap<>();
|
||||
|
||||
private final List<K> list = new ArrayList<>();
|
||||
|
||||
public TableMap(K root, String rootAlias) {
|
||||
public TableMap(BaseColumn<?> root, String rootAlias) {
|
||||
this.root = root;
|
||||
this.rootAlias = rootAlias;
|
||||
}
|
||||
|
||||
public V put(K key, V value) {
|
||||
V v = this.map.put(key, value);
|
||||
if (null == v) {
|
||||
this.list.add(key);
|
||||
public String put(BaseColumn<?> key, String value) {
|
||||
return tableMap.put(key, value);
|
||||
}
|
||||
|
||||
public String get(BaseColumn<?> key) {
|
||||
return get(this, key);
|
||||
}
|
||||
|
||||
private String get(TableMap tableMap, BaseColumn<?> key) {
|
||||
if (null != key.getAlias()) {
|
||||
return key.getAlias();
|
||||
}
|
||||
return v;
|
||||
if (key == tableMap.root) {
|
||||
return tableMap.rootAlias;
|
||||
}
|
||||
String pf = tableMap.tableMap.get(key);
|
||||
if (null == pf) {
|
||||
if (tableMap.parent == null) {
|
||||
throw ExceptionUtils.mpe("table not found %s", key.getColumnClass().getName());
|
||||
} else {
|
||||
return get(tableMap.parent, key);
|
||||
}
|
||||
}
|
||||
return pf;
|
||||
}
|
||||
|
||||
public V get(K key) {
|
||||
return this.map.get(key);
|
||||
}
|
||||
|
||||
public List<K> keyList() {
|
||||
return this.list;
|
||||
public Collection<BaseColumn<?>> keyList() {
|
||||
return tableMap.keySet();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this.map.isEmpty();
|
||||
return this.tableMap.isEmpty();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.map.clear();
|
||||
this.list.clear();
|
||||
this.tableMap.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.annotation.OrderBy;
|
||||
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
||||
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
||||
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.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
@ -109,7 +108,7 @@ public abstract class AptAbstractWrapper<T, Children extends AptAbstractWrapper<
|
||||
* apt别名对应
|
||||
*/
|
||||
@Getter
|
||||
protected TableMap<BaseColumn<?>, String> aptIndex;
|
||||
protected TableMap aptIndex;
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
@ -185,19 +184,6 @@ public abstract class AptAbstractWrapper<T, Children extends AptAbstractWrapper<
|
||||
return decode;
|
||||
}
|
||||
|
||||
|
||||
protected String getPrefix(BaseColumn<?> baseColumn) {
|
||||
if (Objects.nonNull(baseColumn.getAlias())) {
|
||||
return baseColumn.getAlias();
|
||||
}
|
||||
if (aptIndex.getRoot() == baseColumn) {
|
||||
return aptIndex.getRootAlias();
|
||||
}
|
||||
String pf = aptIndex.get(baseColumn);
|
||||
Assert.notEmpty(pf, "table not find %s", baseColumn.getColumnClass().getName());
|
||||
return pf;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String columnsToString(Column... columns) {
|
||||
return Arrays.stream(columns).map(this::columnToString)
|
||||
@ -210,7 +196,7 @@ public abstract class AptAbstractWrapper<T, Children extends AptAbstractWrapper<
|
||||
if (Objects.nonNull(pf)) {
|
||||
return pf + StringPool.DOT + getCache(column).getColumn();
|
||||
}
|
||||
return getPrefix(column.getRoot()) + StringPool.DOT + getCache(column).getColumn();
|
||||
return this.aptIndex.get(column.getRoot()) + StringPool.DOT + getCache(column).getColumn();
|
||||
}
|
||||
|
||||
protected SelectCache getCache(Column fn) {
|
||||
@ -257,7 +243,7 @@ public abstract class AptAbstractWrapper<T, Children extends AptAbstractWrapper<
|
||||
if (aptIndex.isEmpty()) {
|
||||
return StringPool.EMPTY;
|
||||
}
|
||||
return aptIndex.keyList().stream().map(key -> LogicInfoUtils.getLogicInfoApt(key.getColumnClass(), getPrefix(key)))
|
||||
return aptIndex.keyList().stream().map(key -> LogicInfoUtils.getLogicInfoApt(key.getColumnClass(), this.aptIndex.get(key)))
|
||||
.collect(Collectors.joining(StringPool.SPACE));
|
||||
}
|
||||
return StringPool.EMPTY;
|
||||
@ -408,7 +394,7 @@ public abstract class AptAbstractWrapper<T, Children extends AptAbstractWrapper<
|
||||
lastSql = SharedString.emptyString();
|
||||
sqlComment = SharedString.emptyString();
|
||||
sqlFirst = SharedString.emptyString();
|
||||
aptIndex = new TableMap<>(this.baseColumn, this.alias);
|
||||
aptIndex = new TableMap(this.baseColumn, this.alias);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,7 +94,7 @@ public class AptQueryWrapper<T> extends AptAbstractWrapper<T, AptQueryWrapper<T>
|
||||
protected AptQueryWrapper(T entity, BaseColumn<T> baseColumn, SharedString sqlSelect, AtomicInteger paramNameSeq,
|
||||
Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
|
||||
SharedString lastSql, SharedString sqlComment, SharedString sqlFirst,
|
||||
TableMap<BaseColumn<?>, String> aptIndex, Integer index, String keyWord, Class<?> joinClass, String tableName,
|
||||
TableMap aptIndex, Integer index, String keyWord, Class<?> joinClass, String tableName,
|
||||
BiPredicate<Object, IfExistsSqlKeyWordEnum> IfExists) {
|
||||
super(baseColumn);
|
||||
super.setEntity(entity);
|
||||
@ -108,7 +108,9 @@ public class AptQueryWrapper<T> extends AptAbstractWrapper<T, AptQueryWrapper<T>
|
||||
this.lastSql = lastSql;
|
||||
this.sqlComment = sqlComment;
|
||||
this.sqlFirst = sqlFirst;
|
||||
this.aptIndex = aptIndex;
|
||||
if (aptIndex != null) {
|
||||
this.aptIndex = aptIndex;
|
||||
}
|
||||
this.index = index;
|
||||
this.keyWord = keyWord;
|
||||
this.joinClass = joinClass;
|
||||
@ -188,20 +190,17 @@ public class AptQueryWrapper<T> extends AptAbstractWrapper<T, AptQueryWrapper<T>
|
||||
* 子查询
|
||||
*/
|
||||
public <E, F> AptQueryWrapper<T> selectSub(BaseColumn<E> baseColumn, Consumer<AptQueryWrapper<E>> consumer, SFunction<F, ?> alias) {
|
||||
return selectSub(baseColumn, ConfigProperties.subQueryAlias, consumer, alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* 子查询
|
||||
*/
|
||||
public <E, F> AptQueryWrapper<T> selectSub(BaseColumn<E> baseColumn, String st, Consumer<AptQueryWrapper<E>> consumer, SFunction<F, ?> alias) {
|
||||
AptQueryWrapper<E> wrapper = new AptQueryWrapper<E>(null, baseColumn, SharedString.emptyString(),
|
||||
paramNameSeq, paramNameValuePairs, new MergeSegments(), new SharedString(this.paramAlias
|
||||
.getStringValue()), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(),
|
||||
this.aptIndex, null, null, null, null, ifExists) {
|
||||
null, null, null, null, null, ifExists) {
|
||||
};
|
||||
wrapper.alias = st;
|
||||
wrapper.subTableAlias = st;
|
||||
wrapper.aptIndex.setParent(this.aptIndex);
|
||||
if (null == baseColumn.getAlias()) {
|
||||
wrapper.alias = ConfigProperties.subQueryAlias;
|
||||
wrapper.aptIndex.setRootAlias(ConfigProperties.subQueryAlias);
|
||||
}
|
||||
wrapper.subTableAlias = ConfigProperties.subQueryAlias;
|
||||
consumer.accept(wrapper);
|
||||
addCustomWrapper(wrapper);
|
||||
String name = LambdaUtils.getName(alias);
|
||||
@ -279,11 +278,11 @@ public class AptQueryWrapper<T> extends AptAbstractWrapper<T, AptQueryWrapper<T>
|
||||
}
|
||||
if (i.isFunc()) {
|
||||
return String.format(i.getFunc().getSql(), Arrays.stream(i.getColumns()).map(c ->
|
||||
getPrefix(c.getRoot()) + StringPool.DOT + i.getColumn()).toArray()) + Constant.AS + i.getAlias();
|
||||
this.aptIndex.get(c.getRoot()) + StringPool.DOT + i.getColumn()).toArray()) + Constant.AS + i.getAlias();
|
||||
} else {
|
||||
String prefix;
|
||||
if (null == i.getTableAlias() && null != i.getBaseColumn()) {
|
||||
prefix = getPrefix(i.getBaseColumn());
|
||||
prefix = this.aptIndex.get(i.getBaseColumn());
|
||||
} else {
|
||||
prefix = i.getTableAlias();
|
||||
}
|
||||
|
@ -528,13 +528,11 @@ public abstract class JoinAbstractWrapper<T, Children extends JoinAbstractWrappe
|
||||
}
|
||||
|
||||
protected <X, S> Children addCondition(boolean condition, Column column, SqlKeyword sqlKeyword, Column val) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, columnToSqlSegment(val)
|
||||
));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, columnToSqlSegment(val)));
|
||||
}
|
||||
|
||||
protected Children addCondition(boolean condition, String column, SqlKeyword sqlKeyword, Object val) {
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword,
|
||||
() -> formatParam(null, val)));
|
||||
return maybeDo(condition, () -> appendSqlSegments(columnToSqlSegment(column), sqlKeyword, () -> formatParam(null, val)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,13 +1,14 @@
|
||||
package com.github.yulichang.test.join.apt.unit;
|
||||
|
||||
import com.github.yulichang.test.join.entity.AddressDO;
|
||||
import com.github.yulichang.test.join.entity.AreaDO;
|
||||
import com.github.yulichang.test.join.entity.UserDO;
|
||||
import com.github.yulichang.test.join.entity.apt.AddressDOCol;
|
||||
import com.github.yulichang.test.join.entity.apt.AreaDOCol;
|
||||
import com.github.yulichang.test.join.entity.apt.UserDOCol;
|
||||
import com.github.yulichang.test.util.EnabledIfConfig;
|
||||
import com.github.yulichang.test.util.Reset;
|
||||
import com.github.yulichang.test.util.ThreadLocalUtils;
|
||||
import com.github.yulichang.toolkit.JoinWrappers;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.github.yulichang.wrapper.apt.AptQueryWrapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@ -29,39 +30,52 @@ public class SelectSubTest {
|
||||
@Test
|
||||
void sub() {
|
||||
ThreadLocalUtils.set("SELECT (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id AND st.id = ?) LIMIT 1) AS id, (SELECT st.id FROM `user` st WHERE st.del = false AND (st.id = t.id AND st.id = ?) LIMIT 1) AS name FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
|
||||
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
|
||||
.selectSub(UserDO.class, w -> w.select(UserDO::getId)
|
||||
.eq(UserDO::getId, UserDO::getId)
|
||||
.eq(UserDO::getId, 2)
|
||||
UserDOCol u = new UserDOCol();
|
||||
UserDOCol sb = new UserDOCol();
|
||||
UserDOCol sb2 = new UserDOCol();
|
||||
AddressDOCol addr = new AddressDOCol();
|
||||
|
||||
AptQueryWrapper<UserDO> wrapper = JoinWrappers.apt(u)
|
||||
.selectSub(sb, w -> w.select(sb.id)
|
||||
.eq(sb.id, u.id)
|
||||
.eq(sb.id, 2)
|
||||
.last("limit 1"), UserDO::getId)
|
||||
.selectSub(UserDO.class, w -> w.select(UserDO::getId)
|
||||
.eq(UserDO::getId, UserDO::getId)
|
||||
.eq(UserDO::getId, 3)
|
||||
.selectSub(sb2, w -> w.select(sb2.id)
|
||||
.eq(sb2.id, u.id)
|
||||
.eq(sb2.id, 3)
|
||||
.last("limit 1"), UserDO::getName)
|
||||
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
|
||||
.le(UserDO::getId, 100);
|
||||
.leftJoin(addr, addr.userId, u.id)
|
||||
.le(u.id, 100);
|
||||
wrapper.list();
|
||||
|
||||
UserDOCol u1 = new UserDOCol();
|
||||
AddressDOCol addr1 = new AddressDOCol();
|
||||
AreaDOCol area = new AreaDOCol();
|
||||
|
||||
ThreadLocalUtils.set("SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = t1.id) LIMIT 1) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
|
||||
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
|
||||
.selectSub(AreaDO.class, w -> w.select(AreaDO::getId)
|
||||
.eq(AreaDO::getId, AddressDO::getId)
|
||||
AptQueryWrapper<UserDO> wrapper1 = JoinWrappers.apt(u1)
|
||||
.selectSub(area, w -> w.select(area.id)
|
||||
.eq(area.id, addr1.id)
|
||||
.last("limit 1"), UserDO::getId)
|
||||
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
|
||||
.le(UserDO::getId, 100);
|
||||
.leftJoin(addr1, addr1.userId, u1.id)
|
||||
.le(u1.id, 100);
|
||||
wrapper1.list();
|
||||
}
|
||||
|
||||
@Test
|
||||
void sub1() {
|
||||
ThreadLocalUtils.set("SELECT (SELECT st.id FROM `area` st WHERE st.del = false AND (st.id = t1.id) LIMIT 1) AS id FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id) WHERE t.del = false AND t1.del = false AND (t.id <= ?)");
|
||||
MPJLambdaWrapper<UserDO> wrapper1 = JoinWrappers.lambda(UserDO.class)
|
||||
.selectSub(AreaDO.class, w -> w.select(AreaDO::getId)
|
||||
.eq(AreaDO::getId, AddressDO::getId)
|
||||
UserDOCol u = new UserDOCol();
|
||||
AddressDOCol addr = new AddressDOCol();
|
||||
AreaDOCol ar = new AreaDOCol();
|
||||
|
||||
AptQueryWrapper<UserDO> wrapper1 = JoinWrappers.apt(u)
|
||||
.selectSub(ar, w -> w.select(ar.id)
|
||||
.eq(ar.id, addr.id)
|
||||
.setTableName(t -> "`" + t + "`")
|
||||
.last("limit 1"), UserDO::getId)
|
||||
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
|
||||
.le(UserDO::getId, 100);
|
||||
.leftJoin(addr, addr.userId, u.id)
|
||||
.le(u.id, 100);
|
||||
wrapper1.list();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,14 @@
|
||||
package com.github.yulichang.test.join.apt.unit;
|
||||
|
||||
import com.github.yulichang.test.join.entity.AddressDO;
|
||||
import com.github.yulichang.test.join.entity.AreaDO;
|
||||
import com.github.yulichang.test.join.entity.UserDO;
|
||||
import com.github.yulichang.test.join.entity.apt.AddressDOCol;
|
||||
import com.github.yulichang.test.join.entity.apt.AreaDOCol;
|
||||
import com.github.yulichang.test.join.entity.apt.UserDOCol;
|
||||
import com.github.yulichang.test.util.Reset;
|
||||
import com.github.yulichang.test.util.ThreadLocalUtils;
|
||||
import com.github.yulichang.toolkit.JoinWrappers;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import com.github.yulichang.wrapper.apt.AptQueryWrapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
@ -25,20 +27,26 @@ public class UnionTest {
|
||||
@Test
|
||||
void unionAll1() {
|
||||
ThreadLocalUtils.set("SELECT t.id FROM `user` t WHERE t.del = false AND (t.id = ?) UNION ALL SELECT t.id FROM address t WHERE (t.id = ?) UNION ALL SELECT (SELECT st.id FROM area st WHERE st.del = false AND (st.id = ? AND (st.id = ?))) AS id FROM area t WHERE t.del = false AND (t.id = ? AND (t.id = ?))");
|
||||
MPJLambdaWrapper<UserDO> wrapper = JoinWrappers.lambda(UserDO.class)
|
||||
.select(UserDO::getId)
|
||||
.eq(UserDO::getId, 1)
|
||||
.unionAll(AddressDO.class, union -> union
|
||||
.select(AddressDO::getId)
|
||||
|
||||
UserDOCol u = new UserDOCol();
|
||||
AddressDOCol addr = new AddressDOCol();
|
||||
AreaDOCol area = new AreaDOCol();
|
||||
AreaDOCol areaSb = new AreaDOCol();
|
||||
|
||||
AptQueryWrapper<UserDO> wrapper = JoinWrappers.apt(u)
|
||||
.select(u.id)
|
||||
.eq(u.id, 1)
|
||||
.unionAll(addr, union -> union
|
||||
.select(addr.id)
|
||||
.disableLogicDel()
|
||||
.eq(UserDO::getId, 2))
|
||||
.unionAll(AreaDO.class, union -> union
|
||||
.selectSub(AreaDO.class, sub -> sub
|
||||
.select(AreaDO::getId)
|
||||
.eq(AreaDO::getId, 3)
|
||||
.and(and -> and.eq(AreaDO::getId, 4)), AreaDO::getId)
|
||||
.eq(AreaDO::getId, 5)
|
||||
.and(and -> and.eq(AreaDO::getId, 6)));
|
||||
.eq(addr.id, 2))
|
||||
.unionAll(area, union -> union
|
||||
.selectSub(areaSb, sub -> sub
|
||||
.select(areaSb.id)
|
||||
.eq(areaSb.id, 3)
|
||||
.and(and -> and.eq(areaSb.id, 4)), AreaDO::getId)
|
||||
.eq(area.id, 5)
|
||||
.and(and -> and.eq(area.id, 6)));
|
||||
List<UserDO> list = wrapper.list();
|
||||
assert list.size() == 2 && list.get(0).getId() != null;
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class UnionTest {
|
||||
.unionAll(AddressDO.class, union -> union
|
||||
.select(AddressDO::getId)
|
||||
.disableLogicDel()
|
||||
.eq(UserDO::getId, 2))
|
||||
.eq(AddressDO::getId, 2))
|
||||
.unionAll(AreaDO.class, union -> union
|
||||
.selectSub(AreaDO.class, sub -> sub
|
||||
.select(AreaDO::getId)
|
||||
|
Loading…
x
Reference in New Issue
Block a user