MyBatis复杂sql:多对一处理(association)和一对多(collection)

2023-11-11

多对一(association标签)

  • 老师和学生的例子
  • 以学生为出发点,就是一个多对一的例子,即多个学生关联一个老师!

首先搭建数据库

CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO teacher(`id`, `name`) VALUES (1, '羊羊');

CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8


INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小羊', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小锅', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小虎', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小狗', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小明', '1');

利用lombok简化代码

1、Lombok

  • lombok是一个可以帮助我们简化java代码编写的工具类,尤其是简化javabean的编写,即通过采用注解的方式,消除代码中的构造方法,getter/setter等代码,使我们写的类更加简洁,当然,这带来的副作用就是不易阅读…
  • lombok注解解释:https://www.cnblogs.com/heyonggang/p/8638374.html,当然大家也可以自行百度

2、引入Lombok的Maven依赖

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.16.10</version>
</dependency>

3、在代码中增加注解

@Data //GET,SET,ToString,有参,无参构造
public class Teacher {
   private int id;
   private String name;
}
@Data
public class Student {
   private int id;
   private String name;
   //多个学生可以是同一个老师,即多对一
   private Teacher teacher;
}

4、编写实体类对应的Mapper接口

public interface StudentMapper {
}
public interface TeacherMapper {
}

5、编写Mapper接口对应的 mapper.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yang.mapper.StudentMapper">

</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yang.mapper.TeacherMapper">

</mapper>

复杂查询,获取所有学生及对应老师的信息

  • 两种方法实现
  • 按查询嵌套处理(像SQL中的子查询)
  • 按结果嵌套处理(像SQL中的联表查询)

1、给StudentMapper接口增加方法

public List<Student> getStudents();   //查询嵌套处理
public List<Student> getStudents2();  //结果嵌套处理

2、编写对应的Mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yang.mapper.StudentMapper">

   <!--
   查询嵌套处理
   -->
   <select id="getStudents" resultMap="StudentTeacher">
    select * from student
   </select>
   <resultMap id="StudentTeacher" type="Student">
       <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
       <association property="teacher"  column="tid"javaType="Teacher" select="getTeacher"/>
   </resultMap>
   <!--
   这里传递过来的id,只有一个属性的时候,下面可以写任何值
   association中column多参数配置:
       column="{key=value,key=value}"
       其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
   -->
   <select id="getTeacher" resultType="teacher">
      select * from teacher where id = #{id}
   </select>
   
	<!--
	按查询结果嵌套处理
	-->
	<select id="getStudents2" resultMap="StudentTeacher2" >
	  select s.id sid, s.name sname , t.name tname
	  from student s,teacher t
	  where s.tid = t.id
	</select>
	
	<resultMap id="StudentTeacher2" type="Student">
	   <id property="id" column="sid"/>
	   <result property="name" column="sname"/>
	   <!--关联对象property 关联对象在Student实体类中的属性-->
	   <association property="teacher" javaType="Teacher">
	       <result property="name" column="tname"/>
	   </association>
	</resultMap>

</mapper>

3、记得注册Mapper

4、注意点说明:

<resultMap id="StudentTeacher" type="Student">
   <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
   <association property="teacher"  column="{id=tid,name=tid}"javaType="Teacher" select="getTeacher"/>
</resultMap>
<!--
这里传递过来的id,只有一个属性的时候,下面可以写任何值
association中column多参数配置:
   column="{key=value,key=value}"
   其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
-->
<select id="getTeacher" resultType="teacher">
  select * from teacher where id = #{id} and name = #{name}
</select>

5、测试

@Test
public void testGetStudents(){
   SqlSession session = MybatisUtils.getSession();
   StudentMapper mapper =session.getMapper(StudentMapper.class);

   List<Student> students = mapper.getStudents();

   for (Student student : students){
       System.out.println(
               "学生名:"+ student.getName()
                       +"\t老师:"+student.getTeacher().getName());
  }
}

@Test
public void testGetStudents2(){
   SqlSession session = MybatisUtils.getSession();
   StudentMapper mapper =session.getMapper(StudentMapper.class);

   List<Student> students = mapper.getStudents2();

   for (Student student : students){
       System.out.println(
               "学生名:"+ student.getName()
                       +"\t老师:"+student.getTeacher().getName());
  }
}

一对多的处理

  • 老师和学生的例子
  • 以老师为出发点,就是一个多对一的例子,即一个老师关联多个学生!

环境相同,使用两种方法分别实现
按结果嵌套处理

1、TeacherMapper接口编写方法

//获取指定老师,及老师下的所有学生
public Teacher getTeacher(int id);

2、编写接口对应的Mapper配置文件

<mapper namespace="com.yang.mapper.TeacherMapper">

   <!--
   思路:
       1. 从学生表和老师表中查出学生id,学生姓名,老师姓名
       2. 对查询出来的操作做结果集映射
           1. 集合的话,使用collection!
               JavaType和ofType都是用来指定对象类型的
               JavaType是用来指定pojo中属性的类型
               ofType指定的是映射到list集合属性中pojo的类型。
   -->
   <select id="getTeacher" resultMap="TeacherStudent">
      select s.id sid, s.name sname , t.name tname, t.id tid
      from student s,teacher t
      where s.tid = t.id and t.id=#{id}
   </select>

   <resultMap id="TeacherStudent" type="Teacher">
       <result  property="name" column="tname"/>
       <collection property="students" ofType="Student">
           <result property="id" column="sid" />
           <result property="name" column="sname" />
           <result property="tid" column="tid" />
       </collection>
   </resultMap>
</mapper>

3、将Mapper文件注册到MyBatis-config文件中

<mappers>
   <mapper resource="mapper/TeacherMapper.xml"/>
</mappers>

4、测试

@Test
public void testGetTeacher(){
   SqlSession session = MybatisUtils.getSession();
   TeacherMapper mapper =session.getMapper(TeacherMapper.class);
   Teacher teacher = mapper.getTeacher(1);
   System.out.println(teacher.getName());
   System.out.println(teacher.getStudents());
}

按查询嵌套处理

1、TeacherMapper接口编写方法

public Teacher getTeacher2(int id);

2、编写接口对应的Mapper配置文件

<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
   <!--column是一对多的外键 , 写的是一的主键的列名-->
   <collection property="students" javaType="ArrayList"ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
  select * from student where tid = #{id}
</select>

3、将Mapper文件注册到MyBatis-config文件中

4、测试

@Test
public void testGetTeacher2(){
   SqlSession session = MybatisUtils.getSession();
   TeacherMapper mapper =session.getMapper(TeacherMapper.class);
   Teacher teacher = mapper.getTeacher2(1);
   System.out.println(teacher.getName());
   System.out.println(teacher.getStudents());
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis复杂sql:多对一处理(association)和一对多(collection) 的相关文章

  • Grails 3.x bootRun 失败

    我正在尝试在 grails 3 1 11 中运行一个项目 但出现错误 失败 构建失败并出现异常 什么地方出了错 任务 bootRun 执行失败 进程 命令 C Program Files Java jdk1 8 0 111 bin java
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • 如何默认将 Maven 插件附加到阶段?

    我有一个 Maven 插件应该在编译阶段运行 所以在项目中consumes我的插件 我必须做这样的事情
  • Java中反射是如何实现的?

    Java 7 语言规范很早就指出 本规范没有详细描述反射 我只是想知道 反射在Java中是如何实现的 我不是问它是如何使用的 我知道可能没有我正在寻找的具体答案 但任何信息将不胜感激 我在 Stackoverflow 上发现了这个 关于 C
  • Java EE:如何获取我的应用程序的 URL?

    在 Java EE 中 如何动态检索应用程序的完整 URL 例如 如果 URL 是 localhost 8080 myapplication 我想要一个可以简单地将其作为字符串或其他形式返回给我的方法 我正在运行 GlassFish 作为应
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • 无法展开 RemoteViews - 错误通知

    最近 我收到越来越多的用户收到 RemoteServiceException 错误的报告 我每次给出的堆栈跟踪如下 android app RemoteServiceException Bad notification posted fro
  • 反射找不到对象子类型

    我试图通过使用反射来获取包中的所有类 当我使用具体类的代码 本例中为 A 时 它可以工作并打印子类信息 B 扩展 A 因此它打印 B 信息 但是当我将它与对象类一起使用时 它不起作用 我该如何修复它 这段代码的工作原理 Reflection
  • 磁模拟

    假设我在 n m 像素的 2D 表面上有 p 个节点 我希望这些节点相互吸引 使得它们相距越远吸引力就越强 但是 如果两个节点之间的距离 比如 d A B 小于某个阈值 比如 k 那么它们就会开始排斥 谁能让我开始编写一些关于如何随时间更新
  • getResourceAsStream() 可以找到 jar 文件之外的文件吗?

    我正在开发一个应用程序 该应用程序使用一个加载配置文件的库 InputStream in getClass getResourceAsStream resource 然后我的应用程序打包在一个 jar文件 如果resource是在里面 ja
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 无法捆绑适用于 Mac 的 Java 应用程序 1.8

    我正在尝试将我的 Java 应用程序导出到 Mac 该应用程序基于编译器合规级别 1 7 我尝试了不同的方法来捆绑应用程序 1 日食 我可以用来在 Eclipse 上导出的最新 JVM 版本是 1 6 2 马文 看来Maven上也存在同样的
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • simpleframework,将空元素反序列化为空字符串而不是 null

    我使用简单框架 http simple sourceforge net http simple sourceforge net 在一个项目中满足我的序列化 反序列化需求 但在处理空 空字符串值时它不能按预期工作 好吧 至少不是我所期望的 如
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • JGit 检查分支是否已签出

    我正在使用 JGit 开发一个项目 我设法删除了一个分支 但我还想检查该分支是否已签出 我发现了一个变量CheckoutCommand但它是私有的 private boolean isCheckoutIndex return startCo

随机推荐

  • MapReduce的基本工作原理

    MapReduce的基本模型和处理思想 三个层面上的基本构思 1 如果对付大数据处理 分而治之 对相互之间不具有计算依赖关系的大数据 实现并行最自然的办法就是采取分而治之的策略 2 上升到抽象模型 Mapper与Reduce MPI等并行计
  • 那些配置服务器踩的坑

    最近在配置内网 无外网的服务器 纯纯记录一下踩得坑 希望看到的人不要再走这条弯路 任务 对接在目标服务器部署目标sdk 第一天 由于服务器是十分保密的 且通过层层套娃才能传到
  • spark任务执行过程中经常性的failed但是任务并没有失败最后总能跑完

    1 现象场景 在spark执行程序中会看到很多的failed但是过程能正常执行完 spark任务执行过程中经常性的failed但是任务并没有失败最后总能跑完 查看如下 ExecutorLostFailure executor 11 exit
  • 数字盲打怎么练_键盘上的数字键怎么练才能盲打?

    展开全部 副键盘的数字键练习 保证数32313133353236313431303231363533e4b893e5b19e31333431363663字锁定键指示灯亮 如果没有亮 需要按一次 Num Lock 键 使小键盘区为数字输入状态
  • 2020.9.17课堂笔记(Hive数据库常用DDL操作)

    数据库基本操作database 数据库模式定义语言DDL Data Definition Language 是用于描述数据库中要存储的现实世界实体的语言 create database if not exists 数据库名 创建数据库 sh
  • java如何合并_Java中如何把两个数组合并为一个

    在Java中 如何把两个String 合并为一个 看起来是一个很简单的问题 但是如何才能把代码写得高效简洁 却还是值得思考的 这里介绍四种方法 请参考选用 一 apache commons 这是最简单的办法 在apache commons中
  • numpy找非零元素并计数 numpy.nonzero 和 numpy.count_nonzero

    numpy nonzero a Return the indices of the elements that are non zero 示例 x np array 3 0 0 0 4 0 5 6 0 np nonzero x array
  • OCR图像识别技术的JAVA实现(一)

    转自 https blog csdn net weistin article details 78839804 OCR图像识别技术的JAVA实现 最近有个需求需要用图像识别 学习记录一下 目前网络上的开源的图像识别技术有很多 例如 OCRE
  • win10系统下 VS2019点云库PCL1.12.0的安装与配置

    目录 版本信息 安装教程 环境变量设置 VS中PCL的配置 使用 PCL的简单demo PCL简介 点云库全称是Point Cloud Library PCL 是一个独立的 大规模的 开放的2D 3D图像和点云处理项目 PCL根据BSD许可
  • 微信errcode大全

    errArr 1 gt errMsg system error errDesc 系统繁忙 此时请开发者稍候再试 40009 gt errMsg Invalid image size errDesc 图片大小为0或者超过1M 40097 gt
  • oracle open resetlogs

    oracle数据库在使用alter database open resetlogs后 oracle会重置日志序列号 而且会重置 联机重做日志内容 这样做是为了防止不完全恢复后日志序列会发生冲突 所以在执行完resetlogs后 需要重新备份
  • Win7专业版 下安装ArcGIS 9.3总结

    这几天在Win7专业版下安装ArcGIS 9 3 简直逼疯我了 废话不多说 进入正题 边说遇见问题边说步骤和解决方法 1 下载破解文件 下载地址http download csdn net source 3117196 有以下文件夹 图1
  • 【目标检测】24、VarifocalNet: An IoU-Aware Dense Object Detector

    文章目录 一 背景 二 动机 三 方法 3 1 IACS IoU Aware Classification Score 3 2 Varifocal loss 3 3 Star Shaped Box Feature Representatio
  • ios-swift-导入Alamofire出坑

    前言 在最近的swift项目中要用到网络请求 就用到了Alamofire网络库 是AFNetworking库的swift版本 将Alamofire利用Cocoapods导入到项目里面 总是下载不了新的版本 下载不了新的版本就是报错 我用的x
  • Jenkins 配置邮件通知

    1 安装邮件插件 通过系统管理 管理插件 可选插件 选择Email Extension Plugin插件进行安装 2 系统配置 系统管理 系统设置
  • MyBatis和Spring整合+Spring扩展

    ctrl shift t搜索类 ctrl o查看所有的属性和方法 ctrl t查看继承体系 jar包版本需要一致 MyBatis和Spring整合 在配置文件中 不要写空格 空格也会被解析 JavaSE基础内容 Java语法阶段 Java是
  • Cookie 和 Session 的工作流程(模拟网页登录)

    目录 今日良言 欲望以提升热忱 毅力以磨平高山 一 Cookie 和 Session的工作流程 二 模拟网页登录 三 Cookie 和 Session的区别和联系 1 联系 2 区别 今日良言 欲望以提升热忱 毅力以磨平高山 一 Cooki
  • java base64转Binary

    java base64转Binary Base64转byte byte bytes DatatypeConverter parseBase64Binary base64字符串 byte 转base64 String base64Str Da
  • Unity3d 按钮控制视频播放暂停

    有好几个办法 这边选择最简单的办法 创建一个游戏物体 啥都行 组件就是孙悟空的技能 我让游戏物体有啥技能就加啥组件 这里创建了个Quad平面 直接给他添加了组件叫Video Player 任何组件都有对应的类来存放它 直接把放到Unity
  • MyBatis复杂sql:多对一处理(association)和一对多(collection)

    多对一 association标签 老师和学生的例子 以学生为出发点 就是一个多对一的例子 即多个学生关联一个老师 首先搭建数据库 CREATE TABLE teacher id INT 10 NOT NULL name VARCHAR 3