前面我们做的小项目都是一个表的,业务代码也相对简单。现在我们来做一个权限管理系统,体验一下多表的业务逻辑,顺便巩固一下过滤器的知识。!该项目的GitHub地址:https://github.com/ZhongFuCheng3y/Privilege
目的
现在我有一个管理商品、订单的页面。当用户点击某个超链接时,过滤器会检测该用户是否有权限!
![311e3fee657c6b9c46e111ae239f2228.png](https://i-blog.csdnimg.cn/blog_migrate/0ce6f598a95c79ef42aacbd41e79bff4.jpeg)
需求分析
按照面向对象的思想,我们至少应该有权限(Privilege)和用户(User)实体。两个实体足够了吗?细想一下,如果我们有多个用户,多个用户也有多个权限,当要为用户授权的时候,这样子就会非常麻烦!所以我们应该引入角色(Role)这个实体!
引入角色(Role)这个实体方便在哪呢??把权限赋给角色(比如:把删除、修改的权限给管理员这个角色),管理员这个角色再赋给用户,那么该用户就有了修改、删除的权限了!
权限和角色是多对多的关系,角色和用户也是多对多的关系!
开发实体
用户实体
![de92e4354ab1d3cb9b9eb3767c7f49a9.png](https://i-blog.csdnimg.cn/blog_migrate/bf69a512263eac06b4c835b73bdb6e32.jpeg)
角色实体
![8bd5befe1e8e71e974bbe22b5cbcc67b.png](https://i-blog.csdnimg.cn/blog_migrate/f4e0f168079ef87ea2f93f10a48c45f1.jpeg)
权限实体
![656947638cabeee63042aa3600858d20.png](https://i-blog.csdnimg.cn/blog_migrate/5b0708c8ad38cfc0ec1360a13e6c9ca6.jpeg)
改良
用户和角色、角色和权限都是多对多的关系,这是毋庸置疑的!我们也按照面向对象的方法来设计,用集合来记住另一方的数据!
但是呢,我们想想:
- 在权限的Dao中,在查看权限的时候,有必要列出相对应的角色吗??
- 在角色的Dao中,在查看角色的时候,有必要列出相对应的用户吗??
答案是没有的,一般我们都不会显示出来。所以,权限的实体没必要使用Set集合来记住角色,角色实体没必要使用Set集合来记住用户!
改良后的权限实体
![fd837304eb7e1d2f5ab17b03a01b58ab.png](https://i-blog.csdnimg.cn/blog_migrate/dafedb5f9e25bd6a96f07e35bc64f900.jpeg)
改良后的角色实体
![869dca2782d3cc5292d73c62eac97a28.png](https://i-blog.csdnimg.cn/blog_migrate/55818bc1eecdb0dd51d52ca86b6013b8.jpeg)
在数据库中建表
user表
![7d4d0b735aeeba238920d95f3d756977.png](https://i-blog.csdnimg.cn/blog_migrate/ea37f3058301e24d27cf3da283fe0872.jpeg)
role表
![57de97383340fa41410259f659ea27e1.png](https://i-blog.csdnimg.cn/blog_migrate/f7d9310d264a25658cf3cdadae10b4a2.jpeg)
privilege表
![24265a3c6e7ad3140972c39833dc069d.png](https://i-blog.csdnimg.cn/blog_migrate/c9a5fcf0a09844f56ccbcbc05c943a0e.jpeg)
user和role的关系表
![0f4b8c95ff50812c3e40b7f535b11bf3.png](https://i-blog.csdnimg.cn/blog_migrate/05d9d446b3dc008be42134bdcf53de0b.jpeg)
role和privilege的关系表
![df5199cf7d79dbe536e11526aac7c886.png](https://i-blog.csdnimg.cn/blog_migrate/756f756e69471bd35ad964d1cc27109b.jpeg)
注意:user和role的关系表、role和privilege的关系都有role_id作为外键,外键的名称是不能一样的!
开发DAO
PrivilegeDao
![c52e80ac7e8b68cc78dff902b1884981.png](https://i-blog.csdnimg.cn/blog_migrate/f8533ac38487a84f6576ffb0b3fe29b8.jpeg)
UserDao
![540e4b9f6af638964669661feff17fc4.png](https://i-blog.csdnimg.cn/blog_migrate/d17ee727f4ab923ff8d1dd9586d0528f.jpeg)
RoleDao
![31cc57e0b80e73b33fc97f12c5c155f9.png](https://i-blog.csdnimg.cn/blog_migrate/6c3feaee4c7477ef479a23d6c6916df8.jpeg)
补充
上面的仅仅是单表的Dao功能,User和Role表是多对多的关系,Role和Privilege表也是多对多的关系。
前面已经分析了
- 在User对象中,需要一个Set集合来记住Role的关系。【显示用户的时候,应该把所有角色显示出来】
- 在Role对象中,需要一个Set集合来记住Privilege的关系【显示角色的时候,应该把所有权限显示很出来】。
所以应该在UserDao有获取某用户所有的角色的方法:
![00db5d751cce2426caf99655f93d4b0a.png](https://i-blog.csdnimg.cn/blog_migrate/049d9ce0a571d0a4fd00ad7e138d3a97.jpeg)
在RoleDao有获取所有权限的方法:
![e75ba198ab47768d48199537db80853f.png](https://i-blog.csdnimg.cn/blog_migrate/30f3eb20715305fa560e7a3b17e1f6e4.jpeg)
我们既然能获取得到用户所有的角色了,获取得到角色所有的权限了。那自然我们就应该有修改用户的角色功能,修改角色的权限的功能啦!
我们先来分析一下它怎么写:要修改用户所拥有的角色,应该知道修改用户是哪一个,所以需要用户的id或者User对象!修改的角色是什么,需要Role对象或者装载Role对象的集合!
在UserDao有修改某用户角色的方法,我们是想把所有的角色都删除了,再添加新的角色
![f5db638ffb61cb236636ae07ff19946e.png](https://i-blog.csdnimg.cn/blog_migrate/5a61a32e20e9815dba36b5f2d137e43a.jpeg)
在RoleDao有修改角色权限的方法,和上面是类似的。
![0b05e5b5d091fe09aba59ce17b6cdaf8.png](https://i-blog.csdnimg.cn/blog_migrate/22b4837386a1233bf618b2b20c35b31e.jpeg)
更新
刚才又思考了一下:
- 其实我们并不需要在User类用使用集合来维护Role,在Role中使用集合来维护Privilege。在原本的做法我们已经看到了,我们完全是不需要这两个变量也能完成效果的。
- 那么,现在问题就来了。什么时候我们才需要在实体中使用变量来维护多的一方的关系呢???我觉得是这样的:当我们在查询一方数据的时候,另一方的数据也同时需要展示。那么此时我们就应该使用集合来维护多的一方数据了。
- 基于上面一个例子,就比如:订单与订单项。当我们查看订单的时候,同时一定会把所有的订单项都列举出来。
- 再比如:当我们查看购物车的时候,就需要把所有的购物项都列举出来。
- 而我们使用展示用户的时候,并不需要第一时间就把角色列举出来,而是通过超链接来查看用户下的角色,基于这种情况,我觉得我们是不用使用集合变量来维护多的一方的数据的。
这就跟Hibernate的懒加载差不多。用到关联关系的数据的时候才加载,没有用到的时候就先不查询数据库。
开发BusinessService
UserService
![09f26409fa1f6c21bf30f7143bd17854.png](https://i-blog.csdnimg.cn/blog_migrate/82f60e019908a1ee5becc633ca061ae9.jpeg)
RoleService
![68f5d66ada1bf5817c9e082c033833f6.png](https://i-blog.csdnimg.cn/blog_migrate/673c75cf5ad5020a46935c45f6f1dd77.jpeg)
PrivilegeService
![1102e5bcbbfade188b36c32b69c2a64f.png](https://i-blog.csdnimg.cn/blog_migrate/813a7b07bca268b58deeed0554a8bc7f.jpeg)
开发Web
用户模块
添加用户
- 提供页面界面的Servlet
//直接跳转到显示添加用户的界面request.getRequestDispatcher("/WEB-INF/jsp/addUser.jsp").forward(request, response);
- 显示页面的JSP
![0cb13a722c8a42d5dc35dbc29aa5aa53.png](https://i-blog.csdnimg.cn/blog_migrate/72e547c7e7f9115dc01cbd9c94f71edf.jpeg)
- 处理表单数据的Servlet
![5afd42007ebc0c2003df5e55b901ca64.png](https://i-blog.csdnimg.cn/blog_migrate/0d92ac7d94e17cb8fc5a93ac9d8d2452.jpeg)
显示用户
- 提供页面界面的Servlet
![895170722f82dfcd12a89905c3d1e62c.png](https://i-blog.csdnimg.cn/blog_migrate/6e90d4bc89ce90d449a7a6554ce4f367.jpeg)
- 显示页面JSP
![9d922d0f75fefa50a7b562b0093a8d2f.png](https://i-blog.csdnimg.cn/blog_migrate/3c4997f7731f48e8730c8d30ba4ac2b9.jpeg)
- 效果:
![7a25ad863f2aa91b5f25b8ce4ab55458.png](https://i-blog.csdnimg.cn/blog_migrate/deaca2c47baf007cb0ed771099dae3cf.jpeg)
为用户添加角色
在显示用户的基础上,应该添加为用户授权角色的超链接。
![20b6664d1847c4415cd95a6bffb6dd46.png](https://i-blog.csdnimg.cn/blog_migrate/dbfd1100122f5274172ecfacce41f7dc.jpeg)
- 效果:
![fcbc99d828fca3d278a67a27bb44faa1.png](https://i-blog.csdnimg.cn/blog_migrate/5a2da53903e6bf0b6779f3073385e5b1.jpeg)
- 处理显示授权页面的Servlet
![17e5e8794986db06228b6ec6cd1f54e7.png](https://i-blog.csdnimg.cn/blog_migrate/1052f102812c9298b6c0214c62295d68.jpeg)
- 授权页面JSP
![9859bd4d18966ef5ec3967e3fd1ab9e6.png](https://i-blog.csdnimg.cn/blog_migrate/c67ca41313ecbc9b1d323f41daf53547.jpeg)
- 效果:
![0f09e81027abdd6704eec8f7718795eb.png](https://i-blog.csdnimg.cn/blog_migrate/4aaca43191b27e523ca2d5d3be92fca1.jpeg)
- 处理表单数据并为用户添加角色的Servlet
![16fce9c0e29b49d287db021ddde2e661.png](https://i-blog.csdnimg.cn/blog_migrate/552a631864325d72b5285b9473ce94c5.jpeg)
角色模块
添加角色
- 提供添加角色页面的Servlet
![ec650ba0602d778ef8a8a98c15fe4f4f.png](https://i-blog.csdnimg.cn/blog_migrate/535fea7fcd03bf41cd2b0983c1ecb1c3.jpeg)
- 显示页面JSP
![d49d54faad3e18c55936cd6ad8dea5bd.png](https://i-blog.csdnimg.cn/blog_migrate/5a5a8a730c78a49ebd15153982ddf009.jpeg)
- 处理表单数据并添加角色的Servlet
![bb6748a84ad230e0f6120dc818c17774.png](https://i-blog.csdnimg.cn/blog_migrate/49d226e983d79e982ed5bce88710e88e.jpeg)
- 效果:
![e286aabba16d1f1749e3f579f1c1fe3d.gif](https://i-blog.csdnimg.cn/blog_migrate/3168c43f5ac4a7770b384e4a276775a7.gif)
查看所有的角色
- 提供页面的Servlet
![d73f8bc479b0b6bb47d0d07196c7fcc0.png](https://i-blog.csdnimg.cn/blog_migrate/6588df2f05bfcf743e58f52624f18f43.jpeg)
- 显示页面JSP
![c2ad1f2879e26c0f4fdb40cb70d9eb25.png](https://i-blog.csdnimg.cn/blog_migrate/774c287b41e124bbe8594ebf552e1aca.jpeg)
- 效果
![04c3f7ed93a30b74173872d4a82c4c8a.png](https://i-blog.csdnimg.cn/blog_migrate/532fd28c44495df2e16774074a6ed0bc.jpeg)
为角色授权
与上面是类似的,我们要在查看角色的时候,添加授权的功能!
![d619be86ed2d1debacf02f92e4591b0d.png](https://i-blog.csdnimg.cn/blog_migrate/7b36f75fd66ebf19f3169776ea99fcbc.jpeg)
- 效果:
![88291abdacdcb81c809a01c3b052a133.png](https://i-blog.csdnimg.cn/blog_migrate/7111fb8feb3255c1753d87733824f2ae.jpeg)
- 提供显示权利页面的Servlet
![8e8e564b0d9a8d8a8949170df3d28374.png](https://i-blog.csdnimg.cn/blog_migrate/2bc73b86ecd1d073c8f0a98e69376e01.jpeg)
- 显示页面JSP
![a047130f8a298a69706d58e6ae2b1e50.png](https://i-blog.csdnimg.cn/blog_migrate/28ef39c7c2eb445281d4a473bf5d3e0f.jpeg)
- 效果:
![ad34c393bd71a74f7b819bed40c56f8d.png](https://i-blog.csdnimg.cn/blog_migrate/0b6bce5219c13e59f2a32d9b40e8b8a8.jpeg)
- 处理表单数据并添加角色权利的Servlet
![f6bd7d6a551a91b75ad1f42a88873f2f.png](https://i-blog.csdnimg.cn/blog_migrate/7977860121160983e3de763ce4424f9c.jpeg)
- 效果:
![556a9026a6e744c52e6ec42fb998d530.gif](https://i-blog.csdnimg.cn/blog_migrate/aa11908e74e1d25e97e708d1b39087ec.gif)
权限模块
添加权限
- 提供添加权限页面的Servlet
//直接跳转到jsp页面request.getRequestDispatcher("/WEB-INF/jsp/AddPrivilege.jsp").forward(request, response);
- 显示页面JSP
![5ace6b51876a50b6ae8bbd8f560ad46a.png](https://i-blog.csdnimg.cn/blog_migrate/ba1774719c6535930006d8c320ed96ff.jpeg)
- 效果:
![02625a6f8d6abf525da10c9c41be2a12.png](https://i-blog.csdnimg.cn/blog_migrate/091ca69defc392fd36c7a88d1fd64674.jpeg)
- 处理表单数据,并添加权限的Servlet
![68d951df4d9d0b3a4ca008ed31087288.png](https://i-blog.csdnimg.cn/blog_migrate/ebe60d6afbc42576af3b55881269c89b.jpeg)
- 效果:
![eaa6cdc6b3af5db0b0ee0038b8860d0a.gif](https://i-blog.csdnimg.cn/blog_migrate/8c8e83bb51a39291265bb3facca5563e.gif)
查看所有权限
- 提供页面的Servlet
//得到所有的权限PrivilegeService privilegeService = new PrivilegeService();List list = privilegeService.getAllPrivileges();request.setAttribute("list