递归调用的应用场景常常出现在多级嵌套的情况,比如树形的菜单。下面通过一个简单的例子来实现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_categorywhere is_del=0andparent_category_id=#{_parameter,jdbcType=INTEGER}</select>

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

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

<!-- 递归查询所有 --><select id="selectRecursionAll" resultMap="TreeMap">select*from t_categorywhere is_del=0andcategory_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);}
}

转载于:https://www.cnblogs.com/roy-blog/p/7080258.html

mysql+mybatis递归调用相关推荐

  1. mysql导入组织树脚本_mysql存储过程递归调用发作树数据

    mysql存储过程递归调用产生树数据 使用finereport的树下拉框时,要求提供有层次结构的数据.例如:一级001,二级001001,三级001001001 等.而我们一般的递归表是这样的,定义一 ...

  2. Mysql递归调用,报错:Subquery returns more than 1 row

    在学习Mysql递归调用中,编写的 递归SQL 在 Navicat 中运行正常,但在 Java项目中 mapper.xml 文件中确报错:Subquery returns more than 1 ro ...

  3. mysql通过函数完成10的阶乘_请使用函数的递归调用编写求阶乘的函数,并计算1!+2!+3!+4!+5!...

    点击查看请使用函数的递归调用编写求阶乘的函数,并计算1!+2!+3!+4!+5!具体信息 答:include "stdio.h" int fac(int k) { if(k==1) ...

  4. 第一:MySQL+MyBatis实现对测试用例数据的读取(接口自动化落地)

    讲解TestNG+MySQL+MyBatis+ExtentReports实现对测试用例数据的读取,下面放出所有配置文件的目录方便下文理解. 1.配置mysql数据库 在这里,拿logincase表举例 ...

  5. php 匿名函数 递归,匿名函数,lambda_C++ lambda 递归调用,匿名函数,lambda,c++ - phpStudy...

    C++ lambda 递归调用 自己敲的一个归并排序,C++11 #include #include using namespace std; template void merge_sort(T l ...

  6. MySql+Mybatis+Druid 优化之MyBatis批量删除、更新

    业务需求:一次更新/删除多条数据,通常有两种方式: (1)在业务代码中循环遍历,逐条删除,业务清晰: (2)在sql语句中,循环删除,只操作一次数据库,这个分为两种方式: 方式A:通过循环一个id列表 ...

  7. python 递归调用

    2019独角兽企业重金招聘Python工程师标准>>> 解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的. ...

  8. with as递归调用

    一.递归调用--在代码中偶尔看到以记之,便于下次学习 https://blog.csdn.net/johnf_nash/article/details/78681060 --查询节点及其下所有子节点 ...

  9. 编写递归调用的Lambda表达式

    前段时间,我写一个树的访问算法的时候,用了Visitor模式把访问的算法分离了出来,当时打算用lambda表达式写visit算法的,却发现带递归调用的lambda表达式没想象的那么好写,憋了半天愣是没 ...

最新文章

  1. linux文件的权限模式,Linux文件权限和访问模式
  2. 《统一沟通-微软-实战》-3-部署-Exchange 2010-4-基本配置
  3. 如何获得10倍的用户增长?| 文末福利
  4. Mui Webview下来刷新上拉加载实现
  5. Kafka 0.10.0文档翻译二
  6. linux的gromacs模拟分子运动,分子动力学技术交流---gromacsamber
  7. 单板机 单片机 c语言,单板机 单片机 个人计算机有什么区别吗
  8. python 之 click 包,设置命令行参数
  9. 给网游写一个挂吧(四) – 调用游戏函数
  10. 树莓派raspbian OS 64位系统下载和更换源
  11. css 实现居中的五种方式
  12. Ext JS 4 升级指南
  13. lr11 打开controller时,会提示提示cannot initialize driver dll,exiting
  14. 图书馆的uml概念类图怎么画_UML科普文,一篇文章掌握14种UML图
  15. python解压文件(自用)
  16. The More You Know: Using Knowledge Graphs for Image Classification 论文总结
  17. Google Authenticator(谷歌身份验证器)
  18. 现在开一间网吧还能挣钱么?
  19. html2canvas官网blurry,Why html2canvas produced blurry pdf file?
  20. C语言程序设计-现代方法 第二版 第6.1小节 显示平方表

热门文章

  1. spoj SUBLEX (Lexicographical Substring Search) RE的欢迎来看看
  2. GridControl动态添加 颜色列
  3. hdu 4279 Number
  4. [python、flask] - POST请求
  5. javascript --- vue2.x中原型的使用(拦截数组方法) 响应式原理(部分)
  6. es6 --- Proxy的属性(get、set除外)
  7. Java Web Servlet
  8. 25 Refs转发机制与在高阶组件中的使用
  9. 24 React.createRef()用法细节分析
  10. Git commit后,本地代码丢失解决方法