树形菜单在很多系统中都存在,然后在查询的时候确实很费事,如果使用后台代码逻辑去查询,会设计到递归等操作,频繁发起数据库连接,增加数据库压力。经过我多番研究发现mybatis可以实现树形菜单查询(包括多级树);树形菜单如下:
该图仅只有三级菜单,但是提供的方法可以做到多级菜单适用
一、创建数据库表(略):
具体表中要有 id和父id字段
二、创建实体类:
/**
* 树形菜单类
* @author 王 维
* create time:2019年7月1日
*/
public class catagoy implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id ;
/**
* @TODO 这里省略树形中的其他属性,仅给出关键属性
*/
private Integer parentId;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
}
三、创建和菜单父类一样的子类,但是多一个子菜单属性,并继承父菜单:
/**
* 子菜单 -继承父类菜单实体类
* @author 王 维
* create time:2019年7月1日
*/
import java.util.List;
public class catagoyChild extends catagoy implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 子菜单 集合
*/
private List<catagoy> childCatatoyList;
public List<catagoy> getChildCatatoyList() {
return childCatatoyList;
}
public void setChildCatatoyList(List<catagoy> childCatatoyList) {
this.childCatatoyList = childCatatoyList;
}
}
四、编写mybatis mapper(仅给出关键代码):
4.1:给出返回map:
<!-- 结果Map -->
<resultMap id="BaseResultMap" type="com.**.catagoyChild"><!-- 这里使用含子菜单的Bean-->
<result property="id" jdbcType="INTEGER" column="f_id"/>
<result property="parentId" jdbcType="INTEGER" column="f_parent__id"/>
<!--这里使用mybatis collection 进行集合查询 这是关键点-->
<collection property="childCatatoyList" javaType="java.util.ArrayList" ofType="com.**.catagoyChild"
select="getChildLists" column="f_id">
</collection>
</resultMap>
4.2:编写父查询-取出所有一级菜单(顶级);也是整个查询的入口和返回处,service调用此接口:
<select id="getAllCategory" resultMap="BaseResultMap">
select * from t_pro_category where f_level=1 <!-- 这里level 表示属于第几级 -->
</select>
4.3:编写关联集合查询-参数为父级菜单 id:
<select id="getChildLists" parameterType="String" resultMap="BaseResultMap">
select * from t_pro_category where f_parent__id=#{id} <!--父id=传过的id -->
</select>
五、调用接口,返回所有分类。
注意:该方法可能在超大数据第一次加载数据时有点慢,可以配合缓存Ehcache,在第一次查询时将数据加入缓存,这样后面的查询将会直接从缓存中读取。该方法纯属个人研究,如果不合理之处,请提意见。