使用MyBatis轻松实现递归查询与存储过程调用
时间:2022-05-06
本文章向大家介绍使用MyBatis轻松实现递归查询与存储过程调用,主要内容包括递归调用、存储过程调用、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
vhr部门管理模块更新啦!为了让小伙伴们快速理解部门管理模块实现思路,我想通过3篇短文来给大家介绍下大致的实现思路和核心代码。
项目地址:https://github.com/lenve/vhr
本文主要介绍部门管理功能的后台程序,其实都是常规代码,我们重点关注两点:1.递归调用,2.存储过程调用
递归调用
由于部门的层级不可控,因此如果我想要获取所有部门的完整json的话,就要采用递归调用,使用Java代码处理递归有点low,刚好MyBatis的ResultMap中的collection可以很方便的解决这个问题,核心代码如下:
<resultMap id="BaseResultMap" type="org.sang.bean.Department">
<id property="id" column="id"/>
<result column="name" property="name"/>
<result column="parentId" property="parentId"/>
<result column="isParent" property="isParent"/>
<collection property="children" ofType="org.sang.bean.Department" select="org.sang.mapper.DepartmentMapper.getDepByPid" column="id">
</collection>
</resultMap>
<select id="getDepByPid" resultMap="BaseResultMap">
select d1.*from department d1 where d1.`parentId`=#{pid} AND d1.enabled=true;
</select>
每一个Department中都有一个children属性,getDepByPid方法的返回结果是一个BaseResultMap,BaseResultMap中的collection又将调用getDepByPid方法,通过这种方式我们可以快速实现一个递归调用。Mapper中只需要定义如下方法即可:
List<Department> getDepByPid(Long pid);
查询结果如下(部分):
[
{
"id": 1,
"name": "股东会",
"parentId": -1,
"enabled": true,
"children": [
{
"id": 4,
"name": "董事长",
"parentId": 1,
"enabled": true,
"children": [
{
"id": 5,
"name": "总经理",
"parentId": 4,
"enabled": true,
"children": [
{
"id": 8,
"name": "财务部",
"parentId": 5,
"enabled": true,
"children": [],
"parent": false
}],
"parent": true
}
],
"parent": true
}
],
"parent": true
}
]
存储过程调用
存储过程调用比较简单,以添加部门为例,如下:
1.Mapper中添加如下方法:
void addDep(@Param("dep") Department department);
2.xml中写法如下:
<select id="addDep" statementType="CALLABLE">
call addDep(#{dep.name,mode=IN,jdbcType=VARCHAR},#{dep.parentId,mode=IN,jdbcType=INTEGER},#{dep.enabled,mode=IN,jdbcType=BOOLEAN},#{dep.result,mode=OUT,jdbcType=INTEGER},#{dep.id,mode=OUT,jdbcType=BIGINT})
</select>
注意statementType调用表示这是一个存储过程,mode=IN表示这是输入参数,mode=OUT表示这是输出参数,调用成功之后,在service中获取department的id和result字段,就能拿到相应的调用结果了。
其他一些琐碎的技术就不值得介绍了,大家在源码中自行研究,有问题欢迎留言讨论。
- JSON 和 JSONP
- android 项目中出现红色感叹号的解决方法
- SharePoint Foundation 2010
- ASP.NET MVC Action Filters
- Android:StatFs类 获取系统/sdcard存储空间信息
- 数据挖掘干货
- 高效 Mac 人士必备:实现工作/家庭间网络环境切换的自动化
- android中AVD的使用
- ASP.NET MVC 2示例Tailspin Travel UI层分析
- CSS 命名之Dialog, Modal, Popup, Popover, Lightbox 等的区别
- Eclipse JAVA文件注释乱码
- 2018年小程序的红利趋势预测,懂的来……或许你将成为下个富翁
- VUE 入门基础(6)
- 五年换4高管,6000员工裁95%剩300人,王健林为何抛弃万达网科?
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- web.py指南性说明
- this到底指向啥?看完这篇就知道了!
- 学以致用:手把手教你撸一个工具库并打包发布,顺便解决JS小数计算不准问题
- python 实现 php 的 var_dump 功能
- RSA初探,聊聊怎么破解HTTPS
- 深入解析Underscore.js源码架构
- python正向连接后门
- setTimeout和setImmediate到底谁先执行,本文让你彻底理解Event Loop
- emlog全版本CSRF加用户xsser.me模块
- 从发布订阅模式入手读懂Node.js的EventEmitter源码
- 手写一个Promise/A+,完美通过官方872个测试用例
- 浅析白盒审计中的字符编码及SQL注入
- JS做类型检测到底有几种方法?看完本文就知道了!
- HDwiki时间延迟盲注及利用代码
- JS作用域和变量提升看这一篇就够了