场景
业务中经常会用到一对多的数据库的设计与数据的增删改查的实现。
比如要实现一个对手机应用配置允许访问的权限的业务。
app与权限就是一对多的关系。即一个app可以拥有多个权限。
注:
关注公众号 霸道的程序猿 获取编程相关电子书、教程推送与免费下载。
实现
首先设计数据库。要有一个app表、一个权限表、一个app与权限关联表。
首先设计app表
这里是存储的APP对象的一些属性,即一对多中一的那端。
然后创建权限表
这里是存储权限实体的一些属性,即一对多中多的那一方。
以上两个表的id都是主键并且是非空自增的。
然后还需要创建一个关联表实现这种一对多的映射关系。
这里使用的是主表的app编码用来跟从表的id进行关联。
为什么不用主表的id和从表的id进行关联,因为在执行插入时,主表的app编码是有点的,但是id设置是自增的,还没有值,
所以用主表的编码和从表的id进行关联。
比如app表中的数据有
权限表中的数据
那么映射表中的数据
以上映射表代表编码为weixin的app对应id为1的权限,编码为qq的app对应id为1和2的权限。
数据库设计好之后就是对应的实体类以及相关的代码这里使用代码生成工具将主表app表和从表权限表以及之间的关联表生成实体类和相关代码。
主表app表实体
public class YckzAppgl{ private static final long serialVersionUID = 1L; /** id */ private Long id; /** 应用编码 */ private String appcode; /** 应用名称 */ private String appname; /** 数据存储路径 */ private String sjcclj; /** 应用包名 */ private String appbm; /** * 创建时间 */ private Date cjsj; /** * 权限列表 */ private List<YckzAppglQx> qxList; public List<YckzAppglQx> getQxList() { return qxList; } public void setQxList(List<YckzAppglQx> qxList) { this.qxList = qxList; } public int getOffset() { return offset; } public void setOffset(int offset) { this.offset = offset; } public int getPageNum() { return pageNum; } public void setPageNum(int pageNum) { this.pageNum = pageNum; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public Date getCjsj() { return cjsj; } public void setCjsj(Date cjsj) { this.cjsj = cjsj; } public void setId(Long id) { this.id = id; } public Long getId() { return id; } public void setAppcode(String appcode) { this.appcode = appcode; } public String getAppcode() { return appcode; } public void setAppname(String appname) { this.appname = appname; } public String getAppname() { return appname; } public void setSjcclj(String sjcclj) { this.sjcclj = sjcclj; } public String getSjcclj() { return sjcclj; } public void setAppbm(String appbm) { this.appbm = appbm; } public String getAppbm() { return appbm; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) .append("appcode", getAppcode()) .append("appname", getAppname()) .append("sjcclj", getSjcclj()) .append("appbm", getAppbm()) .toString(); }}这里除了用代码生成工具生成的基本属性外,还要添加一个从表权限的List
private List<YckzAppglQx> qxList;这样在进行查询主表数据时能将从表的权限数据进行存储。
从表的实体类
public class YckzQuanxian extends BaseEntity{ private static final long serialVersionUID = 1L; /** id */ private Long id; /** 权限编码 */ private String qxcode; /** 权限名称 */ private String qxname; /** 权限包名 */ private String qxbm; //是否勾选 private Boolean sfgx; public Boolean getSfgx() { return sfgx; } public void setSfgx(Boolean sfgx) { this.sfgx = sfgx; } public void setId(Long id) { this.id = id; } public Long getId() { return id; } public void setQxcode(String qxcode) { this.qxcode = qxcode; } public String getQxcode() { return qxcode; } public void setQxname(String qxname) { this.qxname = qxname; } public String getQxname() { return qxname; } public void setQxbm(String qxbm) { this.qxbm = qxbm; } public String getQxbm() { return qxbm; } @Override public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append("id", getId()) .append("qxcode", getQxcode()) .append("qxname", getQxname()) .append("qxbm", getQxbm()) .toString(); }}然后对这两个表分别使用代码生成工具生成Controller、Service、ServiceImpl、Mapper等相关代码。
然后在主表对应的Controller中,分别引入主表从表和关联表对应的Service接口层。
@Autowired private IYckzAppglService yckzAppglService; @Autowired private IYckzQuanxianService yckzQuanxianService; @Autowired private IYckzAppglQxService yckzAppglQxService;然后在主表中需要进行关联查询时,即又需要主表应用数据,又需要从表权限数据时
public YckzAppgl confirmpeizhiquanxian(@RequestBody YckzAppgl yckzAppgl) { //获取id Long id = yckzAppgl.getId(); //根据id获取编码 String appcode = yckzAppglService.selectYckzAppglById(id).getAppcode(); //根据编码获取从表数据 List<YckzAppglQx> quanxianList = yckzAppglQxService.selectYckzAppglQxByCode(appcode); YckzAppgl yckzAppglResult = new YckzAppgl (); yckzAppglResult .setQxList(quanxianList ); return yckzAppglResult ; }首先根据传递的主表的id查询出主表的数据,获取主表的编码后去根据编码去关联表中获取权限表的id。
然后根据id去权限表中查询出权限的信息,将其赋值给主表的list。