目录
- QueryWrapper实现MybatisPlus多表关联查询
- 1.dao层接口使用Select注解写SQL
- 2.service层代码示例
- 3.反射工具类
- 4.判空工具类
- MybatisPlus QueryWrapper简单用法
QueryWrapper实现MybatisPlus多表关联查询
1.dao层接口使用Select注解写SQL
重点:@Param("ew") Wrapper参数是必须,因为${ew.customSqlSegment} 底层其实就是where 条件,所以为了保证Wrapper不为空,service层代码中的Wrapper至少需要有一个条件:1 = 1
@Override@Select("select a.code as code , b.name as name , b.barcode as barcode ,a.ware_code as wareCode , c.name as wareName , a.qty as qty , a.oprice as oprice , a.total as total , " +" a.id as id , a.create_by as createBy , a.create_date as createDate , a.update_by as updateBy , a.update_date as updateDate , a.status as status , a.remarks as remarks" +"from sku_stock a , goods b , warehouse c " +"${ew.customSqlSegment} and a.code = b.code and a.ware_code = c.code")IPage selectPage(IPage page, @Param("ew")Wrapper queryWrapper);
2.service层代码示例
service父类封装的findPage方法:
/*** 封装findPage* @param entity* @param searchMap中的key:"; "为保留关键字,拆分数组,仅支持最大长度2的数组,*下标0:QueryWrapper查询条件中的列名(支持多表关联查询的表别名 + 列名方式,需要dao层接口支持)*下标1: QueryWrapper中不同的查询条件,eq:等于,ge:大于等..... todo:请自行完善Mybatis eq、ne、gt、lt、ge、le等*Map中的value:QueryWrapper需要查询的值* @param argsQueryWrapper中order by 排序数组* @return*/public IPagefindPage(T entity , Map search , String... args){long current = 1L; long size = 10L; if (EmptyUtil.isNoEmpty(ReflexUtil.getFieldValue(entity , "page")) && (long) ReflexUtil.getFieldValue(entity , "page") != 0){current = (long) ReflexUtil.getFieldValue(entity , "page"); }if (EmptyUtil.isNoEmpty(ReflexUtil.getFieldValue(entity , "limit")) && (long) ReflexUtil.getFieldValue(entity , "limit") != 0){size = (long) ReflexUtil.getFieldValue(entity , "limit"); } QueryWrapper queryWrapper; if (EmptyUtil.isNoEmpty(search)){queryWrapper = new QueryWrapper<>(); for (Map.Entry entry:search.entrySet()) {String[] key = entry.getKey().split("; "); if (key.length > 1){if (key[1].equals("eq")){queryWrapper.eq(key[0] , entry.getValue()); }else if (key[1].equals("ge")){queryWrapper.ge(key[0] , entry.getValue()); }else if (key[1].equals("lt")){queryWrapper.lt(key[0] , entry.getValue()); }}else {queryWrapper.like(entry.getKey() , entry.getValue()); }}}else {queryWrapper = new QueryWrapper<>(entity); }queryWrapper.orderByAsc(args); return super.page(new Page (current , size) , queryWrapper); }
service实现类方法:
public IPage findPage(SkuStock entity, String... args) {Map search = null; search = new HashedMap(); search.put("1; eq" , "1"); if (EmptyUtil.isNoEmpty(entity.getCode())|| EmptyUtil.isNoEmpty(entity.getWareCode())){if (EmptyUtil.isNoEmpty(entity.getCode())){search.put("code" , entity.getCode()); }if (EmptyUtil.isNoEmpty(entity.getWareCode())){search.put("ware_code" , entity.getWareCode()); }}else {long limit = entity.getLimit(); long page = entity.getPage(); entity = new SkuStock(); entity.setLimit(limit); entity.setPage(page); }return super.findPage(entity , search , args); }
3.反射工具类
package org.bluedream.comm.utils; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @ClassName ReflexUtil * @Description TODO * @Author foxsand * @Data 2021-06-09 15:17 * @Version */public class ReflexUtil { /*** 返回 entity 对象的所有属性,包含父类* @param obj* @return*/public static ListgetObjectFields(Object obj){Class clazz = obj.getClass(); List fieldList = new ArrayList<>() ; while (clazz != null) {//当父类为null的时候说明到达了最上层的父类(Object类).fieldList.addAll(Arrays.asList(clazz .getDeclaredFields())); clazz = clazz.getSuperclass(); //得到父类,然后赋给自己}return fieldList; } public static List getObjectFields(Class> clazz){List fieldList = new ArrayList<>() ; while (clazz != null){fieldList.addAll(Arrays.asList(clazz .getDeclaredFields())); clazz = clazz.getSuperclass(); //得到父类,然后赋给自己}return fieldList; } /*** 判断 Class entity 是否存在名称为 fieldName 的属性* @param fieldName* @param entity* @return*/public static Boolean isField(String fieldName , Object entity){List fieldList = getObjectFields(entity); for (Field f1:fieldList) {if (fieldName.equals(f1.getName()))return true; }return false; } /*** 返回 entity 对象中的所有方法,包含父类* @param entity* @return*/public static List getObjectMethods(Object entity){Class> clazz = entity.getClass(); List methods = new ArrayList<>(); while (clazz != null && clazz != Object.class) {//当父类为null的时候说明到达了最上层的父类(Object类).methods.addAll(Arrays.asList(clazz .getDeclaredMethods())); clazz = clazz.getSuperclass(); //得到父类,然后赋给自己}return methods; } public static List getObjectMethods(Class> clazz){List methods = new ArrayList<>(); while (clazz != null && clazz != Object.class) {//当父类为null的时候说明到达了最上层的父类(Object类).methods.addAll(Arrays.asList(clazz .getDeclaredMethods())); clazz = clazz.getSuperclass(); //得到父类,然后赋给自己}return methods; } /*** 判断 Class entity 是否存在名称为 methodName 的方法* @param methodName* @param entity* @return*/public static Boolean isMethod(String methodName , Object entity){List methods = getObjectMethods(entity); for (Method m1:methods) {if (methodName.equals(m1.getName()))return true; }return false; } /*** 循环向上转型, 获取对象的 DeclaredMethod* @param obj* @param methodName* @param parameterTypes方法参数类型* @return*/public static Method getDeclaredMethod(Object obj , String methodName , Class>...parameterTypes) {for (Class> clazz = obj.getClass(); clazz != Object.class && clazz != null; clazz = clazz.getSuperclass()) {try {return clazz.getDeclaredMethod(methodName, parameterTypes); } catch (Exception e) {// 这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。// 如果这里的异常打印或者往外抛,则就不会执行clazz=clazz.getSuperclass(),最后就不会进入到父类中了}}return null; } public static Object invoke(Object object, String methodName, Class>[] parameterTypes,Object[] parameters){Method method = getDeclaredMethod(object, methodName, parameterTypes); try {if (method != null){method.setAccessible(true); // 调用object 的 method 所代表的方法,其方法的参数是 parametersreturn method.invoke(object, parameters); }}catch (Exception e1){e1.printStackTrace(); }return null; } /*** 循环向上转型, 获取对象的 DeclaredField** @param object*: 子类对象* @param fieldName*: 父类中的属性名* @return 父类中的属性对象*/ public static Field getDeclaredField(Object object, String fieldName) {Field field = null; Class> clazz = object.getClass(); for (; clazz != Object.class && clazz != null; clazz = clazz.getSuperclass()) {try {field = clazz.getDeclaredField(fieldName); return field; } catch (Exception e) {// 这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。// 如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了 }} return null; } /*** 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter** @param object*: 子类对象* @param fieldName*: 父类中的属性名* @param value*: 将要设置的值*/ public static void setFieldValue(Object object, String fieldName, Object value) { // 根据 对象和属性名通过反射 调用上面的方法获取 Field对象Field field = getDeclaredField(object, fieldName); if (field != null){// 抑制Java对其的检查field.setAccessible(true); try {// 将 object 中 field 所代表的值 设置为 valuefield.set(object, value); } catch (IllegalArgumentException e) {e.printStackTrace(); } catch (IllegalAccessException e) {e.printStackTrace(); }}} /*** 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter** @param object*: 子类对象* @param fieldName*: 父类中的属性名* @return : 父类中的属性值*/ public static Object getFieldValue(Object object, String fieldName) {// 根据 对象和属性名通过反射 调用上面的方法获取 Field对象Field field = getDeclaredField(object, fieldName); if (field != null){// 抑制Java对其的检查field.setAccessible(true); try {// 获取 object 中 field 所代表的属性值return field.get(object); } catch (Exception e) {e.printStackTrace(); }}return null; }}
4.判空工具类
package org.bluedream.comm.utils; import java.util.Collection; import java.util.Map; public class EmptyUtil {//Suppress default constructor for noninstantiabilityprivate EmptyUtil(){throw new AssertionError(); } public static boolean isEmpty(Object object){if (object == null){return true; }if (object instanceof int[]){return ((int[]) object).length == 0; }if (object instanceof double[]){return ((double[]) object).length == 0; }if (object instanceof long[]){return ((long[]) object).length == 0; }if (object instanceof byte[]){return ((byte[]) object).length == 0; }if (object instanceof short[]){return ((short[]) object).length == 0; }if (object instanceof float[]){return ((float[]) object).length == 0; }if (object instanceof char[]){return ((char[]) object).length == 0; }if (object instanceof Object[]){return ((Object[]) object).length == 0; }if (object instanceof CharSequence) {return ((CharSequence) object).length() == 0; }if (object instanceof Collection ){return ((Collection) object).isEmpty(); }if (object instanceof Map){return ((Map) object).isEmpty(); }return false; } public static boolean isNoEmpty(Object object){return !isEmpty(object); } }
MybatisPlus QueryWrapper简单用法
查询方式 |
说明 |
setSqlSelect |
设置 SELECT 查询字段 |
where |
WHERE 语句,拼接 +?WHERE 条件 |
and |
AND 语句,拼接 +?AND 字段=值 |
andNew |
AND 语句,拼接 +?AND (字段=值) |
or |
OR 语句,拼接 +?OR 字段=值 |
orNew |
OR 语句,拼接 +?OR (字段=值) |
eq |
等于= |
allEq |
基于 map 内容等于= |
ne |
不等于<> |
gt |
大于> |
ge |
大于等于>= |
lt |
小于< |
le |
小于等于<= |
like |
模糊查询 LIKE |
notLike |
模糊查询 NOT LIKE |
in |
IN 查询 |
notIn |
NOT IN 查询 |
isNull |
NULL 值查询 |
isNotNull |
IS NOT NULL |
groupBy |
分组 GROUP BY |
having |
HAVING 关键词 |
orderBy |
排序 ORDER BY |
orderAsc |
ASC 排序 ORDER BY |
orderDesc |
DESC 排序 ORDER BY |
exists |
EXISTS 条件语句 |
notExists |
NOT EXISTS 条件语句 |
between |
BETWEEN 条件语句 |
notBetween |
NOT BETWEEN 条件语句 |
【关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式】addFilter |
自由拼接 SQL |
last |
拼接在最后,例如:last(“LIMIT 1”) |