场景
业务中经常会用到一对多的数据库的设计与数据的增删改查的实现。
比如要实现一个对手机应用配置允许访问的权限的业务。
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 classYckzAppgl
{private static final long serialVersionUID = 1L;/** id*/
privateLong id;/** 应用编码*/
privateString appcode;/** 应用名称*/
privateString appname;/** 数据存储路径*/
privateString sjcclj;/** 应用包名*/
privateString appbm;/**
* 创建时间*/
privateDate cjsj;/**
* 权限列表*/
private ListqxList;public ListgetQxList() {returnqxList;
}public void setQxList(ListqxList) {this.qxList =qxList;
}public intgetOffset() {returnoffset;
}public void setOffset(intoffset) {this.offset =offset;
}public intgetPageNum() {returnpageNum;
}public void setPageNum(intpageNum) {this.pageNum =pageNum;
}public intgetPageSize() {returnpageSize;
}public void setPageSize(intpageSize) {this.pageSize =pageSize;
}publicDate getCjsj() {returncjsj;
}public voidsetCjsj(Date cjsj) {this.cjsj =cjsj;
}public voidsetId(Long id)
{this.id =id;
}publicLong getId()
{returnid;
}public voidsetAppcode(String appcode)
{this.appcode =appcode;
}publicString getAppcode()
{returnappcode;
}public voidsetAppname(String appname)
{this.appname =appname;
}publicString getAppname()
{returnappname;
}public voidsetSjcclj(String sjcclj)
{this.sjcclj =sjcclj;
}publicString getSjcclj()
{returnsjcclj;
}public voidsetAppbm(String appbm)
{this.appbm =appbm;
}publicString getAppbm()
{returnappbm;
}
@OverridepublicString 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 qxList;
这样在进行查询主表数据时能将从表的权限数据进行存储。
从表的实体类
public classYckzQuanxian extends BaseEntity
{private static final long serialVersionUID = 1L;/** id*/
privateLong id;/** 权限编码*/
privateString qxcode;/** 权限名称*/
privateString qxname;/** 权限包名*/
privateString qxbm;//是否勾选
privateBoolean sfgx;publicBoolean getSfgx() {returnsfgx;
}public voidsetSfgx(Boolean sfgx) {this.sfgx =sfgx;
}public voidsetId(Long id)
{this.id =id;
}publicLong getId()
{returnid;
}public voidsetQxcode(String qxcode)
{this.qxcode =qxcode;
}publicString getQxcode()
{returnqxcode;
}public voidsetQxname(String qxname)
{this.qxname =qxname;
}publicString getQxname()
{returnqxname;
}public voidsetQxbm(String qxbm)
{this.qxbm =qxbm;
}publicString getQxbm()
{returnqxbm;
}
@OverridepublicString 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接口层。
@AutowiredprivateIYckzAppglService yckzAppglService;
@AutowiredprivateIYckzQuanxianService yckzQuanxianService;
@Autowiredprivate IYckzAppglQxService yckzAppglQxService;
然后在主表中需要进行关联查询时,即又需要主表应用数据,又需要从表权限数据时
publicYckzAppgl confirmpeizhiquanxian(@RequestBody YckzAppgl yckzAppgl)
{//获取id
Long id =yckzAppgl.getId();//根据id获取编码
String appcode =yckzAppglService.selectYckzAppglById(id).getAppcode();//根据编码获取从表数据
List quanxianList =yckzAppglQxService.selectYckzAppglQxByCode(appcode);
YckzAppgl yckzAppglResult= newYckzAppgl ();
yckzAppglResult .setQxList(quanxianList );returnyckzAppglResult ;
}
首先根据传递的主表的id查询出主表的数据,获取主表的编码后去根据编码去关联表中获取权限表的id。
然后根据id去权限表中查询出权限的信息,将其赋值给主表的list。