-
2020-11-16 15:19:16
需求:getAllMenusWithRole 获取所有菜单访问所需要的角色。
菜单和角色是多对多关系,有一个关联表,菜单去重,角色返回集合
public class MenuVO extends SysMenu { private List<SysRole> roles; }
实现一
@Select("select rm.menu_id,m.`name`,m.url from sys_role_menu as rm LEFT JOIN sys_menu as m on rm.menu_id = m.menu_id GROUP BY rm.menu_id") @Results({ @Result(column="menu_id",property="menuId"), @Result(column="menu_id",property="roles", many=@Many( select="com.XXX.mapper.SysRoleMapper.selectSysRoleByMenuId" ) ) }) List<MenuVO> getAllMenusWithRole();
@Select("select * from sys_role as r where r.role_id in (select rm.role_id from sys_role_menu as rm where rm.menu_id = #{menuid})") List<SysRole> selectSysRoleByMenuId(@Param("menuid") Integer menuid);
标注方式,查询关联,缺点多次查库,@Results标注内,试过没有相关集合标注。其实也可用实现二中的sql,查询出来,自己在service层处理,搞成List
实现二
<!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.XXX.entity.SysMenu"> <id column="menu_id" property="menuId"/> <result column="name" property="name"/> <result column="url" property="url"/> </resultMap> <resultMap id="MenuWithRole" type="com.XXX.entity.MenuVO" extends="BaseResultMap"> <collection property="roles" ofType="com.XXX.entity.SysRole"> <id column="role_id" property="roleId"/> <result column="role_name" property="roleName"/> <result column="role_name_zh" property="roleNameZh"/> </collection> </resultMap> <select id="getAllMenusWithRole" resultMap="MenuWithRole"> select m.*,r.role_id,r.role_name,r.role_name_zh from sys_menu m,sys_role_menu mr,sys_role r where m.menu_id=mr.menu_id and mr.role_id=r.role_id order by m.menu_id desc </select>
xml方式,用mybatis-plus能不用就不用xml文件,所以,是在标注没法实现,优点:查询一次
更多相关内容 -
MybatisPlus多表关联查询
2022-03-31 10:21:10MP多表关联查询 我们关联user表和product表,两个表如下: user表 product表 现在我们要关联两个表查询出product的全部信息已经对应的用户名字 先写sql语句 然后创建vo package com.hyn.mybatisplus.entity...MP多表关联查询
我们关联user表和product表,两个表如下:
-
user表
-
product表
现在我们要关联两个表查询出product的全部信息已经对应的用户名字
先写sql语句
然后创建vo
package com.hyn.mybatisplus.entity; import lombok.Data; @Data public class ProductVo { private Integer category; private Integer count; private String description; private Integer userId; private String userName; }
usermapper创建新方法和JPA类似
package com.hyn.mybatisplus.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.hyn.mybatisplus.entity.ProductVo; import com.hyn.mybatisplus.entity.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; @Repository @Mapper public interface UserMapper extends BaseMapper<User> { @Select("select p.*,u.name userName from user u ,product p where u.id=p.user_id and u.id = #{id}") List<ProductVo> productList(Integer id); }
最后测试一下
@Test void product(){ mapper.productList(13).forEach(System.out::println); }
可见关联表查询以及封装数据成功,如果vo和表里的字段不对应可以在sql语句中改别名。
-
-
MyBatis-Plus多表联合查询并且分页(3表联合)
2020-08-24 19:45:57主要介绍了MyBatis-Plus多表联合查询并且分页(3表联合),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
MyBatis 三表外关联查询的实现(用户、角色、权限)
2020-08-18 16:39:42主要介绍了MyBatis 三表外关联查询的实现(用户、角色、权限),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
MybatisPlus 多表关联分页查询
2021-08-30 10:35:24多表关联查询多表关联在xml中写sql,where条件可用queryWrapper实现dao中插入分页对象和查询条件(Page page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper),xml中使用${ew.customSqlSegment}代替where ...多表关联查询多表关联在xml中写sql,where条件可用queryWrapper实现dao中插入分页对象和查询条件(Page page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper),xml中使用${ew.customSqlSegment}代替where
1.sqlSELECT w.works_id worksId, w.user_id userId, w.user_id_type userIdType, w.title, w.content, w.media_type mediaType, w.media_ids mediaIds, w.first_image_id firstImageId, w.works_tag worksTag, w.lon_map lonMap, w.lat_map latMap, w.location, w.district_id districtId, w.like_num likeNum, w.favorite_num favoriteNum, w.comment_num commentNum, m.image_id imageId, p.nick_name nickName, w.create_time createTime FROM fmzy_biz.works w LEFT JOIN fmzy_main.user_image m on w.user_id = m.user_id LEFT JOIN fmzy_main.user_person p on w.user_id = p.user_id WHERE m.image_type = 'U_TX' AND p.test_flag = 0 AND w.show_flag = 1 AND ( p.nick_name LIKE '%1%' OR w.title LIKE '%1%' OR w.content LIKE '%1%' ) ORDER BY w.works_id DESC LIMIT 0,20
2.java
QueryWrapper<WorksInfoVO> queryWrapper = new QueryWrapper<WorksInfoVO>() .eq("m.image_type", "U_TX") .eq("p.test_flag", 0) .eq("w.show_flag", 1) .in(!CollectionUtils.isEmpty(districtIds), "w.district_id", districtIds) .eq(StringUtils.isNotBlank(mediaType), "w.media_type", mediaType) .eq(StringUtils.isNotBlank(worksTag), " w.works_tag", worksTag) .eq(StringUtils.isNotBlank(userIdType), "w.user_id_type", userIdType) .and(qw->qw.like(StringUtils.isNotBlank(content),"p.nick_name",content) .or() .like(StringUtils.isNotBlank(content),"w.title",content) .or() .like(StringUtils.isNotBlank(content),"w.content",content)).orderByDesc("w.works_id"); Page<WorksInfoVO> page = new Page<>(pageNo, pageSize); IPage<WorksInfoVO> ipage = baseMapper.getFindWorksPage(page,queryWrapper);
3.dao
IPage<WorksInfoVO> getFindWorksPage(Page<WorksInfoVO> page, @Param(Constants.WRAPPER) QueryWrapper<WorksInfoVO> queryWrapper);
4.xml
<select id="getFindWorksPage" resultType="bw.fmzy.svc.web.main.vo.WorksInfoVO"> SELECT w.works_id worksId, w.user_id userId, w.user_id_type userIdType, w.title, w.content, w.media_type mediaType, w.media_ids mediaIds, w.first_image_id firstImageId, w.works_tag worksTag, w.lon_map lonMap, w.lat_map latMap, w.location, w.district_id districtId, w.like_num likeNum, w.favorite_num favoriteNum, w.comment_num commentNum, m.image_id imageId, p.nick_name nickName, w.create_time createTime FROM fmzy_biz.works w LEFT JOIN fmzy_main.user_image m on w.user_id = m.user_id LEFT JOIN fmzy_main.user_person p on w.user_id = p.user_id ${ew.customSqlSegment} </select>
-
基于QueryWrapper,实现MybatisPlus多表关联查询
2022-03-10 10:04:50"为保留关键字,拆分数组,仅支持最大长度2的数组, * 下标0:QueryWrapper查询条件中的列名(支持多表关联查询的表别名 + 列名方式,需要dao层接口支持) * 下标1: QueryWrapper中不同的查询条件,eq:等于,ge:...版权声明:请勿用于任何商业用途的文章转载,转载请说明出处!
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<SkuStock> selectPage(IPage<SkuStock> page, @Param("ew")Wrapper<SkuStock> queryWrapper);
2.service层代码示例:
service父类封装的findPage方法:
/** * 封装findPage * @param entity * @param search Map中的key:";"为保留关键字,拆分数组,仅支持最大长度2的数组, * 下标0:QueryWrapper查询条件中的列名(支持多表关联查询的表别名 + 列名方式,需要dao层接口支持) * 下标1: QueryWrapper中不同的查询条件,eq:等于,ge:大于等..... todo:请自行完善Mybatis eq、ne、gt、lt、ge、le等 * Map中的value:QueryWrapper需要查询的值 * @param args QueryWrapper中order by 排序数组 * @return */ public IPage<T> findPage(T entity , Map<String , Object> 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<T> queryWrapper; if (EmptyUtil.isNoEmpty(search)){ queryWrapper = new QueryWrapper<>(); for (Map.Entry<String , Object> 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<T>(current , size) , queryWrapper); }
service实现类方法:
public IPage<SkuStock> findPage(SkuStock entity, String... args) { Map<String , Object> 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 List<Field> getObjectFields(Object obj){ Class clazz = obj.getClass(); List<Field> fieldList = new ArrayList<>() ; while (clazz != null) {//当父类为null的时候说明到达了最上层的父类(Object类). fieldList.addAll(Arrays.asList(clazz .getDeclaredFields())); clazz = clazz.getSuperclass(); //得到父类,然后赋给自己 } return fieldList; } public static List<Field> getObjectFields(Class<?> clazz){ List<Field> 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<Field> fieldList = getObjectFields(entity); for (Field f1:fieldList ) { if (fieldName.equals(f1.getName())) return true; } return false; } /** * 返回 entity 对象中的所有方法,包含父类 * @param entity * @return */ public static List<Method> getObjectMethods(Object entity){ Class<?> clazz = entity.getClass(); List<Method> 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<Method> getObjectMethods(Class<?> clazz){ List<Method> 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<Method> 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 所代表的方法,其方法的参数是 parameters return 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 所代表的值 设置为 value field.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 noninstantiability private 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); } }
-
SpringBoot+MybatisPlus实现关联表查询
2020-04-07 23:46:06最近写代码用到了mybatisPlus涉及到关联表查询。需求是这样的: 我有一个专业表major其中有个字段是所属院系dept_id,我需要通过这个dept_id关联院系表department的ID去获取院系的名称。例如:国际贸易。 实现效果:... -
MybatisPlus是否支持多表关联查询
2021-07-12 17:22:43如何可以如何使用,如何来区分不同表同名字段。 我现在是用这种方法进行多表联查的,这样是否合适。 Wrappers.query().eq("bqti.status", 0); -
MybatisPlus 关联查询方案
2021-12-14 16:54:28Mybatis-Plus 简介 什么是 MyBatis-Plus?Mybatis-Plus:为简化开发而生 MyBatis-Plus(简称 MP)是一个基于 MyBatis 的增强工具,...Mybatis-Plus 其实可以看作是对 Mybatis 的再一次封装,升级之后,对于单表的 C -
基于MybatisPlus实现多表的关联查询,实现分页,多条件查询
2020-08-20 15:15:27实现商品表,通过表内的id关联查询到供应商表的name属性 商品表 如下所示 供应商表 如下所示 新建查询测试sql 注意, 1、查询tb_goods表的全部,所以用t1.*,查询t2表的name,并用supplierName替换名称 2、使用... -
MybatisPlus多表连接查询
2022-01-20 08:48:59一、序言 (一)背景内容 软件应用技术架构中DAO层最常见的选型组件为MyBatis,熟悉MyBatis的朋友都清楚,曾几何时MyBatis是多么的风光,使用XML文件...MybatisPlus官方并没有提供多表连接查询的通用解决方案,然而连接 -
MybatisPlus 多表关联查询带分页
2021-03-22 11:54:20https://blog.csdn.net/caidingnu/article/details/103739805 -
MybatisPlus自定义Sql实现多表查询的示例
2020-08-24 19:49:25主要介绍了MybatisPlus自定义Sql实现多表查询的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
MybatisPlus多表分页查询
2022-02-16 22:30:36三、根据业务 组装查询构造器 四 、 编写ServeImpl 以及 编写mapper.xnl 一、 /** MyBatis - Plus 配置 / @Slf4j @EnableTransactionManagement @Configuration public class MyBatisPlusConfig { /** * 乐观锁 *... -
MybatisPlus多表联查分页查询
2021-11-03 20:55:16//param 用于存放查询条件 Map ,Long>params = new HashMap(); if (index.getBoardId() != null) { params.put(Constant.INDEX_SET_BELONG_BOARD_ID,index.getBoardId()); } if (index.getIndexId() != null) { ... -
关于myBatis和myBatisPlus关联表的查询
2018-06-11 14:50:501.myBatis表关联查询:在mapper.xml映射文件中添加<collection>或者<association>去关联另一张表.2.myBatisPlus:使用EntityWapper对实体进行封装,通过IService中封装的sql方法去对实体... -
MyBatisPlus 注解方式实现多表关联查询
2021-06-16 10:32:52目录官方API使用概述具体写法Mapper写法:entity写法:service写法:日志报错结果截图 官方API ...使用概述 Mapper层方法上添加 ${ew.customSqlSegment}和@Param(Constants.WRAPPER)...查询vo添加对应的查询条件字段,结果 -
mybatis-plus多表关联查询
2021-11-02 10:13:05mybatis-plus多表关联查询 学习内容: mybatis-plus多表关联查询 实体类部分代码 @Data @AllArgsConstructor @NoArgsConstructor @TableName("wb_member") public class WbMember implements Serializable { ... -
MybatisPlus实现多表联查、分页查询
2022-03-12 13:06:19MybatisPlus对于单表的操作很方便,但是多表查询等复杂的操作还是需要在xml中写sql语句来完成。 那么,在MybatisPlus中如何实现多表联查、分页查询呢? 一、数据库表设计 新建学生表 student 和课程表 course 学生... -
使用mybatisPlus注解方式多表关联查询带条件分页
2021-05-21 17:45:004、利用QueryWrapper对象进行条件查询,单表查询的网上有很多了,多表查询的使用居然不给用列别名,所以里面的条件查询都是用的表的列字段,更多的可以去看mybatisplus的官方文档有介绍api 5、因为我要分页 ,所以...