成都网站建设时代汇创,学校网站网页制作,用wordpress做个,推荐12个国外免费自助建站网站背景
最近碰上有个业务#xff0c;查询的sql如下#xff1a;
select * from table where (sku_id,batch_no) in ((#{skuId},#{batchNo}),...); 本来也没什么#xff0c;很简单常见的一种sql。问题是我们使用的是mybatis-plus#xff0c;然后写的时候又没有考虑到后面的查…背景
最近碰上有个业务查询的sql如下
select * from table where (sku_id,batch_no) in ((#{skuId},#{batchNo}),...); 本来也没什么很简单常见的一种sql。问题是我们使用的是mybatis-plus然后写的时候又没有考虑到后面的查询条件这里用的是mybatis-plus lambda的方式。
LambdaQueryChainWrapperTable query tableService.lambdaQuery();
query.eq(Table::getId, param.getId()); 但是mysql-plus并没有支持这种sql的形式要么用apply方法自定义拼接sql要么不采用lambda方式将语句写成 xml 形式。
不过第一种方式感觉很 low一大段 java 代码里插入一段sql字符串看上去就很别扭因为有点代码洁癖只能果断放弃。
第二种改动又太大前面那么多查询条件又要全部移入xml里面同时本来已经通过测试的筛选条件又要重新来一遍太懒实在干不动了。
想想这么常见的场景网上理应有现成的解决方案。但不知道是搜索关键字不对还是确实没有搜了半天没搜出来。
最后无奈只能尝试自己扩展一下。
代码
import com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper;
import com.baomidou.mybatisplus.core.conditions.ISqlSegment;
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import io.vavr.Tuple;
import org.springframework.util.Assert;import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;
import java.util.stream.Collectors;import static com.baomidou.mybatisplus.core.enums.SqlKeyword.IN;
import static java.util.stream.Collectors.joining;public class CombinationLambdaQueryChainWrapperT extends AbstractLambdaWrapperT, CombinationLambdaQueryChainWrapperT {/*** 查询字段*/private String sqlSelect;public CombinationLambdaQueryChainWrapper() {this(null);}public CombinationLambdaQueryChainWrapper(T entity) {this.entity entity;this.initEntityClass();this.initNeed();}CombinationLambdaQueryChainWrapper(T entity, ClassT entityClass, String sqlSelect, AtomicInteger paramNameSeq, MapString, Object paramNameValuePairs,MergeSegments mergeSegments) {this.entity entity;this.paramNameSeq paramNameSeq;this.paramNameValuePairs paramNameValuePairs;this.expression mergeSegments;this.sqlSelect sqlSelect;this.entityClass entityClass;}/*** p* SELECT 部分 SQL 设置* /p** param columns 查询字段*/SafeVarargspublic final CombinationLambdaQueryChainWrapperT select(SFunctionT, ?... columns) {if (ArrayUtils.isNotEmpty(columns)) {this.sqlSelect this.columnsToString(columns);}return typedThis;}public CombinationLambdaQueryChainWrapperT select(PredicateTableFieldInfo predicate) {return select(entityClass, predicate);}/*** p* 过滤查询的字段信息(主键除外!)* /p* p* 例1: 只要 java 字段名以 test 开头的 - select(i - i.getProperty().startsWith(test))* 例2: 只要 java 字段属性是 CharSequence 类型的 - select(TableFieldInfo::isCharSequence)* 例3: 只要 java 字段没有填充策略的 - select(i - i.getFieldFill FieldFill.DEFAULT)* 例4: 要全部字段 - select(i - true)* 例5: 只要主键字段 - select(i - false)* /p** param predicate 过滤方式* return this*/public CombinationLambdaQueryChainWrapperT select(ClassT entityClass, PredicateTableFieldInfo predicate) {this.entityClass entityClass;this.sqlSelect TableInfoHelper.getTableInfo(getCheckEntityClass()).chooseSelect(predicate);return typedThis;}Overridepublic String getSqlSelect() {return sqlSelect;}/*** p* 用于生成嵌套 sql* 故 sqlSelect 不向下传递* /p*/Overrideprotected CombinationLambdaQueryChainWrapperT instance(AtomicInteger paramNameSeq, MapString, Object paramNameValuePairs) {return new CombinationLambdaQueryChainWrapper(entity, entityClass, null, paramNameSeq, paramNameValuePairs, new MergeSegments());}/*** 组合IN查询* 此处引入元祖需使用io.vavr包**/public CombinationLambdaQueryChainWrapperT combinationIn(boolean condition, ListTuple list, SFunctionT, ?... columns) {Assert.isTrue(columns.length list.get(0).arity(), 请检查组合IN查询参数长度);return doIt(condition,() - StringPool.LEFT_BRACKET columnsToString(columns) StringPool.RIGHT_BRACKET,IN,inExpressionOfParam(list));}private ISqlSegment inExpressionOfParam(ListTuple list) {if (list.size() 1000) {throw new RuntimeException(组合查询禁止超过1000条);}ListString result list.stream().map(m - StringPool.LEFT_BRACKET m.toSeq().asJava().stream().map(n - n instanceof String ? StringPool.SINGLE_QUOTE n StringPool.SINGLE_QUOTE : String.valueOf(n)).collect(Collectors.joining(StringPool.COMMA)) StringPool.RIGHT_BRACKET).collect(Collectors.toList());return () - result.stream().collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET));}}使用示例 productRelService.list(new CombinationLambdaQueryChainWrapperProductRel().select(ProductRel::getLevelId).eq(ProductRel::getLevelId, GBZ0555A0002).combinationIn(true, Arrays.asList(Tuple.of(91cf1c0f3b0bc46e0238dc33717dc88e, GBZ0555A0002)), ProductRel::getProductUuid, ProductRel::getLevelId));productRelService.list(new CombinationLambdaQueryChainWrapperProductRel().combinationIn(true, Arrays.asList(Tuple.of(1L, GBZ0555A0002)), ProductRel::getId, ProductRel::getLevelId));