Skip to content

Instantly share code, notes, and snippets.

@xtulnx
Last active August 22, 2022 02:00
Show Gist options
  • Save xtulnx/cda1fb3cfd441431a12bd38b6b8b7f51 to your computer and use it in GitHub Desktop.
Save xtulnx/cda1fb3cfd441431a12bd38b6b8b7f51 to your computer and use it in GitHub Desktop.
mybatis-plus 的查询增强:多个子查询
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* mybatis 多查询封装。引用示例
* <pre>
* Mapper接口定义:
* List<T> pageList(Page<T> page, @Param("more") MoreQueryWrapper more, @Param("column")String column, @Param("order")String order);
*
* XML中引用
* ${more.q.t2.customSqlSegment} -- 额外的查询 more.must("t2")
* ${more.main.customSqlSegment} -- 默认 more.getMain()
*
* Java中申明
* MoreQueryWrapper<T> more = MoreQueryWrapper.more();
* more.getMain().lt("age",35);
* more.must("t2").eq("id",123);
* more.resetAliasPrefix("more"); // 默认查询对象名称是 qw ,改名时还需要这样调用
*
* </pre>
*
*
* Created by liao on 2022-07-07.
*/
@Data
public class MoreQueryWrapper<TM> {
private QueryWrapper<TM> main;
private HashMap<String, QueryWrapperWithAlias<?>> qw;
private SafeMapGetter q;
public MoreQueryWrapper()
{
this(new QueryWrapperWithAlias<TM>());
}
public MoreQueryWrapper(QueryWrapper<TM> main)
{
this.main = main;
this.qw = new HashMap<>();
this.q = new SafeMapGetter(this.qw);
}
public <T> QueryWrapperWithAlias<T> must(String key)
{
synchronized (this) {
if (qw.containsKey(key)) {
return (QueryWrapperWithAlias<T>) qw.get(key);
}
QueryWrapperWithAlias<T> q = new QueryWrapperWithAlias<>();
qw.put(key, q);
return q;
}
}
/**
* 对子查询统一设置前缀
*/
public void resetAliasPrefix(String prefix)
{
synchronized (this) {
String k1 = String.join(".", prefix, "q", "");
for (String k : qw.keySet()) {
QueryWrapperWithAlias<?> q1 = qw.get(k);
if (q1 != null) {
q1.setAlias(k1 + k);
}
}
if (main instanceof QueryWrapperWithAlias) {
((QueryWrapperWithAlias) main).setAlias(prefix + ".main");
}
}
}
public static <T> MoreQueryWrapper<T> more()
{
return new MoreQueryWrapper<T>();
}
public static <T> MoreQueryWrapper<T> more(QueryWrapper<T> main)
{
return new MoreQueryWrapper<T>(main);
}
public static final class SafeMapGetter extends HashMap<String, QueryWrapper<?>> {
private final HashMap<String, QueryWrapperWithAlias<?>> qw;
private SafeMapGetter(HashMap<String, QueryWrapperWithAlias<?>> qw)
{
this.qw = qw;
}
@Override
public QueryWrapper<?> get(Object key)
{
synchronized (this) {
if (qw != null && qw.containsKey(key)) {
return qw.get(key);
}
return Wrappers.emptyWrapper();
}
}
}
@Data
public static class QueryWrapperWithAlias<T> extends QueryWrapper<T> {
private String alias;
private int mark;
public QueryWrapperWithAlias()
{
this(null);
}
public QueryWrapperWithAlias(String alias)
{
this.alias = alias;
}
@Override
public Map<String, Object> getParamNameValuePairs()
{
return paramNameValuePairs;
}
@Override
public String getCustomSqlSegment()
{
String sql = super.getCustomSqlSegment();
// 有别名的话,修改表达式,如 more.q.t2
// 因为 formatSqlIfNeed 方法 中直接使用了 ew 别名
if (this.alias != null && !this.alias.isEmpty()) {
sql = sql.replaceAll("#\\{ew\\.", String.format("#{%s.", alias));
}
return sql;
}
public QueryWrapperWithAlias<T> Mark()
{
this.mark++;
return this;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment