高级示例:用户-角色-菜单(权限),三者之间分别都是多对多的关系,查询用户的时候,期望查询用户下所有的角色与权限。
1、构建实体对象
@Data@Table(comment = "菜单信息")public class Menu {@ColumnComment("主键")private String id;@ColumnComment("菜单名")private String name;// 省略其他信息.......}
@Data@Table(comment = "角色信息")public class Role {@ColumnComment("主键")private String id;@ColumnComment("角色名")private String name;// @BindEntityByMid是可以实现通过中间表关联数据,主要属性conditions,midEntity指定中间表实体(该实体必须有对应的MP的Mapper),//@BindEntityByMid(conditions = @MidCondition(midEntity = RoleMenu.class, selfMidField = "roleId", joinMidField = "menuId"), orderBy = @JoinOrderBy(field = "name"))private List<Menu> menus;// 省略其他信息.......}
@Data@Table(comment = "用户信息")public class User {@ColumnComment("主键")private String id;@ColumnComment("用户名")private String username;@ColumnComment("密码")private String password;// 通过中间表关联所有相关的角色。// 通过中间表的形式需要使用@Bind*ByMid@BindEntityByMid(conditions = @MidCondition(midEntity = UserRole.class, selfMidField = "userId", joinMidField = "roleId"), orderBy = @JoinOrderBy(field = "name"))private List<Role> roles;// 省略其他信息.......}
@Data@Table(comment = "角色-菜单关联关系")public class RoleMenu {@ColumnComment("主键")private String id;@ColumnComment("角色id")private String roleId;@ColumnComment("菜单id")private String menuId;}
@Data@Table(comment = "用户-角色关联关系")public class UserRole {@ColumnComment("主键")private String id;@ColumnComment("用户id")private String userId;@ColumnComment("角色id")private String roleId;}
2、数据查询
/*** 用户服务*/@Slf4j@Servicepublic class UserService {@Resourceprivate UserRepository userRepository;/*** 根据用户的名字模糊查询所有用户的详细信息*/@Transactional(readOnly = true)public List<UserDetailWithRoleDto> searchUserByName(String name) {// MP的lambda查询方式List<User> userList = userRepository.lambdaQuery().eq(name != null, User::getUsername, name).list();// 关键步骤,指定关联角色数据。如果你打开sql打印,会看到3条sql语句,第一条根据id去User表查询user信息,第二条根据userId去UserRule中间表查询所有的ruleId,第三条sql根据ruleId集合去Rule表查询全部的权限Binder.bindOn(userList, User::getRoles);// Deeper为一个深度遍历工具,可以深入到对象的多层属性内部,从而获取全局上该层级的所有对象同一属性Binder.bindOn(Deeper.with(userList).inList(User::getRoles), Role::getMenus);return UserMapping.MAPPER.toDto5(userList);}/*** 根据用户的名字模糊查询所有用户的详细信息,等价于上一个查询方式*/@Transactional(readOnly = true)public List<UserDetailWithRoleDto> searchUserByName2(String name) {// 本框架拓展的lambda查询器lambdaQueryPlus,增加了bindOne、bindList、bindPage// 显然这是一种更加简便的查询方式,但是如果存在多级深度的关联关系,此种方法就不适用了,还需要借助BinderList<User> userList = userRepository.lambdaQueryPlus().eq(name != null, User::getUsername, name)// 用法一、指定属性关联,只关联身份证号这个字段。.bindList(User::getRoles);// 用法二、全关联。// .bindList();// Deeper为一个深度遍历工具,可以深入到对象的多层属性内部,从而获取全局上该层级的所有对象同一属性Binder.bindOn(Deeper.with(userList).inList(User::getRoles), Role::getMenus);return UserMapping.MAPPER.toDto5(userList);}}
