第一步 使用oracle层级查询
使用oracle的层级查询可以简化一些复杂的查询操作,其树状结构层级查询的基本语法是:
select [level], column, expr...
from table
[where condition]
start with condition
connect by [prior nodeCode1 = nodeCode2 | nodeCode1 = prior nodeCode2]
order by field
其中level是层级数,start with中的condition用来表示限定条件,connect by中的condition用来表示连接条件,order by中的field是排序的字段。
对prior说明:要的时候有两种写法:connect by prior condition 或 connect by condition,前一种写法表示采用自上而下的搜索方式(先找父节点然后找子节点),后一种写法表示采用自下而上的搜索方式(先找叶子节点然后找父节点)。本段引用了https://blog.csdn.net/u012615705/article/details/78321022这位大佬所写的内容。
下面是我自己建的数据表
其中cid是父节点,pid是子节点,code是邮政编码,levels是层级,status是状态。我是直接在idea中里测试,就没有用plsql。例如下面这段我就是寻找父节点为1,然后寻找等级为2的子节点然后根据level的等级进行排序。
select * from COMMUNITYS where levels=2 start with CID=1
connect by prior CID=PID
order by LEVELS
所查询的到的结果自然是浙江省下的两个市,如果我想继续查例如宁波市下面的区或者街道也是同理,只要更改父节点和等级的值就可以实现。
在xml中就只需要再稍稍改动一点就可以了
<!-- 根据id和level查询区域 -->
<select id="queryAreaByLevel1" resultType="Area">
select * from COMMUNITYS where levels=#{levels} start with CID=#{cid}
connect by prior CID=PID
order by LEVELS
</select>
第二步 将这些写入service层中,serviceImpl层以及Controller层中
为了偷懒我就只贴出我controller层中的代码hhhhh,其中用的是restful风格的请求。在这里也顺便给大家推荐一个特别好用的测试请求工具 postman,具体使用方法可以问度娘。
//根据id和level来查询区域 用于联动
@RequestMapping("/queryAreasByLevelsAndID/{id}/{levels}")
@ResponseBody
public List<Area> queryAreasByLevelsandId(@PathVariable("id") int id,@PathVariable("levels") int levels){
List<Area> list=areaService.queryAreaByLevel1(id,levels);
return list;
}
第三步 前端展示
前端中我用的是miniui的框架,在控件中专门有一个url属性,用来接收后端发送过来的请求,也同样可以在script方法里拿到控件之后用seturl的方法给它传值。因为做的功能中就只要先找到市,所以直接就在combo1里直接传入具体的id值
<tr>
<td>市:</td>
<td>
<input id="combo1" name="uid" class="mini-combobox" style="width:150px;" textField="areaName" valueField="cid" emptyText="请选择..."
url="/queryAreasByLevelsAndID/1/2" required="true" allowInput="true" showNullItem="true" nullItemText="请选择..."
onvaluechanged="onDeptChanged"/>
</td>
</tr>
<tr>
<td>区:</td>
<td>
<input id="combo2" name="roleId" class="mini-combobox" style="width:150px;" textField="areaName" valueField="cid" emptyText="请选择..."
value="cn" required="true" allowInput="true" showNullItem="true" nullItemText="请选择..."
onvaluechanged="onDeptChanged1"/>
</td>
</tr>
<tr>
<td>街道:</td>
<td>
<input id="combo3" name="cid" class="mini-combobox" style="width:150px;" textField="areaName" valueField="cid" emptyText="请选择..."
value="cn" required="true" allowInput="true" showNullItem="true" nullItemText="请选择..."/>
</td>
</tr>
下面是js中的方法,先使用mini.get拿到我们所需要的控件,在根据上一层的父节点的值拿下来用就实现层级联动,当然我觉得这样的写法一点也不美观,但好歹实现了效果。因为本人也还只是一个初学者,所以可能会有一些出错的地方或者需要改进的地方,这也是我自己第一次写博客,希望大家可以多多提出批评与建议,好让我吸取进步。希望可以每天都多学一点,可以慢慢进步。
var combo1 = mini.get("combo1");
var combo2 = mini.get("combo2");
var combo3 = mini.get("combo3");
function onDeptChanged(e) {
var id = combo1.getValue();
alert(id);
combo2.setValue("");
var url = "/queryAreasByLevelsAndID/" + id +"/3";
combo2.setUrl(url);
positionCombo.select(0);
}
function onDeptChanged1(e) {
var id = combo2.getValue();
alert(id);
combo3.setValue("");
var url = "/queryAreasByLevelsAndID/" + id +"/4";
combo3.setUrl(url);
positionCombo.select(0);
}
然后实现的效果大概也就是这样