update MyBatisPlus条件构造器AutoQueryWrapper

This commit is contained in:
baoyuzhong 2025-04-21 16:06:41 +08:00
parent 7ecf4bbf1c
commit 9ef691439b
5 changed files with 325 additions and 0 deletions

View File

@ -0,0 +1,54 @@
package org.dromara.test;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import org.dromara.common.mybatis.wrapper.AutoQueryWrapper;
import org.dromara.demo.domain.TestDemo;
import org.dromara.demo.mapper.TestDemoMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
/**
* 单元测试案例
*
* @author Lion Li
*/
@SpringBootTest // 此注解只能在 springboot 主包下使用 需包含 main 方法与 yml 配置文件
@DisplayName("条件构造器测试")
public class MyBatisPlusTest {
@Resource
TestDemoMapper testDemoMapper;
/**
* 没有TableName注解的类或@TableField(exist = false)的注解不能使用LambdaQueryWrapper
*/
@Test
public void test01() {
try {
testDemoMapper.selectOne(new LambdaQueryWrapper<TestDemo>()
.like(TestDemo::getNickName, "狮子")
);
} catch (Exception e) {
System.out.println("can not find lambda cache for this property [nickName] of entity [org.dromara.demo" +
".domain.TestDemo]");
}
}
@Test
public void test02() {
AutoQueryWrapper<TestDemo> wrapper = new AutoQueryWrapper<TestDemo>()
.like(TestDemo::getNickName, "狮子")
.eq(TestDemo::getValue, "")// 自动判空
.singleResult();// 保证结果只有一个
// 如果子查询条件需要参数可以这样设置不需要再额外传递一个param
wrapper.setParam(TestDemo::getUserName, "admin");
System.out.println(testDemoMapper.queryOne(wrapper));
}
}

View File

@ -0,0 +1,230 @@
package org.dromara.common.mybatis.wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @author qixia
*/
public class AutoQueryWrapper<T> extends QueryWrapper<T> {
private final Map<String, Object> entity = new HashMap<>();
public Object getParam(String key) {
return entity.get(key);
}
public Object getParam(SFunction<T, ?> key) {
return entity.get(getFieldName(key));
}
public void setParam(String key, Object value) {
entity.put(key, value);
}
public void setParam(SFunction<T, ?> key, Object value) {
entity.put(getFieldName(key), value);
}
public Boolean isNotEmpty(String key) {
return entity.get(key) != null && entity.get(key) != "";
}
public AutoQueryWrapper<T> eq(boolean condition, SFunction<T, ?> column, Object val) {
super.eq(condition, toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> eq(SFunction<T, ?> column, Object val) {
super.eq(isNotEmpty(val), toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> ne(boolean condition, SFunction<T, ?> column, Object val) {
super.ne(condition, toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> ne(SFunction<T, ?> column, Object val) {
super.ne(isNotEmpty(val), toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> gt(SFunction<T, ?> column, Object val) {
super.gt(isNotEmpty(val), toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> ge(SFunction<T, ?> column, Object val) {
super.ge(isNotEmpty(val), toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> lt(SFunction<T, ?> column, Object val) {
super.lt(isNotEmpty(val), toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> le(SFunction<T, ?> column, Object val) {
super.le(isNotEmpty(val), toUnderline(column), val);
return this;
}
public AutoQueryWrapper<T> like(Boolean condition, SFunction<T, ?> column, Object val) {
if (val instanceof String) {
super.like(condition, toUnderline(column), escapeStr((String) val));
} else {
super.like(condition, toUnderline(column), val);
}
return this;
}
public AutoQueryWrapper<T> like(SFunction<T, ?> column, Object val) {
if (val instanceof String) {
super.like(toUnderline(column), escapeStr((String) val));
} else {
super.like(toUnderline(column), val);
}
return this;
}
public AutoQueryWrapper<T> between(SFunction<T, ?> column, Object val1, Object val2) {
super.between(isNotEmpty(val1) && isNotEmpty(val1), toUnderline(column), val1, val2);
return this;
}
public AutoQueryWrapper<T> in(SFunction<T, ?> column, Collection<?> coll) {
super.in(isNotEmpty(coll), toUnderline(column), coll);
return this;
}
public AutoQueryWrapper<T> inSql(SFunction<T, ?> column, String sql) {
super.inSql(toUnderline(column), sql);
return this;
}
public AutoQueryWrapper<T> isNotNull(SFunction<T, ?> column) {
super.isNotNull(toUnderline(column));
return this;
}
public AutoQueryWrapper<T> isNull(SFunction<T, ?> column) {
super.isNull(toUnderline(column));
return this;
}
public AutoQueryWrapper<T> singleResult() {
super.last("limit 1");
return this;
}
public AutoQueryWrapper<T> orderByAsc(SFunction<T, ?> column) {
super.orderByAsc(toUnderline(column));
return this;
}
public AutoQueryWrapper<T> orderByDesc(SFunction<T, ?> column) {
super.orderByDesc(toUnderline(column));
return this;
}
/**
* 获取字段名
*
* @param column
* @return
*/
private String getFieldName(SFunction<T, ?> column) {
String result = LambdaUtils.extract(column).getImplMethodName().replaceAll("get", "");
return Character.toLowerCase(result.charAt(0)) + result.substring(1);
}
/**
* 方法名转下划线命名
*
* @param str
* @return
*/
private String toUnderline(String str) {
if (str == null || str.isEmpty()) {
return str;
}
StringBuilder result = new StringBuilder();
for (char c : str.toCharArray()) {
if (Character.isUpperCase(c)) {
result.append('_');
}
result.append(Character.toLowerCase(c));
}
return result.toString().replace("get_", "");
}
/**
* 方法名转下划线命名
*
* @param column
* @return
*/
private <R> String toUnderline(SFunction<R, ?> column) {
return toUnderline((LambdaUtils.extract(column).getImplMethodName()));
}
/**
* 特殊字符转义
*
* @param str
* @return
*/
private static String escapeStr(String str) {
if (str != null && !str.isEmpty()) {
str = str.replaceAll("\\\\", "\\\\\\\\");
str = str.replaceAll("_", "\\\\_");
str = str.replaceAll("%", "\\\\%");
}
return str;
}
/**
* 判断是否不为空
*
* @param obj
* @return
*/
private static boolean isNotEmpty(Object obj) {
return !isEmpty(obj);
}
/**
* 判断是否为空
*
* @param obj
* @return
*/
private static boolean isEmpty(Object obj) {
if (null == obj) {
return true;
}
if (obj instanceof CharSequence) {
return ((CharSequence) obj).length() == 0;
} else if (obj instanceof Map) {
return ((Map<?, ?>) obj).isEmpty();
} else if (obj instanceof Iterable) {
return !((Iterable<?>) obj).iterator().hasNext();
} else if (obj instanceof Iterator) {
return !((Iterator<?>) obj).hasNext();
} else if (obj.getClass().isArray()) {
return 0 == Array.getLength(obj);
}
return false;
}
}

View File

@ -65,4 +65,16 @@ public class TestDemo extends TenantEntity {
@TableLogic
private Long delFlag;
/**
* 用户名
*/
@TableField(exist = false)
private String userName;
/**
* 昵称
*/
@TableField(exist = false)
private String nickName;
}

View File

@ -61,4 +61,5 @@ public interface TestDemoMapper extends BaseMapperPlus<TestDemo, TestDemoVo> {
})
int updateById(@Param(Constants.ENTITY) TestDemo entity);
TestDemo queryOne(@Param(Constants.WRAPPER) Wrapper<TestDemo> ew);
}

View File

@ -8,4 +8,32 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
SELECT * FROM test_demo ${ew.customSqlSegment}
</select>
<select id="queryOne" resultType="org.dromara.demo.domain.TestDemo">
select td.id,
td.tenant_id,
td.dept_id,
td.user_id,
su.user_name,
su.nick_name,
td.order_num,
td.test_key,
td.value,
td.version,
td.create_dept,
td.create_time,
td.create_by,
td.update_time,
td.update_by,
td.del_flag
from test_demo td
left join (
select * from sys_user
<where>
<if test="ew.isNotEmpty('userName')">
user_name = '${ew.getParam('userName')}'
</if>
</where> ) su on su.user_id = td.user_id
${ew.getCustomSqlSegment}
</select>
</mapper>