也是很久没有和大家见面,算是小结一篇(Working…)
总的来说,确实是开始慢慢的减缓更新速度了…(很多都在草稿箱中…堆积数量也正在慢慢清理)
啥都很奇怪,但是又都不奇怪。工作就是这样,有时候需要处理的很多,要学习也很多。前提:数据啥的不能从数据库中删除…数据只能是越来越多,所有就有了下面的种种需求
需求:
第一次进来加载只加载第一级的数据,不是一次返回数据
当个点击的时候查询下一级,交给前端进行拼接
模糊查询,只出现有关系的树
图片使用的是ElementUI里面的树菜单图片,大概都差不多其实
框架就是SpringMVC:Spring:Mybitas做的一颗神奇的树…
下面的内容采用文字加代码来书写…做到一次到胃(啊Sir,开车?)
快上车。来不及解释了
说到Mybitas第一步必须是xm文件(内容太长,有的没用的方法就直接去掉吧…看我的,不会少的)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.excegroup.dao.SysDataLabelDao" >
<resultMap id="BaseResultMap" type="com.excegroup.bean.DataLabelBean" >
<id column="ID" property="id" jdbcType="VARCHAR" />
<result column="Pid" property="Pid" jdbcType="VARCHAR" />
<result column="Name" property="Name" jdbcType="VARCHAR" />
<result column="Level" property="Level" jdbcType="INTEGER" />
</resultMap>
<sql id="Base_Column_List" >
ID, label_Pid, label_Code, label_Name, label_Type,label_Level, status, time_Stamp, create_By,
create_Time, modify_By, modify_Time,attr_Subject_Id,attr_Org_Id,attr_Region_Id
</sql>
<!-- 根据对象的父ID去查询当前数据(一般用来做查询父ID的全部数据) -->
<select id="getDataLableByLabelPid" resultMap="BaseResultMap" >
select
<include refid="Base_Column_List" />
from sys_data_label a where a.status='1'
and a.label_Pid=#{labelPid,jdbcType=VARCHAR}
</select>
<!-- 根据对象的父ID去查询当前数据(一般用来做查询父ID的全部数据) -->
<select id="selectLablePidById" resultMap="BaseResultMap" parameterType="java.lang.String">
select
<include refid="Base_Column_List" />
from sys_data_label a where a.label_Pid= #{id,jdbcType=VARCHAR} and a.status='1'
</select>
<!-- 查询出模糊查询条件返回的数据(可能有多个,毕竟是模糊查询) -->
<select id="selectLableByName" resultMap="BaseResultMap" parameterType="com.excegroup.bean.DataLabelBean">
select
<include refid="Base_Column_List" />
from sys_data_label a where a.status='1' and a.label_Level=2
<if test="labelName != null and labelName != ''">
and a.label_Name LIKE CONCAT(#{labelName,jdbcType=VARCHAR},'%')
</if>
</select>
<!-- 查询出当前对象的第二级菜单有哪些, 以及第三级菜单有哪些 -->
<select id="selectParentList" resultMap="BaseResultMap" parameterType="java.lang.String">
select
ID, label_Pid, label_Code, label_Name,label_Level
from sys_data_label where id in (${sql}) and status='1'
union all
select distinct
ID, label_Pid, label_Code, label_Name,label_Level
from sys_data_label where status='1' and
id in(select label_Pid from sys_data_label where id in (${sql}) and status='1')
</select>
</mapper>
package com.excegroup.bean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class DataLabelBean{
//有用的就给个注释写一下,其他无需关注
//有的没有用的数据会再下面使用到,有注释,不管就可以了,这边懒得删除了
private String id;//当前id
private String labelPid;//父ID(重点,分为三级,第一级父ID为-1,第二级的父ID为上一级的ID,第三级同理)
private String labelName;//标签名称
private int labelLevel;//第一级的level为0;第二级的level为1,第三级的level为2
private List<DataLabelBean> children = new ArrayList<>();//一个LIst集合用来做树结构用
//提供set和get不说。浪费地方(自己加一下)
}
package com.excegroup.dao;
import java.util.List;
import com.excegroup.bean.DataLabelBean;
public interface SysDataLabelDao {//没有用的也丢掉,让神仙你少看一点代码
List<DataLabelBean> getDataLableByLabelPid(DataLabelBean recode);
List<DataLabelBean> selectLablePidById(String id);
List<DataLabelBean> selectLableByName(DataLabelBean recode);
List<DataLabelBean> selectParentList(String sql);
}
package com.excegroup.service;
import java.util.List;
import com.excegroup.base.bean.ResultMsg;
import com.excegroup.bean.DataLabelBean;
//ResultMsg,一个工具包,用来做返回结果的处理,有没有无所谓,你们没有的就按照Dao层写也是一样的
public interface SysDataLableService {
/**
* 删除标签
* @param id
* @return
*/
ResultMsg updateStatus(String id);
/**
* 新增标签
* @param id
* @return
*/
ResultMsg insert(DataLabelBean record);
/**
* 查询标签
* @param id
* @return
*/
ResultMsg selectByPrimaryKey(String id);
/**
* 修改标签
* @param id
* @return
*/
ResultMsg updateByPrimaryKeySelective(DataLabelBean record);
/**
* 修改标签
* @param id
* @return
*/
ResultMsg updateByPrimaryKey(DataLabelBean record);
/**
* 加载标签菜单
*/
ResultMsg labelTree(DataLabelBean recode);
/**
* 根据id查询lablePid
* @param id
* @return
*/
List<DataLabelBean> selectLablePidById(String id);
}
package com.excegroup.service.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.excegroup.base.bean.ResultMsg;
import com.excegroup.bean.DataLabelBean;
import com.excegroup.constant.SequenceConstant;
import com.excegroup.core.DbcContext;
import com.excegroup.core.Utils;
import com.excegroup.dao.SysDataLabelDao;
import com.excegroup.service.SysDataLableService;
import com.excegroup.service.SysSequenceService;
@Service
public class SysDataLableServiceImpl implements SysDataLableService {
//重点就是下面的这一个方法,同时做到了查询,点击,模糊查询三个功能
@Autowired
SysDataLabelDao SysDataLabelDao;
@Override
public ResultMsg labelTree(DataLabelBean recode) {
ResultMsg msg = new ResultMsg();
//没有就不写,然后返回的结果就直接在return中带回去就可以了
if (StringUtils.isEmpty(recode.getLabelPid())) {
//由于是一个接口,在第一次进来的时候(及加载页面),第一次肯定是没有父ID,所以手动设置查询父ID为-1的
recode.setLabelPid("-1");
//设置pid为-1就是进来默认查询第一级的数据
}
if (!StringUtils.isEmpty(recode.getId())) {
//判断是否有Id,这里和前端做的同步(前端点击第一级的时候需要展开第一级对应的第二次数据,则传递id过来)
recode.setLabelPid(recode.getId());
//设置id为当前点击的id
}
if (StringUtils.isEmpty(recode.getLabelName())) {
//判断是否使用了模糊查询功能,没有传递labelName代表没有进行模糊查询
//可能是点击下一个,或者是第一次进来查询
List<DataLabelBean> dataList = SysDataLabelDao.getDataLableByLabelPid(recode);
//根据pid查询全部数据,分为两个情况,点击和不点击,不点击的情况就不说了,加载一级菜单。
//点击的情况就是要求前端传递一个id给我,在上面就这设置了id当做Pid去查询儿子信息
//这个for循环没有什么用,使用来个前端传递两个参数的,可以不看
for (DataLabelBean sysDataLabel : dataList) {
sysDataLabel.setLoading(false);
sysDataLabel.setExpand(false);
}
if (dataList != null) {
//这里就是用的上面说的工具包,没有的可以直接返回数据就完事了
msg.setCode("000");
msg.setDescribe("查询成功1");
msg.setData(dataList);
}
} else {
//这边就是说明传递了labelName,进行模糊查询,重点来了
//需求:哪些有这个模糊查询的数据都需要显示出来。及两个二级都有第三级的模糊查询条件的时候,两个二级都要有
List<DataLabelBean> threeList = SysDataLabelDao.selectLableByName(recode);
//进行模糊查询。返回出来的数据可能有很多条,可能来自不同的第二级菜单。
//说实话,懵逼了,数据库查询出来的数据是没有顺序的,有可能后面for循环加载的时候重复了,怎么搞?
//这里就是本篇博客的重点内容了
if (null == threeList || threeList.isEmpty()) {
return msg;
}
//上面的if做判断,没有符合条件的直接返回,你们可以直接返回null;
StringBuffer sql = new StringBuffer();
// sql用来存放所有的父节点PId,用于sql语句查询
for (DataLabelBean label : threeList) {
sql.append("'" + label.getLabelPid() + "',");
//对所有的父节点进行拼接,但是最后还是会携带一个, 这样会导致sql语句查询的时候报错
}
sql.append("'-1'");
//用于最后拼接一个-1,不会导致sql出错。大概意思就是sql="'1','2','3','-1'" 这么个感觉
List<DataLabelBean> parList = SysDataLabelDao.selectParentList(sql.toString());
//查询出来的结果就是满足与输入的模糊查询的全部结果
List<DataLabelBean> oneList = new ArrayList<DataLabelBean>();
//新建一个List集合,用来做拼接存放第一级的数据
for (DataLabelBean one : parList) {
one.setLoading(false);
one.setExpand(false);
//上面两个不用管,给前端用的,和树没有关系
if (0 == one.getLabelLevel()) {
//进行循环拼接:满足这个条件意思就是第一级的数据,进行拼接加到oneList
oneList.add(one);
}
}
//这里for循环出来就已经是拼接完了全部有的第一级
for (DataLabelBean one : oneList) {
//还是去循环我们查询出来的全部结果
List<DataLabelBean> twoList = new ArrayList<DataLabelBean>();
//新建一个List集合,用来做拼接存放第二级的数据
for (DataLabelBean two : parList) {
two.setLoading(false);
two.setExpand(false);
//上面两个不用管,给前端用的,和树没有关系
if (one.getId().equals(two.getLabelPid())) {
//这里是满足第一级的id为第二级的pid,这里代表意思就是 two是属于one 下面的一个子节点
twoList.add(two);
//满足的时候新增子节点。进行拼接
// 三級樹
List<DataLabelBean> thrList = new ArrayList<DataLabelBean>();
//新建一个List集合,用来做拼接存放第三级级的数据
for (DataLabelBean thr : threeList) {//从开始的全部数据里面去找有没有第三级
thr.setLoading(false);
thr.setExpand(false);
//上面两个不用管,给前端用的,和树没有关系
if (two.getId().equals(thr.getLabelPid())) {
//这里是满足第二级的id为第三级的pid,这里代表意思就是 thr是属于two下面的一个子节点
thrList.add(thr);
//满足的时候新增子节点。进行拼接
}
}
two.setChildren(thrList);
//给第二级拼接属于他的第三级
}
}
one.setChildren(twoList);
//给第一级拼接属于他的第二级
}
msg.setData(oneList);
//返回数据完事
}
return msg;
}
}
模拟出来的数据库,和上面的xml内容可能不一致。但是不影响理解
一些返回数据结果:手动写的…(应该没有问题)
第一次加载:
{
"code": "000",
"describe": "查询成功1",
"data": [{
"id": "1",
"Pid": "-1",
"Name": "第一级One",
"Level": 0
}, {
"id": "2",
"labelPid": "-1",
"labelName": "only老K",
"labelLevel": 0
}]
}
点击的时候:
{
"code": "000",
"describe": "查询成功1",
"data": [{
"id": "121",
"Pid": "1",
"Name": "第二级One",
"Level": 1
}, {
"id": "122",
"Pid": "1",
"Name": "第二级TWO",
"Level": 1
}, {
"id": "123",
"Pid": "1",
"Code": "L008",
"Name": "第二级Three",
"Level": 2
}]
}
模糊查询:
{
"code": "000",
"describe": "Operation succeed!",
"data": [{
"id": "1",
"Pid": "-1",
"Name": "第一级One",
"Level": 0,
"children": [{
"id": "123",
"Pid": "1",
"Name": "第二级Three",
"Level": 1,
"children": [{
"id": "132",
"Pid": "123",
"Name": "带第三级TWO",
"Level": 2
}, {
"id": "131",
"Pid": "123",
"Name": "带第三级One",
"Level": 2
}]
}]
}]
}