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集合的更多相关文章

  1. 【mybatis基础】mybatis开发dao两种方法

    mybatis是一个支持普通SQL查询,存储过程和高级映射的优秀的持久层的框架,是apache下的顶级项目.mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.mybat ...

  2. mybatis 根据id批量删除的两种方法

    原文:https://blog.csdn.net/qq_40010745/article/details/81032218 mybatis 根据id批量删除的两种方法   第一种,直接传递给mappe ...

  3. 使用PHP发送邮件的两种方法

    使用PHP发送邮件的两种方法 May242013 作者:Jerry Bendy   发布:2013-05-24 22:25   分类:PHP   阅读:2,107 views   抢沙发     今天 ...

  4. C++调用DLL有两种方法——静态调用和动态调用

    C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报  分类: cpp(30)  [ ...

  5. Delphi Windows API判断文件共享锁定状态(OpenFile和CreateFile两种方法)

    一.概述 锁是操作系统为实现数据共享而提供的一种安全机制,它使得不同的应用程序,不同的计算机之间可以安全有效地共享和交换数据.要保证安全有效地操作共享数据,必须在相应的操作前判断锁的类型,然后才能确定 ...

  6. 原生Js 两种方法实现页面关键字高亮显示

    原生Js 两种方法实现页面关键字高亮显示 上网看了看别人写的,不是兼容问题就是代码繁琐,自己琢磨了一下用两种方法都可以实现,各有利弊. 方法一 依靠正则表达式修改 1.获取obj的html2.统一替换 ...

  7. 取xml文件转成List<T>对象的两种方法

    读取xml文件转成List<T>对象的两种方法(附源码)   读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最 ...

  8. oracle rename数据文件的两种方法

    oracle rename数据文件的两种方法 2012-12-11 20:44 10925人阅读 评论(0) 收藏 举报  分类: oracle(98)  版权声明:本文为博主原创文章,未经博主允许不 ...

  9. MyBatis开发Dao层的两种方式(原始Dao层开发)

    本文将介绍使用框架mybatis开发原始Dao层来对一个对数据库进行增删改查的案例. Mapper动态代理开发Dao层请阅读我的下一篇博客:MyBatis开发Dao层的两种方式(Mapper动态代理方 ...

随机推荐

  1. Python类型和对象

    关键字:Python 类型 对象原文:http://wiki.woodpecker.org.cn/moin/PyTypesAndObjects 关于本书 解释新式的Python对象(new-style ...

  2. 一张图弄明白开源协议-GPL、BSD、MIT、Mozilla、Apache和LGPL 之间的区别

    导读 在开源软件中经常看到各种协议说明,GPL.BSD.MIT.Mozilla.Apache和LGPL. - 这些协议之间的有什么区别 - 如何选择合适的开源协议 请看下文,特作记录一篇,以供后续查看 ...

  3. Font Awesome Text 使用方法

    <!-- basic text--> <com.beardedhen.androidbootstrap.FontAwesomeText android:layout_width=&q ...

  4. PostgreSQL9.3:JSON 功能增强 根据PQ中文论坛francs 给出的东西结合自己的摸索总结下

     在 PostgreSQL 9.2 版本中已经支持 JSON 类型,不过支持的操作非常有限,仅支持以下函数   array_to_json(anyarray [, pretty_bool]) row_ ...

  5. 【转载】MySQL Replication 环境安装与配置

    安装[root@msr01 ~]# yum install mysql-serverInstalled:mysql-server.x86_64 0:5.1.73-3.el6_5 Dependency ...

  6. css3 位置选择器 类似jq的:eq(0)

    JQ使用 :eq(位置),可以选择第几个元素 CSS3里面新增了一个用法,:nth-child(位置) 可实现和JQ同样的功能 需要注意的是jq第一个是从0开始,CSS的第一个是从1开始

  7. 数据在数组中存储的顺序:小端 OR 大端模式 详解

    大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放: 小端模式,是指数据的高 ...

  8. 自定义View相关的博客收藏

    颜色: http://android.jobbole.com/83283/ 坐标: http://android.jobbole.com/83276/ 流程介绍: http://android.job ...

  9. 安装 VirtualBox 出现回滚,无法安装及解决方法

    原文:安装 VirtualBox 出现回滚,无法安装及解决方法 缘由:打算安装 Vagrant,因此打算安装 VirtualBox. 现象:安装 VirtualBox,进度快到最后的时候,安装程序执行 ...

  10. ASP.NET获取客户端、服务器端基础信息

    1. 在ASP.NET中专用属性: 获取服务器电脑名:Page.Server.ManchineName 获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostN ...