业务描述

  • 资源的外在表现形式:菜单

    系统设计

原型设计

  • 菜单列表页面

image.png

  • 菜单编辑页面

image.png

  • 菜单修改页面

image.png

部门与菜单类似(不再描述)

image.png
image.png
image.png
image.png

表设计

  • common模块中

    核心API设计

    image.png

    逻辑实现

    领域对象POJO

    ```java package com.cy.pj.sys.pojo;

/**基于此对象存储内存中菜单信息

  • java中所有用于存储数据的对象,都建议实现序列化接口,并提供序列化id
  • 标准:
  • 对象序列化:将对象转换为字节 (其目的是便于网络传输或存储)
  • 反序列化:将字节转换为对象
  • 行业扩展:
  • JSON对象序列化:将对象转换JSON字符串
  • JSON对象反序列化:将json字符串转换为对象
  • */

@Data public class SysMenu implements Serializable { /建议手动生成序列化ID,唯一标识*/ private static final long serialVersionUID = 5531553051566760402L; //ObjectOutputStream /菜单ID/ private Integer id; /**菜单名字/ private String name; /菜单类型*/ private Integer type; /菜单url/ private String url; /**上级菜单id/ private Integer parentId; /上级菜单名称*/ private String parentName; /菜单排序号/ private Integer sort; /**菜单授权标识/ private String permission; /备注*/ private String remark; /创建时间/ private Date createdTime; /**修改时间/ private Date modifiedTime; /创建用户*/ private String createdUser; /修改用户*/ private String modifiedUser;

}

  1. <a name="PftZB"></a>
  2. ### Dao层
  3. - Dao层接口
  4. ```java
  5. package com.cy.pj.sys.dao;
  6. /**
  7. * 用于操作菜单表的数据访问对象
  8. */
  9. @Mapper
  10. public interface SysMenuDao {
  11. /**
  12. * 查询全部菜单,以及菜单对应的上级菜单名称
  13. *@paramm
  14. *@return
  15. */
  16. List<SysMenu> selectMenus();
  17. /**
  18. * 查询树节点信息,在添加或者编辑菜单时
  19. * 会以树结构方式呈现可选的菜单信息
  20. * @return
  21. */
  22. @Select("select id,name,parentId from sys_menus")
  23. List<Node> selectMenuTreeNodes();
  24. /**
  25. * 向数据库表中新增菜单信息
  26. * @param menu 存储了菜单信息的对象
  27. * @return 插入的行数
  28. */
  29. int insertMenu(SysMenu menu);
  30. /**
  31. * 基于id更新菜单信息
  32. * @param menu
  33. * @return 更新的行数
  34. */
  35. int updateMenu(SysMenu menu);
  36. /**
  37. * 基于用户id查询菜单授权标识(permission)
  38. * @param userId
  39. * @return
  40. */
  41. Set<String> selectUserPermissions(Integer userId);
  42. }

<insert id="insertMenu">
    insert into sys_menus
    (name,type,url,sort,parentId,permission,remark,createdTime,modifiedTime,createdUser,modifiedUser)
    values
    (#{name},#{type},#{url},#{sort},#{parentId},#{permission},#{remark},now(),now(),#{createdUser},#{modifiedUser})
</insert>

<update id="updateMenu">
    update sys_menus
    set name=#{name},
    type=#{type},
    url=#{url},
    sort=#{sort},
    parentId=#{parentId},
    permission=#{permission},
    remark=#{remark},
    modifiedTime=now(),
    modifiedUser=#{modifiedUser}
    where id=#{id}
</update>

  <select id="selectUserPermissions" resultType="string">
    select m.permission
    from sys_user_roles ur join sys_role_menus rm join sys_menus m
    on ur.role_id=rm.role_id and rm.menu_id=m.id
    where ur.user_id=#{userId} and m.permission is not null
    and trim(m.permission)&lt;&gt;''
</select>

<a name="z2U6B"></a>
### Service层

- 接口规范定义
```java
package com.cy.pj.sys.service;

/**
 * 菜单逻辑业务操作的规范定义
 */
public interface SysMenuService {
    /**查询所有菜单信息以及菜单对应的上级菜单名称*/
    List<SysMenu> findMenus();
    /**新增菜单信息*/
    int saveMenu(SysMenu entity);
    /**更新菜单信息*/
    int updateMenu(SysMenu entity);
    /**查找菜单树节点信息*/
    List<Node> findMenuTreeNodes();
}
  • 接口实现 ```java package com.cy.pj.sys.service.impl;

/*菜单业务管理/ @Service public class SysMenuServiceImpl implements SysMenuService { @Autowired private SysMenuDao sysMenuDao;

/**
 * 查询所有菜单。
 * 请思考,菜单数据会经常变化吗,假如每次访问菜单数据都查数据库
 * 是否会对数据库带来一定的访问压力。即便是没有压力,那访问数据库
 * 的性能相对于直接访问内存,是不是会低一些?我们能否将查询到的
 * 数据在缓存放一份,下一次再取时,从数据库取。
 * @return
 */
@Cacheable("sysMenu") //缓存应用的切入点方法(底层AOP)
@Override
public List<SysMenu> findMenus() {
    //从缓存取,缓存有则直接返回
    //假如缓存没有,则去查数据库,然后将查询到结果存储到缓存
    return sysMenuDao.selectMenus();
}

/**
 * @CacheEvict注解描述方法时,表示方法是一个清缓存的切入点方法
 * 这里的value属性值表示要清除的缓存,allEntries=true表示要清除当前value属性指向的Cache中所有数据
 * beforeInvocation=false表示在执行增删改 之后才清理Cache
 * @param entity
 * @return
 */
@CacheEvict(value="sysMenu",allEntries = true,beforeInvocation = false)  //清理缓存数据
@Override
public int saveMenu(SysMenu entity) {
    return sysMenuDao.insertMenu(entity);
}

@CacheEvict(value="sysMenu",allEntries = true,beforeInvocation = false)  //清理缓存数据
@Override
public int updateMenu(SysMenu entity) {
    return sysMenuDao.updateMenu(entity);
}

@Override
public List<Node> findMenuTreeNodes() {
    return sysMenuDao.selectMenuTreeNodes();
}

}

<a name="bXC00"></a>
### Controller层
```java
package com.cy.pj.sys.web.controller;

@RequestMapping("/menu/")
@RestController
public class SysMenuController {
    @Autowired
    private SysMenuService sysMenuService;

    @PutMapping
    public JsonResult doUpdateMenu(@RequestBody SysMenu menu){
        sysMenuService.updateMenu(menu);
        return new JsonResult("Update Ok");
    }

    @PostMapping
    public JsonResult doSaveMenu(@RequestBody SysMenu menu){
        sysMenuService.saveMenu(menu);
        return new JsonResult("Save OK!");
    }

    @GetMapping("treeNodes")
    public JsonResult doFindMenuTreeNodes(){
        return new JsonResult(sysMenuService.findMenuTreeNodes());
    }

    @GetMapping
    public JsonResult doFindMenus(){
        return new JsonResult(sysMenuService.findMenus());
    }

}

Main

  • 主类添加注解@EnableCaching ```java package com.cy;

@EnableCaching //启动springboot工程中内置缓存 @SpringBootApplication public class AdminApplication { public static void main(String[] args) { SpringApplication.run(AdminApplication.class,args); } } ```