java递归查询分类及分类下所有子分类

该案例是实际开发中运用,java递归查询分类及分类下所有子分类。

代码走起:

1.jsp页面布局样式这里不再介绍,js业务逻辑展示分类树形结构如下:

/**
 * 商品分类操作
 */

/**
 * 初始化
 */
$(function(){
	//加载树
	reloadTree();
	
	
    });
	
});

/**
 * 加载树
 */
function reloadTree(){
	//加载列表树
	initGoodsCateTree(1);
	//加载添加分类弹框树
	initGoodsCateTree(2);
	//加载编辑分类弹框树
	initGoodsCateTree(3);
}

  
/**
 * 初始化商品分类树
 * type:1列表树2弹框树
 */
function initGoodsCateTree(type){
	$.ajax({
		type:"post",  
		url: "queryAllCate.htm",
		async:false, //同步
		cache:false, //清除缓存
		dataType:"json",
		success: function(data){
			if(type==1){
				//加载列表树
				$("#cat_tree").html("");
			}else if(type==2){
				//加载添加分类弹框树
				$("#parentCate_add .tree").html("");
			}else if(type==3){
				//加载编辑分类弹框树
				$("#parentCate_edit .tree").html("");
			}
			loadGoodsCateTree(data,0,type);
			//加载分类树样式
			initGoodsCateTreeCss();
		}
   });
}

/**
 * 递归树
 * datas:商品分类数据
 * parendId:父节点默认为0
 * type:1列表树2弹框树
 */
function loadGoodsCateTree (datas,parentId,type){
	if(datas!=null){
		if(parentId==0){
			for(var i=0;i<datas.length;i++){
				var data=datas[i];
				if(type==1){
					//拼接列表树
					$("#cat_tree").append(goodsCateHtml(data));
				}else if(type==2){
					//拼接添加分类弹框树
					$("#parentCate_add .tree").append(selectGoodsCateHtml(data,"cateAdd"));
				}else if(type==3){
					//拼接编辑分类弹框树
					$("#parentCate_edit .tree").append(selectGoodsCateHtml(data,"cateEdit"));
				}
				//递归所有子节点
				for(var j=0;j<data.cateVos.length;j++){
					var dataCate=data.cateVos[j];
					loadGoodsCateTree(dataCate,dataCate.catId,type);
				}
			}
		}else{//非父节点
			var data=datas;
			if(type==1){
				//拼接列表树
				$("#cat_tree").append(goodsCateHtml(data));
			}else if(type==2){
				//拼接添加分类弹框树
				$("#parentCate_add .tree").append(selectGoodsCateHtml(data,"cateAdd"));
			}else if(type==3){
				//拼接编辑分类弹框树
				$("#parentCate_edit .tree").append(selectGoodsCateHtml(data,"cateEdit"));
			}
			//递归所有子节点
			for(var j=0;j<data.cateVos.length;j++){
				var dataCate=data.cateVos[j];
				loadGoodsCateTree(dataCate,dataCate.catId,type);
			}
		}
	}
}

/**
 * 拼接商品分类列表树
 * data:商品分类数据
 */
var goodsCateHtml=function (data) {
	var html="";
	//默认只展示父节点
	if(data.catGrade==1){
		html= '<div depath="'+data.catGrade+'" class="clear_cat row"  cid="'+data.catId+'"  pid="'+data.catParentId+'" >'
	}else{
		html= '<div depath="'+data.catGrade+'" class="clear_cat row"  style="display:none;" cid="'+data.catId+'"  pid="'+data.catParentId+'" >'
	}
	html= html+
	'<table>'+
		'<tbody>'+
			'<tr>'+
				'<td class="td1">'+
					'<div >'+
						'<span class="handle-icon">'+
							'<img src="images/cticon2.png" alt="收起子分类" title="收起子分类" class="handle-hide" app="desktop" style="display: none;">'+
							'<img src="images/cticon1.png" alt="展开子分类" title="展开子分类" class="handle-show" app="desktop">'+
						'</span>'+
						 '<a >'+data.catName+'</a>'+
					'</div>'+
				'</td>'+
				'<td class="td2"><span class="quiet">['+data.typeName+']</span></td>'+
				'<td class="td3"><b>'+data.catSort+'</b></td>'+
				'<td class="td4">'+
					'<a href="javascript:void(0);" class="addSubNote" οnclick="addSubCate('+data.catId+','+data.catGrade+',\''+data.catName+'\')">增加子类</a>'+ 
					'<a href="javascript:void(0);" οnclick="editGoodsCate('+data.catId+')">编辑</a>'+ 
					'<a href="javascript:void(0);" οnclick="deleteGoodsCate('+data.catId+')">删除</a>'+
				'</td>'+
				'<td class="td5">'+
	              '<input type="hidden" value="'+data.catIsFinal+'"/>'+
	            '</td>'+
			'</tr>'+
		'</tbody>'+
	'</table>'+
  '</div>';
	return html;
}

/**
 * 加载商品分类树样式
 */
function initGoodsCateTreeCss(){
	$(".clear_cat").each(function(){
		//判断是否是末级
		var isM = $(this).find(".td5 input").val();
		if(isM == 1){
			//末级节点不展示图标
			$(this).find(".handle-icon").remove();
			//不显示添加子类
			$(this).find(".addSubNote").remove();
		}else {
			//非末级节点不显示类型名称
			$(this).find(".quiet").html(" ");
		}
		//子节点添加样式
		var depath = $(this).attr("depath");
		$(this).find(" .td1>div").css("padding-left",20*depath+"px");
	});
}

/**
 * 拼接商品分类弹框树
 * data:商品分类数据
 */
var selectGoodsCateHtml=function (data,divId){
	var html="";
	//默认只展示父节点
	if(data.catGrade==1){
		html= '<div depath="'+data.catGrade+'" class="clear_cat row"  cid="'+data.catId+'"  pid="'+data.catParentId+'" >'
	}else{
		html= '<div depath="'+data.catGrade+'" class="clear_cat row"  style="display:none;" cid="'+data.catId+'"  pid="'+data.catParentId+'" >'
	}
	html= html+
	'<table>'+
		'<tbody>'+
			'<tr>'+
				'<td class="td1">'+
					'<div >'+
						'<span class="handle-icon">'+
							'<img src="images/cticon2.png" alt="收起子分类" title="收起子分类" class="handle-hide" app="desktop" style="display: none;">'+
							'<img src="images/cticon1.png" alt="展开子分类" title="展开子分类" class="handle-show" app="desktop">'+
						'</span>'+
						 '<a href="javascript:void(0);" οnclick="selectParentCate('+data.catId+','+data.catGrade+',\''+data.catName+'\',\''+divId+'\')" >'+data.catName+'</a>'+
					'</div>'+
				'</td>'+
				'<td class="td5">'+
	              '<input type="hidden" value="'+data.catIsFinal+'"/>'+
	            '</td>'+
			'</tr>'+
		'</tbody>'+
	'</table>'+
  '</div>';
	return html;
}

/**
 * 点击上级分类显示弹框树
 */
function showParentCate(){
	if($(".cateTree").css("display")=="none"){
		$(".cateTree").show();
	}else{
		$(".cateTree").hide();
	}
}

/**
 *点击上级分类显示弹框树,选择任意一个上级分类名称赋值至文件框
 * parentId:父节点id
 * parentGrade:父节点层级
 * parentName:父节点名称
 * divId:div标识判断是添加分类弹窗还是编辑分类弹窗
 */
function selectParentCate(parentId,parentGrade,parentName,divId){
	//alert("parentId:"+parentId);alert("parentGrade:"+parentGrade);alert("parentName:"+parentName);alert("divId:"+divId);
	if(divId=="cateAdd"){
		$("#catParentName_add").val(parentName);
		$("#catParentId_add").val(parentId);
		$("#catGrade_add").val(parentGrade);
	}else if(divId=="cateEdit"){
		$("#catParentName_edit").val(parentName);
		$("#catParentId_edit").val(parentId);
		$("#catGrade_edit").val(parentGrade);
	}
	//隐藏弹框树
	$(".cateTree").hide();
}

	
备注:

1.注意用了代码重构的思想,如添加分类,编辑分类都要显示谈框树,则用type来区分是添加显示还是编辑显示

2.js执行顺序是从上到下,代码顺序很重要,在实际开发中因为代码放的位置不对,导致展示数据异常,这里就明显体现了。

3.从后台递归查询了数据,前台没有用任何框架,纯js+css展示,这里用js递归方法展示,本人是第一次写,觉得非常好,留着纪念吐舌头

后台代码:

controlle层:

/**
     * 递归查询商品分类
     * @return
     */
    @RequestMapping("/queryAllCate")
    @ResponseBody
    public List<GoodsCateVo> queryGoodsCateVo(HttpServletRequest request)  {
    	//获取参数(all查询所有)
    	String queryType = request.getParameter("queryType");
    	Date date=new Date();
    	List<GoodsCateVo> list=new ArrayList<GoodsCateVo>();
    	HashMap<String, Object> paramMap=new HashMap<String, Object>();
        try {
        	//根据父节点递归查询子节点
        	if(!"all".equals(queryType)){
        		paramMap.put("catParentId", 0);
        	}
        	list=goodsCateService.findAllGoodsCate(paramMap);
        	System.out.println("查询耗时:"+(new Date().getTime()-date.getTime()));
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("递归查询商品分类失败"+e.getMessage(),e);
		}
        return list;
    }
注意这里查询是所有父分类即catParentId=0,然后根据父分类递归查询所有子分类

serverImpl业务层:

 /**
     * @descript:根据父节点递归查询子节点
    * @param:
    * @return:
     */
    @Transactional(readOnly=true)
    public List<GoodsCateVo> findAllGoodsCate(Map<String, Object> paramMap){
    	//封装返回结果
    	List<GoodsCateVo> list=new ArrayList<GoodsCateVo>();
    	try {
    		//查询所有父商品分类
    		List<GoodsCateVo> goodsParentCateList=goodsCateMapper.queryAllParentGoosCate(paramMap);
    		if(goodsParentCateList!=null && !goodsParentCateList.isEmpty()){
    			for(GoodsCateVo cateVo:goodsParentCateList){
    				// 初始化变量申明
    				GoodsCateVo vo=new GoodsCateVo();
    				vo.setCatId(cateVo.getCatId());
    				vo.setCatName(cateVo.getCatName());
    				vo.setCatParentId(cateVo.getCatParentId());
    				vo.setCatGrade(cateVo.getCatGrade());
    				vo.setCatSort(cateVo.getCatSort());
    				vo.setCatRate(cateVo.getCatRate());
    				vo.setCatIsFinal(cateVo.getCatIsFinal());
    				vo.setTypeId(cateVo.getTypeId());
    				vo.setTypeName(cateVo.getTypeName());
    				//子分类参数
    				 Map<String, Object> dataMap=new HashMap<String, Object>();
    				 dataMap.put("catParentId", cateVo.getCatId());
    				 //通过父分类递归子分类,最后一级不递归,商品分类是否是末级0否1是
    				 if("0".equals(cateVo.getCatIsFinal())){
    					 vo.setCateVos(findAllGoodsCate(dataMap));
    				 }
    				 list.add(vo);
    			}
    		}
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("查询商品分类失败"+e.getMessage(),e);
		}
    	return list;
    }
mybatis查询:
 <!-- 根据父节点递归查询子节点 -->
	 <select id="queryAllParentGoosCate" parameterType="java.util.Map"  resultMap="goodsCateVo">
		  	select 
		  		<include refid="goodsCateVo_Colimn_list" />
		  	from t_goods_category  c 
		  	left join t_goods_type   t  on c.type_id=t.type_id  and  t.type_delflag='0'
		  	where	
		  	c.cat_delflag='0'  
		 	<if test="catParentId != null" >
	       		and  c.cat_parent_id=#{catParentId}
	      	</if>
		  	
		  	order by  c.cat_sort,c.cat_id
	 </select>
实体类:
package com.qianjiang.goods.vo;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 商品分类VO
 */
public class GoodsCateVo implements Serializable{
    /**
	 * 序列化
	 */
	private static final long serialVersionUID = -1362577335137261590L;
	/*
    *分类ID
     */
    private Long catId;
    /*
    *分类名称
     */
    private String catName;
    /*
    *父级分类ID
     */
    private Long catParentId;
    /*
    *商品类型ID
     */
    private Long typeId;

    /*
    *类型排序
     */
    private Integer catSort;
    /*
    *层级
     */
    private Integer catGrade;
    /*
    *类型名称
     */
    private String typeName;

    /*
    *子级的CateVo集合,默认为空(这样定义是因为在js递归子分类出现异常故这样定义给个默认值)
     */
    private List<GoodsCateVo> cateVos=new ArrayList<GoodsCateVo>(0);
    /*
    *类目扣率
     */
    private BigDecimal catRate;
    /*
     *商品分类是否是末级0否1是
      */
    private String catIsFinal;

    public BigDecimal getCatRate() {
        return catRate;
    }

    public void setCatRate(BigDecimal catRate) {
        this.catRate = catRate;
    }

    public Long getCatId() {
        return catId;
    }

    public void setCatId(Long catId) {
        this.catId = catId;
    }

    public String getCatName() {
        return catName;
    }

    public void setCatName(String catName) {
        this.catName = catName;
    }

    public Long getCatParentId() {
        return catParentId;
    }

    public void setCatParentId(Long catParentId) {
        this.catParentId = catParentId;
    }

    public Long getTypeId() {
        return typeId;
    }

    public void setTypeId(Long typeId) {
        this.typeId = typeId;
    }

    public Integer getCatSort() {
        return catSort;
    }

    public void setCatSort(Integer catSort) {
        this.catSort = catSort;
    }

    public Integer getCatGrade() {
        return catGrade;
    }

    public void setCatGrade(Integer catGrade) {
        this.catGrade = catGrade;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

	public List<GoodsCateVo> getCateVos() {
		return cateVos;
	}

	public void setCateVos(List<GoodsCateVo> cateVos) {
		this.cateVos = cateVos;
	}

	public String getCatIsFinal() {
		return catIsFinal;
	}

	public void setCatIsFinal(String catIsFinal) {
		this.catIsFinal = catIsFinal;
	}
    
    
}

补充:

这里用到一个方法:Select下拉框onchange事件获取option的value值

jsp:

<div class="form-group">
	<label class="col-sm-5 control-label"> <span class="text-danger">*</span>是否末级:</label>
	<div class="col-sm-14">
		<select class="form-control w100 required" data-live-search="false" name="catIsFinal"  οnchange="changeSelect(this.options[this.options.selectedIndex].value,'cateRate_add');">
			<option value="">请选择</option>
			<option value="0">否</option>
			<option value="1" >是</option>
			</select>
	</div>
	<div class="col-sm-4"></div>
</div>
js方法:
/**
 * select change事件
 * 判断是否末级,若是显示分类扣率否则不显示
 * catIsFinal 0否1是
 * @param obj select选中的值
 * @param divId 分类扣率divId
 */
function changeSelect(obj,divId){
	//alert("select value:"+obj); alert("divId:"+divId);
	var catIsFinal=obj;
	if(catIsFinal=="1"){
		//添加验证
		$("#"+divId).find("select").addClass("required");
		$("#"+divId).find("input").addClass("required");
		//显示分类扣率
		$("#"+divId).show();
	}else{
		//移除验证
		$("#"+divId).find("select").removeClass("required");
		$("#"+divId).find("input").removeClass("required");
		//隐藏分类扣率
		$("#"+divId).hide();
	}
}
案例中放开alert,obj就是下拉框选中的值





  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 可以通过递归的方式来获取当前分类下的分类,具体实现如下: ```java public List<Category> getSubCategories(Category category) { List<Category> subCategories = new ArrayList<>(); for (Category subCategory : category.getSubCategories()) { subCategories.add(subCategory); subCategories.addAll(getSubCategories(subCategory)); } return subCategories; } ``` 其中,Category表示分类对象,getSubCategories()方法获取当前分类分类列表。通过循环遍历分类,将其添加到结果列表中,并递归调用getSubCategories()方法获取其分类,最终返回所有分类列表。 ### 回答2: 在Java中,可以使用递归来获取当前分类下的分类。首先,需要定义一个方法来实现递归的逻辑。 方法的输入参数为当前分类的ID,通过这个ID可以获取该分类下的所有分类。首先,需要查询数据库或其他数据源,获取当前分类的所有分类的ID列表。 然后,对于每个分类的ID,再次调用递归方法,将该分类的ID作为参数传入。递归方法会继续查询这个分类的所有分类的ID列表,并继续调用递归方法,直到所有分类的ID被获取完毕。 最后,递归方法会返回所有分类的ID列表。 以下是一个递归方法的示例代码: ``` public List<Integer> getAllSubcategories(int categoryId) { List<Integer> allSubcategories = new ArrayList<>(); // 查询当前分类下的所有分类的ID列表 List<Integer> subcategoryIds = getCategoryIdsByParentId(categoryId); // 对于每个分类的ID,递归调用获取所有分类的ID列表 for (int subcategoryId : subcategoryIds) { List<Integer> subcategories = getAllSubcategories(subcategoryId); allSubcategories.addAll(subcategories); } // 将当前分类下的所有分类的ID列表添加到结果中 allSubcategories.addAll(subcategoryIds); return allSubcategories; } private List<Integer> getCategoryIdsByParentId(int parentId) { // 查询数据库或其他数据源,根据父分类ID获取分类的ID列表 // 这里使用一个简化的示例,直接返回预定义的分类ID列表 List<Integer> subcategories = new ArrayList<>(); if (parentId == 1) { subcategories.add(2); subcategories.add(3); } else if (parentId == 2) { subcategories.add(4); subcategories.add(5); } else if (parentId == 3) { subcategories.add(6); subcategories.add(7); } return subcategories; } ``` 使用该方法,可以递归地获取给定分类下的所有分类的ID列表。 ### 回答3: 要实现Java递归获取当前分类下的分类,可以采用以下方法: 1. 首先,创建一个Category类,该类包含一个名称属性和一个分类列表(List<Category>)属性。 2. 在Category类中,定义一个方法getChildCategories(),用于递归获取当前分类下的分类。 3. 在getChildCategories()方法中,首先获取当前分类分类列表。然后,遍历该列表,对于每个分类递归调用getChildCategories()方法获取其分类,并将返回的结果添加到一个新的分类列表中。 4. 最后,返回这个新的分类列表。 下面是一个示例代码: ``` import java.util.ArrayList; import java.util.List; public class Category { private String name; private List<Category> childCategories; public Category(String name) { this.name = name; this.childCategories = new ArrayList<>(); } public void addChildCategory(Category childCategory) { this.childCategories.add(childCategory); } public List<Category> getChildCategories() { List<Category> allChildCategories = new ArrayList<>(); for (Category child : childCategories) { allChildCategories.addAll(child.getChildCategories()); } return allChildCategories; } public static void main(String[] args) { // 创建分类 Category rootCategory = new Category("Root"); Category category1 = new Category("Category 1"); Category category2 = new Category("Category 2"); Category subcategory1 = new Category("Subcategory 1"); Category subcategory2 = new Category("Subcategory 2"); // 构建分类的层次结构 rootCategory.addChildCategory(category1); rootCategory.addChildCategory(category2); category1.addChildCategory(subcategory1); category2.addChildCategory(subcategory2); // 获取当前分类下的所有分类 List<Category> allChildCategories = rootCategory.getChildCategories(); System.out.println("当前分类下的分类:"); for (Category category : allChildCategories) { System.out.println(category.name); } } } ``` 运行以上代码,将输出以下内容: ``` 当前分类下的分类: Category 1 Subcategory 1 Category 2 Subcategory 2 ``` 以上就是用Java递归获取当前分类下的分类的示例代码和解释。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值