您现在的位置是:首页 > 文章详情

不设外键:用程序来实现表之间的关联

日期:2018-08-07点击:443
img_2876f76a73e7ca18ee9b074196a50485.jpe
Association

相信有很多同学都有使用过Hibernate框架的开发经验,尽管现在开发人员对Hibernate的褒贬不一,我们暂且不谈这个话题。
图中的三个注解,正好解析了表与表之间的关联关系。我也就不这这方面进行过多的赘述了。所以...
今天的主题是:我想在不涉及表与表之间的关联关系的情况下对表进行关联。
换成对应的表的意思就是,不设外键,实现多对多关联。话不多说 先上一张我自己的设计手稿:


img_9bebe716b78970bf19e1a1ee2c74ebb7.jpe
手稿

数据库:(数据库的编码(utf8)与数据库引擎(InnonDB)已经设置好了)

CREATE table t_user( uid int(10) NOT NULL PRIMARY KEY AUTO_INCREMENT, username VARCHAR(100) not null, password VARCHAR(100) not null, createtime date not null )default CHARSET=utf8; -- 创建角色表 CREATE TABLE t_role( rid int(10) not null PRIMARY KEY AUTO_INCREMENT, rname VARCHAR(100) not null ) -- 权限表db_auth CREATE TABLE t_authority( aid int(10) not null PRIMARY KEY AUTO_INCREMENT, aname VARCHAR(100) not NULL, url VARCHAR(100) not NULL ) -- 意义上的中间表 CREATE TABLE t_role_authority( rid int(10) not null, aid int(10) not NULL, KEY index_rid(rid), KEY index_aid(aid) ) CREATE TABLE t_user_role( uid int(10) not null, rid int(10) not null, KEY index_uid(uid), KEY index_rid(rid) ) 
img_a055ac723c5ef7aaa04d98f3866746ea.png
没有任何关联关系的5张表

项目框架选型我用的是SpringBoot+MyBatis


img_d15f2c6a9ea936c17983d41d15387bf9.png
项目结构

Vo类:

package cn.calista.sbm.pojo.Vo; import cn.calista.sbm.pojo.Authority; import java.util.HashSet; /** * 权限和角色也是多对多 */ public class AuthorityVo extends Authority { private HashSet<RoleVo> roleVos = new HashSet<>(); public HashSet<RoleVo> getRoleVos() { return roleVos; } public void setRoleVos(HashSet<RoleVo> roleVos) { this.roleVos = roleVos; } } 
package cn.calista.sbm.pojo.Vo; import cn.calista.sbm.pojo.Role; import java.util.HashSet; /** * Role 和 User 多对对 * Role 和 authority 多对多 */ public class RoleVo extends Role { private HashSet<AuthorityVo> authorityVos = new HashSet<>(); private HashSet<UserVo> userVos = new HashSet<>(); public HashSet<AuthorityVo> getAuthorityVos() { return authorityVos; } public void setAuthorityVos(HashSet<AuthorityVo> authorityVos) { this.authorityVos = authorityVos; } public HashSet<UserVo> getUserVos() { return userVos; } public void setUserVos(HashSet<UserVo> userVos) { this.userVos = userVos; } } 
package cn.calista.sbm.pojo.Vo; import cn.calista.sbm.pojo.User; import java.util.HashSet; /** * 用户和角色 多对多 */ public class UserVo extends User { private HashSet<RoleVo> roleVos = new HashSet<>(); public HashSet<RoleVo> getRoleVos() { return roleVos; } public void setRoleVos(HashSet<RoleVo> roleVos) { this.roleVos = roleVos; } } 

这里说一句,虽然用户和角色是多对多的关系,但是我们在实际开发中并不会去关注一个角色被多少用户所拥有,我们关心的更多的是一个用户拥有哪些角色然后拥有多少权限。所以我们实际理解就可以理解为 用户和角色是 一对多的关系就OK

至于XML Mapper 的代码我就不在粘了 直接上核心代码

package cn.calista.sbm; import cn.calista.sbm.mapper.*; import cn.calista.sbm.pojo.*; import cn.calista.sbm.pojo.Vo.AuthorityVo; import cn.calista.sbm.pojo.Vo.RoleVo; import cn.calista.sbm.pojo.Vo.UserVo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.HashSet; import java.util.Iterator; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class SbmApplicationTests { @Autowired private UserMapper userMapper; @Autowired private UserRoleMapper userRoleMapper; @Autowired private RoleMapper roleMapper; @Autowired private RoleAuthorityMapper roleAuthorityMapper; @Autowired private AuthorityMapper authorityMapper; @Test public void testMethod() { UserVo userVo = new UserVo(); RoleVo roleVo = null; AuthorityVo authorityVo = null; //根据uid 查询到 user User user = userMapper.getUser(1); //拿到User 装配给 UserVo BeanUtils.copyProperties(user, userVo); //根据user的uid 查询 user_role 用户角色表 得到该 user所拥有的角色集合 List<UserRole> userRoleList = userRoleMapper.getUserRoleList(user.getUid()); //遍历 操作每一个 用户角色对象 for (UserRole userRole : userRoleList ) { // 拿到角色 Role role = roleMapper.getRoleById(userRole.getRid()); roleVo = new RoleVo(); // 拿到role 装配给 roleVo BeanUtils.copyProperties(role, roleVo); //通过每一个role的rid 查询中间表roleAuthority 的到该角色的权限集合 List<RoleAuthority> roleAuthorites = roleAuthorityMapper.getRoleAuthorites(role.getRid()); //遍历权限集合 for (RoleAuthority roleAuthority : roleAuthorites ) { //通过aid查询到权限 Integer aid = roleAuthority.getAid(); Authority authority = authorityMapper.getAuthorityById(aid); authorityVo = new AuthorityVo(); BeanUtils.copyProperties(authority, authorityVo); authorityVo.getRoleVos().add(roleVo); //装配roleVo中的AuthorityVos roleVo.getAuthorityVos().add(authorityVo); } //装配userVo属性roleVos userVo.getRoleVos().add(roleVo); } } } 

最后测试一下:
我想知道id是 1 的用户拥有哪些权限?

HashSet<AuthorityVo> authorityVos = roleVo.getAuthorityVos(); Iterator<AuthorityVo> it = authorityVos.iterator(); while (it.hasNext()){ AuthorityVo next = it.next(); System.out.println(next.getAname()); } 
img_f765181dd4615ad75ce8427545406852.png
测试结果

再查看一下数据库


img_dd0fbac20ed0d7285799cf58aa64f0f5.png
user

img_dff2688e429f0e1f37e752d5b28bd59c.png
role

img_49193d0182fa3533d29d9eb546cc30d1.png
authority

img_41f314a1f789f79ad7e560928699c77b.png
role_Authority

img_9d12fd3c1e0ebfef6185009aa7704763.png
user_role

最后,实现了关联。(并没有使用连接查询)

img_b6916100578997ef6ed29449730d5e59.png
image.png

img_fbc3bc9957109ea5fa69723fc0d99382.png
image.png

img_dd65e878f322968dcf2fd8f771a46c84.png
image.png

img_7d604b440b15272f36e96ed915e1ebc1.png
image.png

img_e457c209fd9bdbeaa63aebb20eb491f8.png
image.png
原文链接:https://yq.aliyun.com/articles/637801
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章