MyBatis无限级分类实现的两种方法--自关联与map集合
1、这回先创建数据库吧
下表cid是CategoryId的缩写,cname是CategoryName的缩写,pid是parentId的缩写
无限级分类一般都包含这三个属性,至少也要包含cid和pid才能建立无限级关联
ok,这个东东就是无限级分类了。
即便是外行人稍微看一眼也能发现cid为1的图书在小说和周刊两行中作为了pid,也就是说小说和周刊的父级分类就是图书
图书和饮料的pid是0,代表他们是顶级分类
如果没有其他约束条件,这张表几乎可以无限向下级延伸,是一个树形结构,这里就不写什么数学公式了,道理很简单。想必大家都懂了。
2、写个实体类
首先还是生产实体类,植入一个他本身的List集合:
package cn.sohappy.acourses.bean; import java.util.ArrayList;
import java.util.List; public class Category {
private Long cid;
private String cname;
private Long pid;
private List<Category> children; //省略getter and setter
}
然后初始化children并重写toString方法方便测试,完整代码如下:
package cn.sohappy.acourses.bean; import java.util.ArrayList;
import java.util.List; public class Category {
private Long cid;
private String cname;
private Long pid;
private List<Category> children=new ArrayList<Category>();//这里为了防止后面空指针,初始化了children实例 public List<Category> getChildren() {
return children;
} public void setChildren(List<Category> children) {
this.children = children;
} public Long getCid() {
return cid;
} public void setCid(Long cid) {
this.cid = cid;
} public String getCname() {
return cname;
} public void setCname(String cname) {
this.cname = cname;
} public Long getPid() {
return pid;
} public void setPid(Long pid) {
this.pid = pid;
} @Override
public String toString() {
return "Category{cid:"+cid+
",cname:"+cname+
",pid:"+pid+
",children:"+children+
"}";
}
}
3、写接口:
List<Category> findCategoriesByParentId(Long pid);自关联查询
List<Category> findAllCategories();一条sql查询所有,后期用Map算法分级
package cn.sohappy.acourses.course0921; import cn.sohappy.acourses.bean.Category; import java.util.List; public interface ICategoryDAO {
List<Category> findCategoriesByParentId(Long pid);
List<Category> findAllCategories();
}
4、小配置:
<?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="cn.sohappy.acourses.course0921.ICategoryDAO">
<!--.自关联查询-->
<resultMap id="selectCategoriesByPid" type="cn.sohappy.acourses.bean.Category">
<id property="cid" column="cid"/>
<result property="cname" column="cname"/>
<result property="pid" column="pid"/>
<collection property="children" ofType="cn.sohappy.acourses.bean.Category" select="findCategoriesByParentId" column="cid"/>
</resultMap>
<select id="findCategoriesByParentId" resultMap="selectCategoriesByPid">
select * from category where pid=#{}
</select>
<!--.单次查询-->
<resultMap id="MenuOneSQL" type="cn.sohappy.acourses.bean.Category" autoMapping="false">
<id property="cid" column="cid"/>
<result property="cname" column="cname"/>
<result property="pid" column="pid"/>
</resultMap>
<select id="findAllCategories" resultMap="MenuOneSQL">
select * from category
</select>
</mapper>
5.测试类:
package cn.test; import cn.sohappy.acourses.bean.BillManyToOne;
import cn.sohappy.acourses.bean.Category;
import cn.sohappy.acourses.bean.UserOneToMany;
import cn.sohappy.acourses.course0921.ICategoryDAO;
import cn.sohappy.acourses.course0921.IUserDAO;
import cn.sohappy.acourses.course0921.InfiniteMenuUtil;
import cn.sohappy.bean.Smbms_user;
import cn.sohappy.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test; import java.util.List; public class test20170921 {
@Test
//自关联实现无穷分类
public void selfCorrelation(){
SqlSession session = MyBatisUtil.getSession();
ICategoryDAO mapper = session.getMapper(ICategoryDAO.class);
List<Category> categories = mapper.findCategoriesByParentId(0L);
for (Category item :categories) {
System.out.println(item);
}
session.close();
}
@Test
//Map集合实现无穷分类
public void InfiniteMenu(){
SqlSession session = MyBatisUtil.getSession();
ICategoryDAO mapper = session.getMapper(ICategoryDAO.class);
List<Category> categoriesClassified = new InfiniteMenuUtil().loadMenu(mapper.findAllCategories());
for (Category item :categoriesClassified) {
System.out.println(item);
}
session.close();
}
}
6、InfiniteMenu的Map算法
package cn.sohappy.acourses.course0921; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*; public class InfiniteMenuUtil {
@SuppressWarnings("unchecked")
public <T> List<T> loadMenu(List<T> menus) {
List<T> rootMenus = new ArrayList<T>();
if (menus != null && menus.size() != ) {
List<Method> methodsList = Arrays.asList(menus.get().getClass().getDeclaredMethods());
//这里可以自己定制啦,我定制的是以pid,id,children结尾的get方法为分别getPid,getId,getChildren.所以menu类(Category)的属性名要符合定制规范
Method getId = null;
Method getPid = null;
Method getChildren = null;
//get getMethod
for (Method item : methodsList) {
if ("get".equals(item.getName().toLowerCase().substring(,))&&item.getName().length()>=&&"pid".equals(item.getName().toLowerCase().substring(item.getName().length() - , item.getName().length()))){
getPid = item;
continue;
}
if ("get".equals(item.getName().toLowerCase().substring(,))&&item.getName().length()>=&&"id".equals(item.getName().toLowerCase().substring(item.getName().length() - , item.getName().length()))){
getId = item;
continue;
}
if ("get".equals(item.getName().toLowerCase().substring(,))&&item.getName().length()>=&&"children".equals(item.getName().toLowerCase().substring(item.getName().length() - , item.getName().length()))){
getChildren = item;
}
}
if (getId!=null&&getPid!=null&&getChildren!=null){
//get menuMap
Map<Long, T> menuMap = new HashMap<Long, T>();
for (T menu : menus) {
Long id = null;
try {
id = (Long)getId.invoke(menu);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
menuMap.put(id,menu);
}
//add children
for (T menu:menus) {
Long pid = null;
try {
pid = (Long)getPid.invoke(menu);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
if (pid==null||pid==){
rootMenus.add(menu);
}else {
T t = menuMap.get(pid);
List<T> ts;
try {
ts = (List<T>) getChildren.invoke(t);
ts.add(menu);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
return rootMenus;
}
}
MyBatis无限级分类实现的两种方法--自关联与map集合的更多相关文章
- 【mybatis基础】mybatis开发dao两种方法
mybatis是一个支持普通SQL查询,存储过程和高级映射的优秀的持久层的框架,是apache下的顶级项目.mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.mybat ...
- mybatis 根据id批量删除的两种方法
原文:https://blog.csdn.net/qq_40010745/article/details/81032218 mybatis 根据id批量删除的两种方法 第一种,直接传递给mappe ...
- 使用PHP发送邮件的两种方法
使用PHP发送邮件的两种方法 May242013 作者:Jerry Bendy 发布:2013-05-24 22:25 分类:PHP 阅读:2,107 views 抢沙发 今天 ...
- C++调用DLL有两种方法——静态调用和动态调用
C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报 分类: cpp(30) [ ...
- Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)
一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...
- 原生Js 两种方法实现页面关键字高亮显示
原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...
- 取xml文件转成List<T>对象的两种方法
读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最 ...
- oracle rename数据文件的两种方法
oracle rename数据文件的两种方法 2012-12-11 20:44 10925人阅读 评论(0) 收藏 举报 分类: oracle(98) 版权声明:本文为博主原创文章,未经博主允许不 ...
- MyBatis开发Dao层的两种方式(原始Dao层开发)
本文将介绍使用框架mybatis开发原始Dao层来对一个对数据库进行增删改查的案例. Mapper动态代理开发Dao层请阅读我的下一篇博客:MyBatis开发Dao层的两种方式(Mapper动态代理方 ...
随机推荐
- 随机森林与 GBDT
随机森林(random forest),GBDT(Gradient Boosting Decision Tree),前者中的森林,与后者中的 Boosting 都在说明,两种模型其实都是一种集成学习( ...
- AVL 树的插入、删除、旋转归纳
参考链接: http://blog.csdn.net/gabriel1026/article/details/6311339 1126号注:先前有一个概念搞混了: 节点的深度 Depth 是指从根 ...
- ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程
原文:ASP.NET Core Razor 布局视图 - ASP.NET Core 基础教程 - 简单教程,简单编程 ASP.NET Core Razor 布局视图 上一章节中我们学习了如何使用 EF ...
- javascript-DOM学习
javascript-DOM学习 DOM document(html) object modle document对象(DOM核心对象) dom能用来干什么? 对html元素的样式(颜色.大小.位置等 ...
- ADT eclipse的几个快捷键
智能内容感知 Alt+/ ,该快捷键可以方便的匹配我们使用的类信息,/ 在键盘上和?是同一个按键. ctrl+.及ctrl+1:下一个错误及快速修改 ctrl+.将光标移动至当前文件中的下一个报错处或 ...
- 数据库访问工具 DBUtl(公孙二狗)
数据库访问工具 DBUtil DBUtil 用于简化数据库的访问,只要准备好配置文件,调用 DBUtil 的静态函数就能直接得到查询数据库的结果. 本文主要内容有: 数据库访问的思考 DBUtil 实 ...
- 图像滤镜艺术---Photoshop实现Instagram之Sierra滤镜
原文:图像滤镜艺术---Photoshop实现Instagram之Sierra滤镜 本文介绍PS实现Instagram中的Sierra滤镜,内容如下: 先看下效果图: 下面是具体实现步骤: 1. To ...
- 微信小程序把玩(五)页面生命周期
原文:微信小程序把玩(五)页面生命周期 这里只要熟悉页面的基本生命周期即可,业务在指定生命周期函数内书写. 以下是官网给出的生命周期函数方法和状态图 上面的生周期函数图对于做Android 或者IOS ...
- Android疑难杂症之Theme
背景:最近在把自己之前写的一个应用换成Material Design风格,在看官方Guide后动手试了一试,没想到出门就遇到了坑,在换成Material Design风格的主题后,我设置了一下colo ...
- [机器学习]Bagging and Boosting
Bagging 和 Boosting 都是一种将几个弱分类器(可以理解为分类或者回归能力不好的分类器)按照一定规则组合在一起从而变成一个强分类器.但二者的组合方式有所区别. 一.Bagging Bag ...