• 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);
        }
    }
  • 相关阅读:
    jumpserver的安装
    安装iostat 命令
    zabbix配置server,proxy,agent架构
    RGB颜色对照表
    【ZYNQ-7000开发之九】使用VDMA在PL和PS之间传输视频流数据
    基于AXI VDMA的图像采集系统
    图像采集调试总结
    DDR3调试总结
    内存系列二:深入理解硬件原理
    在嵌入式设计中使用MicroBlaze(Vivado版本)
  • 原文地址:https://www.cnblogs.com/roy-blog/p/7080258.html
Copyright © 2020-2023  润新知