zoukankan      html  css  js  c++  java
  • mysql+mybatis递归调用

    递归调用的应用场景常常出现在多级嵌套的情况,比如树形的菜单。下面通过一个简单的例子来实现mysql+mybatis的递归。

    数据模型

        private Integer categoryId;
    
        private String categoryName;
    
        private Integer isRoot;
    
        private Integer categoryLevel;
    
        private Integer rootCategoryId;
    
        private Integer parentCategoryId;
    
        private String parentCategoryName;

    以上是一个简单的类目的数据实体,主要要注意通过乐parentCategoryId实现了父子的关联。

    数据库数据

    我们可以很简单的通过父级的id获取其直接子级列表。但是如果我们想要通过某一父级id获取其直接下属和间接下属的(子,孙,曾孙等)列表呢?这就需要用到递归来实现。

    实现方法

    首先,我们在实体类下面加上这么一个属性。

    public List<TCategory>childList=new ArrayList<TCategory>();//子Category列表

    然后,我们编写xml文件中的ResultMap,如下。

    <!-- 带有chlidList的map -->
        <resultMap id="TreeMap" type="com.qgranite.entity.TCategory">
            <id column="category_id" property="categoryId" jdbcType="INTEGER" />
            <result column="category_name" property="categoryName"
                jdbcType="VARCHAR" />
            <result column="category_remark" property="categoryRemark"
                jdbcType="VARCHAR" />
            <result column="category_type" property="categoryType"
                jdbcType="INTEGER" />
            <result column="is_root" property="isRoot" jdbcType="INTEGER" />
            <result column="category_level" property="categoryLevel"
                jdbcType="INTEGER" />
            <result column="root_category_id" property="rootCategoryId"
                jdbcType="INTEGER" />
            <result column="parent_category_id" property="parentCategoryId"
                jdbcType="INTEGER" />
            <result column="parent_category_name" property="parentCategoryName"
                jdbcType="VARCHAR" />
            <collection property="childList" column="category_id"
                ofType="com.qgranite.entity.TCategory" select="selectRecursionByParentCategoryId"></collection>
        </resultMap>

    最后一句是关键,它说明了递归所需要调用的方法selectRecursionByParentCategoryId

    然后我们来写这个递归方法。

    <!-- 根据父键递归查询 -->
        <select id="selectRecursionByParentCategoryId" resultMap="TreeMap"
            parameterType="java.lang.Integer">
            select
            *
            from t_category
            where is_del=0
            and
            parent_category_id=#{_parameter,jdbcType=INTEGER}
        </select>

    注意这边的resultMap就是上述定义的resultMap.

    如果要递归获取所有的TCategory,我们只要获取所有category_type=1(即根类目),然后从根目录递归下去,注意这边的resultMap必须为TreeMap,才会触发递归。

    <!-- 递归查询所有 -->
        <select id="selectRecursionAll" resultMap="TreeMap">
            select
            *
            from t_category
            where is_del=0
            and
           category_type=1
        </select>

    接下来写后台调用方法。

    /**
         * 根据特定父类递归查询所有子类
         * 
         * @param categoryId
         * @return
         */
        public List<TCategory> allCategoryRecursion() {
            return baseDao
                    .findTList(
                            "TCategoryMapper.selectRecursionAll");
        }
    /**
         * 根据特定父类递归查询所有子类
         * 
         * @param categoryId
         * @return
         */
        public List<TCategory> subCategoryListByParentId(int categoryId) {
            return baseDao
                    .findTListByParam(
                            "TCategoryMapper.selectRecursionByParentCategoryId",
                            categoryId);
        }
     
    /**
         * 根据categoryId获取子孙categoryId的id字符串,用逗号隔开
         * 
         * @param categoryId
         * @return
         */
        public String subCategoryStrByParentId(Integer categoryId) {
            String categoryStr = categoryId.toString();
            List<TCategory> categoryList = baseDao
                    .findTListByParam(
                            "TCategoryMapper.selectRecursionByParentCategoryId",
                            categoryId);
            int size = categoryList.size();
            for (int i = 0; i < size; i++) {
                TCategory category = categoryList.get(i);
                categoryStr = categoryStr + "," + category.getCategoryId();
                if (!category.getChildList().isEmpty()) {
                    Iterator<TCategory> it = category.getChildList().iterator();
                    while (it.hasNext()) {
                        categoryStr = categoryStr + "," + it.next().getCategoryId();
                    }
                }
            }
            return categoryStr;
        }

    其中baseDao的代码如下。

    package com.qgranite.dao;
    
    import java.io.Serializable;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.List;
    
    import javax.annotation.Resource;
    
    import org.mybatis.spring.SqlSessionTemplate;
    import org.springframework.stereotype.Repository;
    
    /**
     * 所有dao基类
     * 
     * @author xdx
     *
     * @param <T>
     * @param <PK>
     */
    @Repository("baseDao")
    public class BaseDao<T, PK extends Serializable> {
        private Class<T> enetityClass;
        @Resource(name = "sqlSessionTemplate")
        private SqlSessionTemplate sqlSessionTemplate;
    
        // 构造方法,根据实例类自动获取实体类型,这边利用java的反射
        public BaseDao() {
            this.enetityClass = null;
            Class c = getClass();
            Type t = c.getGenericSuperclass();
            if (t instanceof ParameterizedType) {
                ParameterizedType p = (ParameterizedType) t;
                Type[] type = p.getActualTypeArguments();
                this.enetityClass = (Class<T>) type[0];
            }
        }
    
        /**
         * 获取实体
         * 
         * @param id
         * @return
         */
        public T getT(String sql, Object param) {
            return sqlSessionTemplate.selectOne(sql, param);
        }
        /**
         * 不带查询参数的列表
         * @param str
         * @return
         * @throws Exception
         */
        public List<T> findTList(String sql){
            return sqlSessionTemplate.selectList(sql);
        }
    
        /**
         * 带有参数的列表
         * 
         * @param str
         * @param param
         * @return
         * @throws Exception
         */
        public List<T> findTListByParam(String sql, Object param) {
            return sqlSessionTemplate.selectList(sql, param);
        }
    
        /**
         * 插入一条数据,参数是t
         * 
         * @param sql
         * @param t
         * @return
         */
        public int addT(String sql, T t) {
            return sqlSessionTemplate.insert(sql, t);
        }
        /**
         * 修改一条数据,参数是t
         * @param sql
         * @param t
         * @return
         */
        public int updateT(String sql,T t){
            return sqlSessionTemplate.update(sql, t);
        }
        /**
         * 删除t,参数是主键
         * @param sql
         * @param t
         * @return
         */
        public int deleteT(String sql,PK pk){
            return sqlSessionTemplate.delete(sql, pk);
        }
        /**
         * 根据param获取一个对象
         * @param sql
         * @param param
         * @return
         */
        public Object getObject(String sql,Object param){
            return sqlSessionTemplate.selectOne(sql,param);
        }
    }
  • 相关阅读:
    SVN服务器搭建(一)
    排序算法二:冒泡排序
    【LeetCode】136. Single Number
    【LeetCode】217. Contains Duplicate
    【LeetCode】189. Rotate Array
    【LeetCode】122. Best Time to Buy and Sell Stock II
    【LeetCode】26. Remove Duplicates from Sorted Array
    【LeetCode】20. Valid Parentheses
    【LeetCode】680. Valid Palindrome II
    【LeetCode】345. Reverse Vowels of a String
  • 原文地址:https://www.cnblogs.com/roy-blog/p/7080258.html
Copyright © 2011-2022 走看看