javaBean如下:
public class Permission implements Serializable {
private Integer id;
private String name;
private String icon;
private String url;
private boolean open;//树叶是否打开
private Integer pid;//父id
private boolean checked;//是否被选中
private List<Permission> children =new ArrayList<Permission>();//子集合
}
第一种:使用mybatis映射实现:
1.在mapper映射文件中配置:
<!--递归结果集合-->
<resultMap id="RecursionResultMap" type="com.ssm.bean.Permission">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="pid" jdbcType="INTEGER" property="pid" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="icon" jdbcType="VARCHAR" property="icon" />
<result column="url" jdbcType="VARCHAR" property="url" />
<!--一对多,递归配置-->
<collection property="children" ofType="com.ssm.bean.Permission" column="id" select="recursionChildren"/>
</resultMap>
<select id="selectRoot" resultMap="RecursionResultMap">
select id, pid, name, icon, url
from t_permission where pid is null or pid =0
</select>
<select id="recursionChildren" resultMap="RecursionResultMap">
select id, pid, name, icon, url
from t_permission where pid = #{id}
</select>
2.Service层:调用selectRoot方法
public List<Permission> selectRoot() {
return permissionMapper.selectRoot();
}
3.Controller层:
@RequestMapping("/permissionALL")
@ResponseBody
public List<Permission> all(){
List<Permission> list= permissionService.selectRoot();
return list;
}
结果得到的:
第二种:通过递归实现:
1.mapper.xml配置:
<resultMap id="BaseResultMap" type="com.ssm.bean.Permission">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="pid" jdbcType="INTEGER" property="pid" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="icon" jdbcType="VARCHAR" property="icon" />
<result column="url" jdbcType="VARCHAR" property="url" />
</resultMap>
<select id="selectChildren" resultMap="BaseResultMap">
select id, pid, name, icon, url
from t_permission where pid = #{id}
</select>
2.Service层:
public List<Permission> selectChildren(Integer id) {
return permissionMapper.selectChildren(id);
}
3.Controller层:
@RequestMapping("/initPermission1")
@ResponseBody
public Permission initPermission1(){
Permission permission=new Permission ();
try{
permission.setId(1);//这个地方应该通过数据库查询出根节点,因为根节点id在数据库是1,所以偷了一下懒
queryChildPermissions(permission);//递归得到全部节点
}catch (Exception e){
throw e;
}
return permission;
}
private void queryChildPermissions (Permission permission){
List<Permission> children= permissionService.selectChildren(permission.getId());//通过id查询子集合
permission.setChildren(children);//将查询出来的子节点集合放入到permission集合中
for(Permission innerChildren:children){ //遍历出子集合的子集合
queryChildPermissions(innerChildren); //放入到子节点的子集合中
}
}
4.调用initPermission1方法,查询结果和第一种方式是一致的,这两种方式不建议使用,因为每一次执行递归都会发sql语句,对资源占有很大。
第三种:一次查出全部记录,通过嵌套循环遍历结果
1.mapper.xml配置;
<resultMap id="BaseResultMap" type="com.ssm.bean.Permission">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="pid" jdbcType="INTEGER" property="pid" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="icon" jdbcType="VARCHAR" property="icon" />
<result column="url" jdbcType="VARCHAR" property="url" />
</resultMap>
<select id="selectAll" resultMap="BaseResultMap">
select id, pid, name, icon, url
from t_permission
</select>
2.Service层:
public List<Permission> selectAll() {
return permissionMapper.selectAll();
}
3.Controller层:
@RequestMapping("/initPermission2")
@ResponseBody
public Permission initPermission2(){
Permission permission=new Permission ();
List<Permission> lists=permissionService.selectAll();//查询所有节点
try{
for(Permission ps:lists){//遍历节点
Permission child=ps;
if(ps.getPid().equals(0)||ps.getPid()==null){//获取根节点,Integer类型是包装类,判断对象引用
permission=ps;//根节点
}else{
for (Permission innerpermission:lists){
if(child.getPid()==innerpermission.getId()){//如果节点的的pid和集合中某个节点的id一致
Permission parent=innerpermission;//将这个节点命名为父节点
parent.getChildren().add(child);//然后把child放入到它的父亲集合中
break;
}
}
}
}
}catch (Exception e){
throw e;
}
return permission;
}
查询的结果和前面两种的结果一致,一次查出所有数据,通过嵌套循环遍历得到结果,不需要频繁发送sql语句,但是如果数据多的话,循环的次数过多,会影响性能
第四种:一次查出所有数据,通过Map集合实现树结构
Service层和mapper.xml 同第三种方式
Controller层:
@RequestMapping("/initPermission")
@ResponseBody
public Permission initPermission(){
Permission permission=new Permission ();
List<Permission> lists=permissionService.selectAll();//查询所有节点
Map<Integer,Permission> map=new HashMap<Integer,Permission>();//将所有节点存入到map集合
try{
for(Permission ps:lists) {
map.put(ps.getId(),ps);//将所有id做为key,Permission对象做值,存入到map集合
}
for(Permission ps:lists){//遍历所有节点
Permission child=ps;
if (child.getPid().equals(0)||child.getPid()==null){
permission=ps;//取出根节点
}else{
Permission parent=map.get(child.getPid());//通过子节点的pid获取父节点
parent.getChildren().add(child);//将子节点放入父节点中
}
}
}catch (Exception e){
throw e;
}
return permission;
}