24282 před 1 rokem
rodič
revize
2224f40832

+ 22 - 10
sd-business/src/main/java/com/sd/business/service/warehouse/impl/WarehouseServiceImpl.java

@@ -1,15 +1,15 @@
 package com.sd.business.service.warehouse.impl;
 
-import cn.hutool.core.bean.BeanUtil;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.ruoyi.common.utils.wrapper.IWrapper;
 import com.sd.business.entity.warehouse.dto.WarehouseDto;
 import com.sd.business.entity.warehouse.dto.WarehouseSelectDto;
 import com.sd.business.entity.warehouse.po.Warehouse;
 import com.sd.business.entity.warehouse.vo.WarehouseVo;
 import com.sd.business.mapper.warehouse.WarehouseMapper;
 import com.sd.business.service.warehouse.WarehouseService;
+import com.sd.business.util.sql.Sql;
+import com.sd.framework.util.Assert;
 import org.springframework.stereotype.Service;
 
 
@@ -26,18 +26,30 @@ public class WarehouseServiceImpl extends ServiceImpl<WarehouseMapper, Warehouse
 
     @Override
     public Page<WarehouseVo> getPage(WarehouseSelectDto dto) {
-        IWrapper<Warehouse> wrapper = getWrapper();
-        wrapper.orderByDesc("w", Warehouse::getId);
-        wrapper.eq("w", Warehouse::getType, dto.getType());
-        wrapper.like("w", Warehouse::getName, dto.getName());
-        return this.baseMapper.getPage(dto.getPage(), wrapper);
+
+        Page<WarehouseVo> page = Sql.create(WarehouseVo.class)
+                .selectAll(Warehouse.class)
+                .from(Warehouse.class)
+                .eq(Warehouse::getType, dto.getType())
+                .like(Warehouse::getName, dto.getName())
+                .orderByDesc(Warehouse::getId)
+                .page(dto.getPage());
+
+        return page;
     }
 
     @Override
     public WarehouseVo detail(Long id) {
-        Warehouse warehouse = this.getById(id);
-        WarehouseVo result = BeanUtil.toBean(warehouse, WarehouseVo.class);
-        return result;
+
+        WarehouseVo vo = Sql.create(WarehouseVo.class)
+                .selectAll(Warehouse.class)
+                .from(Warehouse.class)
+                .eq(Warehouse::getId, id)
+                .one();
+
+        Assert.notNull(vo, "未知数据");
+
+        return vo;
     }
 
     @Override

+ 87 - 0
sd-business/src/main/java/com/sd/business/util/sql/FieldUtil.java

@@ -0,0 +1,87 @@
+package com.sd.business.util.sql;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import org.apache.ibatis.reflection.property.PropertyNamer;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class FieldUtil {
+
+    private static final Map<Class<?>, String> tableAliasMap = new ConcurrentHashMap<>();
+    private static final Map<Class<?>, String> tableNameMap = new ConcurrentHashMap<>();
+
+    /**
+     * 获取sql字段名
+     * 例:getSqlFieldName(DemoEntity::getBaseId) -》 return "de.base_id"
+     */
+    public static <K, V> String getSqlFieldName(SFunction<K, V> function) {
+        LambdaMeta meta = LambdaUtils.extract(function);
+        String alias = getTableAlias(meta.getInstantiatedClass());
+        return getSqlFieldName(alias, meta);
+    }
+
+    /**
+     * 获取sql字段名
+     * 例:getSqlFieldName("s", DemoEntity::getBaseId) -》 return "s.base_id"
+     */
+    public static <K, V> String getSqlFieldName(String alias, SFunction<K, V> function) {
+        LambdaMeta meta = LambdaUtils.extract(function);
+        String fieldName = StrUtil.toUnderlineCase(PropertyNamer.methodToProperty(meta.getImplMethodName()));
+        return alias + StringPool.DOT + fieldName;
+    }
+
+    /**
+     * 获取sql字段名
+     * 例:getSqlFieldName("s", DemoEntity::getBaseId) -》 return "s.base_id"
+     */
+    public static String getSqlFieldName(String alias, LambdaMeta meta) {
+        String fieldName = StrUtil.toUnderlineCase(PropertyNamer.methodToProperty(meta.getImplMethodName()));
+        return alias + StringPool.DOT + fieldName;
+    }
+
+    /**
+     * 获取表别名
+     */
+    public static String getTableAlias(Class<?> cls) {
+        return tableAliasMap.computeIfAbsent(cls, itemCls -> {
+            String tableName = getTableName(cls);
+            StringBuilder aliasBuilder = new StringBuilder();
+            for (String item : tableName.split("_")) {
+                aliasBuilder.append(item, 0, 1);
+            }
+            return aliasBuilder.toString();
+        });
+    }
+
+    /**
+     * 获取表名
+     */
+    public static String getTableName(Class<?> cls) {
+        return tableNameMap.computeIfAbsent(cls, itemCls -> {
+            Annotation[] annotations = itemCls.getAnnotations();
+            TableName tableName = null;
+            for (Annotation annotation : annotations) {
+                if (annotation instanceof TableName) {
+                    tableName = (TableName) annotation;
+                    break;
+                }
+            }
+            String tableNameStr = null;
+            if (tableName != null) {
+                tableNameStr = tableName.value();
+            }
+            if (StrUtil.isBlank(tableNameStr)) {
+                tableNameStr = StrUtil.toUnderlineCase(itemCls.getSimpleName());
+            }
+            return tableNameStr;
+        });
+    }
+
+}

+ 85 - 0
sd-business/src/main/java/com/sd/business/util/sql/Fields.java

@@ -0,0 +1,85 @@
+package com.sd.business.util.sql;
+
+import cn.hutool.core.util.ReflectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import lombok.AllArgsConstructor;
+import org.apache.ibatis.reflection.property.PropertyNamer;
+
+import java.lang.reflect.Field;
+
+@AllArgsConstructor
+public class Fields<T> {
+
+    private final Sql<T> sql;
+
+    public <S, V> Fields<T> select(SFunction<S, V> function) {
+        LambdaMeta meta = LambdaUtils.extract(function);
+        sql.fieldList.add(FieldUtil.getSqlFieldName(sql.getTableAlias(meta), meta));
+        return this;
+    }
+
+    public <S, V> Fields<T> select(SFunction<S, V> function, SFunction<T, ?> asFunction) {
+        String as = PropertyNamer.methodToProperty(LambdaUtils.extract(asFunction).getImplMethodName());
+        LambdaMeta meta = LambdaUtils.extract(function);
+        sql.fieldList.add(FieldUtil.getSqlFieldName(sql.getTableAlias(meta), meta) + StringPool.SPACE + as);
+        return this;
+    }
+
+    public <S, V> Fields<T> select(String alias, SFunction<S, V> function) {
+        LambdaMeta meta = LambdaUtils.extract(function);
+        sql.fieldList.add(FieldUtil.getSqlFieldName(alias, meta));
+        return this;
+    }
+
+    public <S, V> Fields<T> select(String alias, SFunction<S, V> function, SFunction<T, ?> asFunction) {
+        String as = PropertyNamer.methodToProperty(LambdaUtils.extract(asFunction).getImplMethodName());
+        LambdaMeta meta = LambdaUtils.extract(function);
+        sql.fieldList.add(FieldUtil.getSqlFieldName(alias, meta) + StringPool.SPACE + as);
+        return this;
+    }
+
+    public Fields<T> selectAll(Class<?> cls) {
+        return selectAll(sql.getTableAlias(cls), cls);
+    }
+
+    public Fields<T> selectAll(String alias, Class<?> cls) {
+        Field[] fields = ReflectUtil.getFields(cls);
+        for (Field field : fields) {
+            String fieldName = ReflectUtil.getFieldName(field);
+            if ("serialVersionUID".equals(fieldName)) {
+                continue;
+            }
+
+            TableField tableField = field.getAnnotation(TableField.class);
+            if (tableField != null) {
+                if (!tableField.exist() || !tableField.select()) {
+                    continue;
+                }
+                String value = tableField.value();
+                if (StrUtil.isNotBlank(value)) {
+                    fieldName = value;
+                }
+            }
+
+            sql.fieldList.add(alias + StringPool.DOT + StrUtil.toUnderlineCase(fieldName));
+        }
+        return this;
+    }
+
+    public From<T> from(Class<?> cls) {
+        String tableAlias = sql.getTableAlias(cls);
+        return from(tableAlias, cls);
+    }
+
+    public From<T> from(String alias, Class<?> cls) {
+        String tableName = FieldUtil.getTableName(cls);
+        sql.fromList.add(" FROM " + tableName + " " + alias);
+        return new From<>(sql);
+    }
+
+}

+ 69 - 0
sd-business/src/main/java/com/sd/business/util/sql/From.java

@@ -0,0 +1,69 @@
+package com.sd.business.util.sql;
+
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+
+
+public class From<T> extends Where<T> {
+
+    private final Sql<T> sql;
+
+    protected From(Sql<T> sql) {
+        super(sql);
+        this.sql = sql;
+    }
+
+    public <K, V> From<T> leftJoin(Class<K> cls1, SFunction<K, ?> on1, SFunction<V, ?> on2) {
+        return leftJoin(sql.getTableAlias(cls1), cls1, on1, sql.getTableAlias(on2), on2);
+    }
+
+    public <K, V> From<T> leftJoin(Class<K> cls1, SFunction<K, ?> on1, String as2, SFunction<V, ?> on2) {
+        return leftJoin(sql.getTableAlias(cls1), cls1, on1, as2, on2);
+    }
+
+    public <K, V> From<T> leftJoin(String as1, Class<K> cls1, SFunction<K, ?> on1, SFunction<V, ?> on2) {
+        return leftJoin(as1, cls1, on1, sql.getTableAlias(on2), on2);
+    }
+
+    public <K, V> From<T> leftJoin(String as1, Class<K> cls1, SFunction<K, ?> on1, String as2, SFunction<V, ?> on2) {
+        sql.fromList.add(" LEFT JOIN " + FieldUtil.getTableName(cls1) + " " + as1 + " ON " +
+                FieldUtil.getSqlFieldName(as1, on1) + " = " + FieldUtil.getSqlFieldName(as2, on2));
+        return this;
+    }
+
+    public <K, V> From<T> rightJoin(Class<K> cls1, SFunction<K, ?> on1, SFunction<V, ?> on2) {
+        return leftJoin(sql.getTableAlias(cls1), cls1, on1, sql.getTableAlias(on2), on2);
+    }
+
+    public <K, V> From<T> rightJoin(Class<K> cls1, SFunction<K, ?> on1, String as2, SFunction<V, ?> on2) {
+        return leftJoin(sql.getTableAlias(cls1), cls1, on1, as2, on2);
+    }
+
+    public <K, V> From<T> rightJoin(String as1, Class<K> cls1, SFunction<K, ?> on1, SFunction<V, ?> on2) {
+        return leftJoin(as1, cls1, on1, sql.getTableAlias(on2), on2);
+    }
+
+    public <K, V> From<T> rightJoin(String as1, Class<K> cls1, SFunction<K, ?> on1, String as2, SFunction<V, ?> on2) {
+        sql.fromList.add(" RIGHT JOIN " + FieldUtil.getTableName(cls1) + " " + as1 + " ON " +
+                FieldUtil.getSqlFieldName(as1, on1) + " = " + FieldUtil.getSqlFieldName(as2, on2));
+        return this;
+    }
+
+    public <K, V> From<T> innerJoin(Class<K> cls1, SFunction<K, ?> on1, SFunction<V, ?> on2) {
+        return leftJoin(sql.getTableAlias(cls1), cls1, on1, sql.getTableAlias(on2), on2);
+    }
+
+    public <K, V> From<T> innerJoin(Class<K> cls1, SFunction<K, ?> on1, String as2, SFunction<V, ?> on2) {
+        return leftJoin(sql.getTableAlias(cls1), cls1, on1, as2, on2);
+    }
+
+    public <K, V> From<T> innerJoin(String as1, Class<K> cls1, SFunction<K, ?> on1, SFunction<V, ?> on2) {
+        return leftJoin(as1, cls1, on1, sql.getTableAlias(on2), on2);
+    }
+
+    public <K, V> From<T> innerJoin(String as1, Class<K> cls1, SFunction<K, ?> on1, String as2, SFunction<V, ?> on2) {
+        sql.fromList.add(" INNER JOIN " + FieldUtil.getTableName(cls1) + " " + as1 + " ON " +
+                FieldUtil.getSqlFieldName(as1, on1) + " = " + FieldUtil.getSqlFieldName(as2, on2));
+        return this;
+    }
+
+}

+ 48 - 0
sd-business/src/main/java/com/sd/business/util/sql/Sql.java

@@ -0,0 +1,48 @@
+package com.sd.business.util.sql;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.extra.spring.SpringUtil;
+import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
+import com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.sd.business.util.sql.mapper.JoinMapper;
+import lombok.AllArgsConstructor;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@AllArgsConstructor
+public class Sql<T> {
+
+    protected static final JoinMapper mapper = SpringUtil.getBean(JoinMapper.class);
+    protected final Class<T> resultCls;
+    protected final List<String> fieldList = new ArrayList<>();
+    protected final List<String> fromList = new ArrayList<>();
+    private final Map<Class<?>, String> tableAliasMap = new HashMap<>();
+
+    public static <T> Fields<T> create(Class<T> cls) {
+        return new Fields<>(new Sql<>(cls));
+    }
+
+    protected String getTableAlias(SFunction<?, ?> function) {
+        LambdaMeta meta = LambdaUtils.extract(function);
+        Class<?> cls = meta.getInstantiatedClass();
+        return getTableAlias(cls);
+    }
+
+    protected String getTableAlias(LambdaMeta meta) {
+        Class<?> cls = meta.getInstantiatedClass();
+        return getTableAlias(cls);
+    }
+
+    protected String getTableAlias(Class<?> cls) {
+        return tableAliasMap.computeIfAbsent(cls, itemCls -> "t" + (tableAliasMap.size() + 1));
+    }
+
+    protected String getSql() {
+        return "SELECT " + CollectionUtil.join(fieldList, ",") + CollectionUtil.join(fromList, "");
+    }
+
+}

+ 332 - 0
sd-business/src/main/java/com/sd/business/util/sql/Where.java

@@ -0,0 +1,332 @@
+package com.sd.business.util.sql;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
+import com.baomidou.mybatisplus.core.conditions.SharedString;
+import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class Where<T> extends AbstractWrapper<T, String, Where<T>> {
+
+    private final Sql<T> sql;
+
+    protected Where(Sql<T> sql) {
+        this.sql = sql;
+        super.initNeed();
+    }
+
+    private Where(Sql<T> sql, T entity, Class<T> entityClass, AtomicInteger paramNameSeq,
+                  Map<String, Object> paramNameValuePairs, MergeSegments mergeSegments, SharedString paramAlias,
+                  SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) {
+        super.setEntity(entity);
+        super.setEntityClass(entityClass);
+        this.paramNameSeq = paramNameSeq;
+        this.paramNameValuePairs = paramNameValuePairs;
+        this.expression = mergeSegments;
+        this.paramAlias = paramAlias;
+        this.lastSql = lastSql;
+        this.sqlComment = sqlComment;
+        this.sqlFirst = sqlFirst;
+        this.sql = sql;
+    }
+
+    /**
+     * 排序
+     */
+    public <K, V> Where<T> orderByAsc(SFunction<K, V> function) {
+        return orderByAsc(FieldUtil.getSqlFieldName(sql.getTableAlias(function), function));
+    }
+
+    public <K, V> Where<T> orderByAsc(String alias, SFunction<K, V> function) {
+        return orderByAsc(FieldUtil.getSqlFieldName(alias, function));
+    }
+
+    public <K, V> Where<T> orderByDesc(SFunction<K, V> function) {
+        return orderByDesc(FieldUtil.getSqlFieldName(sql.getTableAlias(function), function));
+    }
+
+    public <K, V> Where<T> orderByDesc(String alias, SFunction<K, V> function) {
+        return orderByDesc(FieldUtil.getSqlFieldName(alias, function));
+    }
+
+    /**
+     * between
+     */
+    public <K, V> Where<T> between(SFunction<K, V> function, Object val1, Object val2) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return between(sqlFieldName, val1, val2);
+    }
+
+    public <K, V> Where<T> between(String alias, SFunction<K, V> function, Object val1, Object val2) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return between(sqlFieldName, val1, val2);
+    }
+
+    public Where<T> between(String sqlFieldName, Object val1, Object val2) {
+        return between(ObjectUtil.isAllNotEmpty(val1, val2), sqlFieldName, val1, val2);
+    }
+
+    /**
+     * eq
+     */
+    public <K, V> Where<T> eq(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return eq(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> eq(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return eq(sqlFieldName, value);
+    }
+
+    public Where<T> eq(String sqlFieldName, Object value) {
+        return eq(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * ne
+     */
+    public <K, V> Where<T> ne(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return ne(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> ne(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return ne(sqlFieldName, value);
+    }
+
+    public Where<T> ne(String sqlFieldName, Object value) {
+        return ne(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * ge
+     */
+    public <K, V> Where<T> ge(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return ge(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> ge(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return ge(sqlFieldName, value);
+    }
+
+    public Where<T> ge(String sqlFieldName, Object value) {
+        return ge(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * gt
+     */
+    public <K, V> Where<T> gt(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return gt(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> gt(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return gt(sqlFieldName, value);
+    }
+
+    public Where<T> gt(String sqlFieldName, Object value) {
+        return gt(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * le
+     */
+    public <K, V> Where<T> le(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return le(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> le(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return le(sqlFieldName, value);
+    }
+
+    public Where<T> le(String sqlFieldName, Object value) {
+        return le(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * lt
+     */
+    public <K, V> Where<T> lt(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return lt(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> lt(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return lt(sqlFieldName, value);
+    }
+
+    public Where<T> lt(String sqlFieldName, Object value) {
+        return lt(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * like
+     */
+    public <K, V> Where<T> like(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return like(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> like(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return like(sqlFieldName, value);
+    }
+
+    public Where<T> like(String sqlFieldName, Object value) {
+        return apply(ObjectUtil.isNotEmpty(value), "instr(" + sqlFieldName + ", {0}) > 0", value);
+    }
+
+    /**
+     * notLike
+     */
+    public <K, V> Where<T> notLike(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return notLike(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> notLike(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return notLike(sqlFieldName, value);
+    }
+
+    public Where<T> notLike(String sqlFieldName, Object value) {
+        return notLike(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * likeLeft
+     */
+    public <K, V> Where<T> likeLeft(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return likeLeft(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> likeLeft(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return likeLeft(sqlFieldName, value);
+    }
+
+    public Where<T> likeLeft(String sqlFieldName, Object value) {
+        return likeLeft(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * likeRight
+     */
+    public <K, V> Where<T> likeRight(SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return likeRight(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> likeRight(String alias, SFunction<K, V> function, Object value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return likeRight(sqlFieldName, value);
+    }
+
+    public Where<T> likeRight(String sqlFieldName, Object value) {
+        return likeRight(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    /**
+     * in
+     */
+    public <K, V> Where<T> in(SFunction<K, V> function, Collection<?> value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return in(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> in(String alias, SFunction<K, V> function, Collection<?> value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return in(sqlFieldName, value);
+    }
+
+    public Where<T> in(String sqlFieldName, Collection<?> value) {
+        return in(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> in(SFunction<K, V> function, Object... value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return in(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> in(String alias, SFunction<K, V> function, Object... value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return in(sqlFieldName, value);
+    }
+
+    /**
+     * notIn
+     */
+    public <K, V> Where<T> notIn(SFunction<K, V> function, Collection<?> value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return notIn(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> notIn(String alias, SFunction<K, V> function, Collection<?> value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return notIn(sqlFieldName, value);
+    }
+
+    public Where<T> notIn(String sqlFieldName, Collection<?> value) {
+        return notIn(ObjectUtil.isNotEmpty(value), sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> notIn(SFunction<K, V> function, Object... value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(sql.getTableAlias(function), function);
+        return notIn(sqlFieldName, value);
+    }
+
+    public <K, V> Where<T> notIn(String alias, SFunction<K, V> function, Object... value) {
+        String sqlFieldName = FieldUtil.getSqlFieldName(alias, function);
+        return notIn(sqlFieldName, value);
+    }
+
+    @Override
+    protected Where<T> instance() {
+        return new Where<>(sql, getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, new MergeSegments(),
+                paramAlias, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString());
+    }
+
+    public List<T> list() {
+        List<Map<String, Object>> list = Sql.mapper.list(sql.getSql(), this);
+        return BeanUtil.copyToList(list, sql.resultCls);
+    }
+
+    public Page<T> page(Page<?> page) {
+        Page<Map<String, Object>> tempPage = Sql.mapper.page(sql.getSql(), page, this);
+
+        Page<T> result = new Page<>();
+        result.setRecords(BeanUtil.copyToList(tempPage.getRecords(), sql.resultCls));
+        result.setPages(tempPage.getPages());
+        result.setSize(tempPage.getSize());
+        result.setTotal(tempPage.getTotal());
+        result.setCurrent(tempPage.getCurrent());
+        return result;
+    }
+
+    public T one() {
+        Map<String, Object> one = Sql.mapper.one(sql.getSql(), this);
+        return BeanUtil.copyProperties(one, sql.resultCls);
+    }
+
+    public String getSql() {
+        return sql.getSql() + " " + getCustomSqlSegment();
+    }
+
+}

+ 22 - 0
sd-business/src/main/java/com/sd/business/util/sql/mapper/JoinMapper.java

@@ -0,0 +1,22 @@
+package com.sd.business.util.sql.mapper;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.sd.business.util.sql.Where;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+import java.util.Map;
+
+public interface JoinMapper {
+
+    @Select("${sql} ${ew.customSqlSegment}")
+    List<Map<String, Object>> list(@Param("sql") String sql, @Param("ew") Where<?> wrapper);
+
+    @Select("${sql} ${ew.customSqlSegment}")
+    Page<Map<String, Object>> page(@Param("sql") String sql, @Param("page") Page<?> page, @Param("ew") Where<?> wrapper);
+
+    @Select("${sql} ${ew.customSqlSegment}")
+    Map<String, Object> one(@Param("sql") String sql, @Param("ew") Where<?> wrapper);
+
+}

+ 1 - 1
sd-starter/src/main/resources/application.yml

@@ -18,7 +18,7 @@ ruoyi:
 # 开发环境配置
 server:
   # 服务器的HTTP端口,默认为8080
-  port: 7777
+  port: 8639
   tomcat:
     # tomcat的URI编码
     uri-encoding: UTF-8