mybatis一对多查询的几种方法:MyBatis精讲四查询数据方法精讲及实战代码集合
欢迎来到全网最完整的Java系列教程!!! 本教程将包含基础知识、进阶知识、常用框架等,循序渐进地分享Java中必须掌握的知识和技术。跟着老K的教程每天学习一点,你会发现入门Java没有想象中那么难。
MyBatis是一个非常实用、在java领域应用非常广泛的持久层框架。
这是本系列的第四篇文章,在前面的内容中,我们已经体验了使用MyBatis请求数据的过程了。
今天我们就落到细节,详细讲讲MyBatis发起查询请求这些事儿。
要了解前三篇内容的,可以从下述链接进入查看:
- MyBatis精讲(一)MyBatis基础配置及持久层连接创建代码实战
- MyBatis精讲(二)常用工具MyBatisUtils类的实现
- MyBatis精讲(三)一篇文章让你学会用MyBatis获取数据
一、无参查询请求
首先,对于MyBatis的基本配置,以及mapper映射表相关的准备工作,请参见前几讲的内容。
本文涉及到的代码会应用到MySQL数据库,请至MyBatis精讲(三)一篇文章让你学会如何用MyBatis获取数据获取本项目涉及的SQL语句。
在完成前期的准备后,就可以编写查询请求的代码了。
一般数据请求的编写都是在Mapper映射文件中完成的,编写完整的测试用例需要对mapper和test两个文件进行操作,本例中此2文件分别为:
- ./src/main/resources/mappers/humanResource.xml
- ./src/test/java/MyBatisTest.java
所有的映射方法都是在humanResource.xml中的<mapper>标签下设置:
<select id="selectAll" resultType="koder.mybatis.entity.Employee">
select * from employee order by id desc limit 10
</select>
再在MyBatisTest.java里编写测试用例:
@Test
public void testSelectAll() {
SQLSession session = null;
try {
session = MyBatisUtils.openSession();
List<Employee> list = session.selectList("humanResource.selectAll");
for (Employee ex : list) {
System.out.println(ex.getDepart() "\t" ex.getName());
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
上述案例在MyBatis精讲(三)一篇文章让你学会如何用MyBatis获取数据有详解,本文中不做展开。
上述测试用例运行结果是:
技术部 郑望
技术部 周武
销售部 孙礼
销售部 赵乾
二、单参查询请求
本例中,我们会通过id为参数,完成查询请求的操作,以展示MyBatis单参查询的方法。
- humanResource.xml
<select id="selectById" parameterType="Integer" resultType="koder.mybatis.entity.Employee">
select * from employee where id = #{value}
</select>
- 属性id即为当前查询方法的名称;
- 属性parameterType表示该单参方法传入的参数类型,此处为Integer;
- 属性resultType表示该方法的输出结果的数据类型,此处k.m.e.Employee表示该java类型的项目地址;
- 对于熟悉java的小伙伴,如果对上述xml的写法理解困难,可以对照下述代码,比较着记忆:
public k.m.e.Employee selectById(Integer value){
return SQL("select * from employee where id = #{value}");
}
- MyBatisTest.java 的测试用例
@Test
public void testSelectById() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
Employee employee = session.selectOne("humanResource.selectById", 5002);
System.out.println(employee.getDepart() "\t" employee.getName());
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- 由于上例中的单参查询返回的是单个对象,所以使用session.selectOne的方法执行查询;
- humanResource.selectById的语法结构和java相当类似,表示在humanResource这个命名空间下的selectById方法;
- selectOne中的第二个参数即为传入humanResource.selectById方法中的参数,参数类型需要同humanResource.xml 中的parameterType设置的数据类型一致;
- 查询结果为Employee,这与在mapper的resultType中设置的koder.mybatis.entity.Employee一致
上述测试用例代码执行后,将会得到如下结果:
销售部 孙礼
三、多参查询请求
实战场景中,无参或单参查询的情况比较少,这里我们介绍以下多参查询请求。
本例中,我们通过多参请求,获取薪酬在6000-7000元之间的职员名单。
humanResource.xml
<select id="selectBySalaryRange" parameterType="java.util.Map" resultType="koder.mybatis.entity.Employee">
select * from employee where salary between #{min} and #{max}
</select>
- 这里,我们用Map对象将多参传入方法,所以这里的parameterType设置为java.util.Map
MyBatisTest.java 的测试用例
@Test
public void testSelectByScoreRange() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
Map param = new HashMap();
param.put("min", 6000);
param.put("max", 7000);
List<Employee> list = session.selectList("humanResource.selectBySalaryRange", param);
for (Employee em : list) {
System.out.println(em.getDepart() "\t" em.getName() "\t" em.getSalary());
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- 传入的参数先存储到Map中,本例使用的HashMap;
- selectList和selectOne 的参数列表相同,第一个参数为xml的查询方法名,第二个参数为传入的方法参数,本例中由于是多参,传入Map;
上例中运行后的结果为:
销售部 赵乾 6000.0
销售部 孙礼 7000.0
技术部 周武 6500.0
四、链表查询请求
链表查询是sql数据查询中常见的应用场景,本例中,我们链表查询雇员和部门的信息。
humanResource.xml
<select id="selectEmployeeMap" resultType="java.util.LinkedHashMap">
select e.*, d.* from employee e, department d where e.depart = d.depart
</select>
- 本例中以HashMap的形式输出结果,所以resultType设置为java.util.LinkedHashMap
MyBatisTest.java 的测试用例
@Test
public void testSelectEmployeeMap() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
List<LinkedHashMap> list = session.selectList("humanResource.selectEmployeeMap");
for (LinkedHashMap map : list) {
System.out.println(map);
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- 链表查询本例中也是使用selectList调用,主要设置环节在mapper里配置
运行上述测试代码,得到的结果是:
{id=5001, name=赵乾, depart=销售部, salary=6000.00, age=28, did=1, member=5}
{id=5002, name=孙礼, depart=销售部, salary=7000.00, age=34, did=1, member=5}
{id=6001, name=周武, depart=技术部, salary=6500.00, age=27, did=2, member=6}
{id=6002, name=郑望, depart=技术部, salary=7500.00, age=40, did=2, member=6}
五、DTO对象查询请求
用Map做链表查询其实不是MyBatis的常规操作,我们引入一个DTO的概念。
DTO是”Data Transfer Object“的缩写,是MyBatis解决链表查询规范性、一致性问题的解决方案。
DTO的中心思想,就是在项目中新建一个对象,来容纳返回的链表数据。
先在./src/main/java/koder/mybatis/路径下创建目录和文件/dto/EmployeeDTO.java;
EmployeeDTO.java代码如下:
import koder.mybatis.entity.Department;
import koder.mybatis.entity.Employee;
public class EmployeeDTO {
private Employee employee;
private Department department;
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
}
- 将链表所对应的对象包装到DTO的私有变量里,再设置好getter和setter即可;
编写humanResource.xml
<resultMap id="emDTO" type="koder.mybatis.dto.EmployeeDTO">
<id property="employee.id" column="id"/>
<result property="employee.name" column="name"/>
<result property="employee.salary" column="salary"/>
<result property="employee.depart" column="depart"/>
<result property="employee.depart" column="depart"/>
<result property="employee.age" column="age"/>
<result property="department.did" column="did"/>
<result property="department.member" column="member"/>
</resultMap>
<select id="selectEmployeeDTO" resultMap="emDTO">
select e.*, d.* from employee e, department d where e.depart = d.depart
</select>
- DTO首先要在<mapper>标签下创建<resultMap>标签,用id和result将EmployeeDTO类匹配起来;
- <resultMap>里的属性id表示该对象在mapper映射表xml中的名字,type表示该对象在项目中的java文件路径;
- <resultMap>的子标签<id>和<result>的性质差不多,都是有property和columm属性,分别对应DTO类的私有变量名和数据表中的字段名。唯一的差别是<id>表示这个字段是id;
- 完成<resultMap>的设置后,就能在mapper映射表xml中调用它了,我们把<select>标签下的resultMap属性设置成<resultMap>中定义的名字,即id名。
MyBatisTest.java 的测试用例:
@Test
public void testSelectEmployeeDTO() {
SqlSession session = null;
try {
session = MyBatisUtils.openSession();
List<EmployeeDTO> list = session.selectList("humanResource.selectEmployeeDTO");
for (EmployeeDTO em : list) {
System.out.println(em.getEmployee().getName() "所在的部门有" em.getDepartment().getMember() "人。");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
MyBatisUtils.closeSession(session);
}
}
- 具体调用测试的代码,就和前述的用Map包裹链表结果的方法一致,不作展开了。
运行结果如下:
赵乾所在的部门有5人。
孙礼所在的部门有5人。
周武所在的部门有6人。
郑望所在的部门有6人。
至此,MyBatis的常见查询方法,我们已经介绍的差不多了。
本期的内容非常多,一下子消化可能有难度,建议收藏起来,慢慢阅读。
之后,我们还剩“增删改”相关的知识没有分享。
这部分会在下一讲里分享,大家可以先关注一下,随时获取后续教程内容和信息。
如果你对老K分享的内容有任何疑问,欢迎随时在评论区留言或者私信我。
正在学习的小伙伴记得给老K一个赞哦,你的支持是我持续输出课程内容最大的动力!
阅读推荐我也分享过关于如何学习Java的文章,有需要的小伙伴可以点击下方链接获取:
IT大佬推荐!学习Java的最优路径 分享多个阶段的学习资源 建议收藏
结束语
我是专注于开发领域的@老K玩代码,会持续生产关于如何学习编程语言的优质内容。
如果你想学习Java编程,或者想精进你的Java编程能力,可以关注我。
如果你对开发、编程有任何疑问或者有想了解的内容,而我暂时没有写到的,也欢迎随时来找我聊聊。
#创作挑战赛#
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com