User-Profile-Image
hankin
  • 5
  • Java
  • Kotlin
  • Spring
  • Web
  • SQL
  • MegaData
  • More
  • Experience
  • Enamiĝu al vi
  • 分类
    • Zuul
    • Zookeeper
    • XML
    • WebSocket
    • Web Notes
    • Web
    • Vue
    • Thymeleaf
    • SQL Server
    • SQL Notes
    • SQL
    • SpringSecurity
    • SpringMVC
    • SpringJPA
    • SpringCloud
    • SpringBoot
    • Spring Notes
    • Spring
    • Servlet
    • Ribbon
    • Redis
    • RabbitMQ
    • Python
    • PostgreSQL
    • OAuth2
    • NOSQL
    • Netty
    • MySQL
    • MyBatis
    • More
    • MinIO
    • MegaData
    • Maven
    • LoadBalancer
    • Kotlin Notes
    • Kotlin
    • Kafka
    • jQuery
    • JavaScript
    • Java Notes
    • Java
    • Hystrix
    • Git
    • Gateway
    • Freemarker
    • Feign
    • Eureka
    • ElasticSearch
    • Docker
    • Consul
    • Ajax
    • ActiveMQ
  • 页面
    • 归档
    • 摘要
    • 杂图
    • 问题随笔
  • 友链
    • Spring Cloud Alibaba
    • Spring Cloud Alibaba - 指南
    • Spring Cloud
    • Nacos
    • Docker
    • ElasticSearch
    • Kotlin中文版
    • Kotlin易百
    • KotlinWeb3
    • KotlinNhooo
    • 前端开源搜索
    • Ktorm ORM
    • Ktorm-KSP
    • Ebean ORM
    • Maven
    • 江南一点雨
    • 江南国际站
    • 设计模式
    • 熊猫大佬
    • java学习
    • kotlin函数查询
    • Istio 服务网格
    • istio
    • Ktor 异步 Web 框架
    • PostGis
    • kuangstudy
    • 源码地图
    • it教程吧
    • Arthas-JVM调优
    • Electron
    • bugstack虫洞栈
    • github大佬宝典
    • Sa-Token
    • 前端技术胖
    • bennyhuo-Kt大佬
    • Rickiyang博客
    • 李大辉大佬博客
    • KOIN
    • SQLDelight
    • Exposed-Kt-ORM
    • Javalin—Web 框架
    • http4k—HTTP包
    • 爱威尔大佬
    • 小土豆
    • 小胖哥安全框架
    • 负雪明烛刷题
    • Kotlin-FP-Arrow
    • Lua参考手册
    • 美团文章
    • Java 全栈知识体系
    • 尼恩架构师学习
    • 现代 JavaScript 教程
    • GO相关文档
    • Go学习导航
    • GoCN社区
    • GO极客兔兔-案例
    • 讯飞星火GPT
    • Hollis博客
    • PostgreSQL德哥
    • 优质博客推荐
    • 半兽人大佬
    • 系列教程
    • PostgreSQL文章
    • 云原生资料库
    • 并发博客大佬
Help?

Please contact us on our email for need any support

Support
    首页   ›   SQL   ›   MyBatis   ›   正文
MyBatis

Mybatis一对一、一对多、多对多查询(补充)

2020-04-08 23:26:51
1099  0 0
参考目录 隐藏
1) 数据表:
2) 老师表:
3) 学生表:
4) 职位表:
5) 最后是教师学生关系表:
6) 贴出POJO中的三个实体:
7) Position.java
8) Student.java
9) Teacher.java
10) 一对一:老师对职位
11) TeacherMapper.xml
12) TeacherMapper.java接口
13) 测试一对一:
14) 一对多:职位对老师
15) PositionMapper.xml
16) TeacherMapper.java接口
17) 测试一对多:
18) 多对多:职位是教授的老师教授的所有学生(一对多对多:只要你愿意可以一直对多下去…)
19) PositionMapper.xml
20) PositionMapper.java接口
21) 测试:

阅读完需:约 8 分钟

场景:使用三张数据表:student学生表、teacher教师表、position职位表

一个学生可以有多为老师、一位老师可以有多个学生、但是一个老师只能有一个职位:教授、副教授、讲师;但是一个职位可以有多个老师:例如教授可以多人

这里则产生了:

  1. 一对一关系,从老师角度:老师对职位一对一
  2. 一对多关系,从职位角度:职位对老师一对多
  3. 多对多关系:查找被教授教导的所有学生(首先职位对老师一对多,老师再对学生再对多、这里便有了一对多对多)
Mysql—多表连接查询

数据表:

老师表:

CREATE TABLE `tb_teacher` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_no` varchar(20) DEFAULT NULL,
  `t_name` varchar(20) DEFAULT NULL,
  `position_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
 
/*Data for the table `tb_teacher` */
 
insert  into `tb_teacher`(`id`,`t_no`,`t_name`,`position_id`) values
(1,'163314001','张文远',1),
(2,'163314002','赵传智',1),
(3,'163314003','风清扬',2),
(4,'163314004','王汇智',2),
(5,'163314005','汪思远',3);

学生表:

CREATE TABLE `tb_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_stu_name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
 
/*Data for the table `tb_student` */
 
insert  into `tb_student`(`id`,`t_stu_name`) values 
 
(1,'赵依'),
 
(2,'钱迩'),
 
(3,'张山'),
 
(4,'李石'),
 
(5,'王武'),
 
(6,'马柳');

职位表:

CREATE TABLE `tb_position` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_pos_name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
 
/*Data for the table `tb_position` */
 
insert  into `tb_position`(`id`,`t_pos_name`) values 
 
(1,'教授'),
 
(2,'副教授'),
 
(3,'讲师');

最后是教师学生关系表:

CREATE TABLE `tb_stu_teach` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_stu_id` int(11) DEFAULT NULL,
  `t_teach_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
 
/*Data for the table `tb_stu_teach` */
 
insert  into `tb_stu_teach`(`id`,`t_stu_id`,`t_teach_id`) values 
 
(1,1,1),
 
(2,1,2),
 
(3,1,3),
 
(4,2,2),
 
(5,2,3),
 
(6,2,4),
 
(7,3,3),
 
(8,3,4),
 
(9,3,5),
 
(10,4,4),
 
(11,4,5),
 
(12,4,1);

eclipse中的目录结构如下:

贴出POJO中的三个实体:

Position.java

package com.pojo;
 
import java.io.Serializable;
 
import lombok.Data;
 
@Data
public class Position implements Serializable {
	private int id;
	private String name;
	
	private Teacher teacher;
 
}

Student.java

package com.pojo;
 
import java.io.Serializable;
import java.util.List;
 
import lombok.Data;
 
@Data
public class Student implements Serializable {
	private String id;
	private String name;
	
	private List<Teacher> list;
}

Teacher.java

package com.pojo;
 
import java.io.Serializable;
import java.util.List;
 
import lombok.Data;
 
@Data
public class Teacher implements Serializable {
	private int id;
	
	private String no;
	private String name;
	private List<Student> studentList;
	
	private Position pos;
}

注意:关系表不用以实体表示出来,表示外键关系的ID也不用写在实体中(一般我们也不使用外键)

一对一:老师对职位

TeacherMapper.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.mapper.TeacherMapper">
	<resultMap type="Teacher" id="teacherPositionResultMap">
		<id property="id" column="id"/>
		<result property="no" column="t_no"/>
		<result property="name" column="t_name"/>
		<!-- association:配置的一对一属性 -->
		<!-- property:名字
			 javaType:类型
		 -->
		<association property="pos" javaType="Position">
			<id property="id" column="id"/>
			<result property="name" column="t_pos_name"/>
		</association>
	</resultMap>
	
	<!-- 一对一关联查询,查询老师及其对应的职位 -->
	<!-- 注意:id不能相同,当多个值传入,比如包装类的时候,我们才能够用SQL片段的形式来做if判断,单个值是不行的 -->
	<select id="queryTeacherPositionResultMapById" resultMap="teacherPositionResultMap" parameterType="Integer">
		SELECT *
		FROM tb_teacher t
		LEFT JOIN tb_position p
		ON t.position_id = p.id
		where t.id = #{id}
	</select>
 
	<select id="queryTeacherPositionResultMap" resultMap="teacherPositionResultMap">
		SELECT *
		FROM tb_teacher t
		LEFT JOIN tb_position p
		ON t.`position_id` = p.id
	</select> 
</mapper>

TeacherMapper.java接口

package com.mapper;
 
import java.util.List;
 
import com.pojo.Teacher;
 
public interface TeacherMapper {
	public List<Teacher> queryTeacherPositionResultMap();
	
	public Teacher queryTeacherPositionResultMapById(Integer id);
}

测试一对一:

package com.test;
 
import java.util.List;
 
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
 
import com.mapper.TeacherMapper;
import com.pojo.Teacher;
import com.util.MyBatisUtil;
 
public class TestOneToOne {
	@Test
	public void testOneToOne() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		System.err.println(sqlSession);
		
		TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
		
		List<Teacher> list = teacherMapper.queryTeacherPositionResultMap();
		
		System.out.println(list);
		
		Teacher teacher = teacherMapper.queryTeacherPositionResultMapById(1);
		System.out.println(teacher);
	}
}

一对多:职位对老师

PositionMapper.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.mapper.PositionMapper"> 
	<resultMap type="Position" id="positionTeacherResultMap">
		<id property="id" column="id"/>
		<result property="name" column="t_pos_name"/> <!-- t_name -->
		<!-- 
		property同association中的一样是属性名称(javaBean中的);
		javaType也同association中的是类型,
		最后多了一个OfType,因为一对多,不像一对一是单个的!我们这里是List集合,list和List都可以。
		一对多其中是放的一个集合所以这个是集合的泛型的类型,这里我们的list中放的是Teacher:
		所以这里是Teacher。
		 -->
		<collection property="teacherList" javaType="list" ofType="Teacher" >
			<!-- 
				一对多出现的问题:
					当数据库表中,主表的主键id和明细表的 ...
					当表中的字段名相同时怎么办?多表联查?
					
					注意:Mybatis中做多表联查的时候,不管是
					一对一、一对多、一对多对多:多对多:
					都不能有字段重名的情况:不管是主键还是普通字段。
					一旦字段重名的话,就会造成数据少自动赋值,或者覆盖,甚至重复赋值!
					规避和解决此类问题的方法:
						1.尽量不要表间重名,mybatis里处理起来很麻烦!id和普通字段都是。
						但是在表多的时候,很难不会出现字段重名的情况。主键id最容易重名!
						那么就要用以下的办法了!
						
						2.在mybatis中写原生SQL进行查询的时候,查的字段尽可能的少,这
						也影响速率,强烈禁止使用*,用多少查多少!这样也能及时发现字段重
						名的情况!
						
						3.最后如果真的需要查出重名的字段,并且修改数据库字段名造成的更改
						过大,这里推荐的方式是给字段取别名,在写resultMap映射的时候,其
						中的column属性就填写SQL语句中查出字段取的别名,这样就能解决重复
						问题了!
			 -->
			<id property="id" column="t_id"/>
			<result property="no" column="t_no"/>
			<result property="name" column="t_name"/>	
		</collection>
	</resultMap>
	
	<select id="queryPositionTeacherResultMapById" resultMap="positionTeacherResultMap" 
		parameterType="Integer">
		<!-- 
		SELECT *
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		WHERE p.id = #{id}
		-->
		
		SELECT 
		p.*, 
		t.id t_id,
		t.t_name,
		t.t_no
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		WHERE p.id = #{id}
	</select>
	
	<select id="queryPositionTeacherResultMap" resultMap="positionTeacherResultMap" >
		<!-- 
		SELECT *
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		-->
		
		SELECT 
		p.*, 
		t.id t_id,
		t.t_name,
		t.t_no
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		
	</select>
</mapper>

TeacherMapper.java接口

package com.mapper;
 
import java.util.List;
 
import com.pojo.Position;
 
public interface PositionMapper {
	public Position queryPositionTeacherResultMapById(Integer id);
	
	public List<Position> queryPositionTeacherResultMap();
}

测试一对多:

package com.test;
 
import java.util.List;
 
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
 
import com.mapper.PositionMapper;
import com.pojo.Position;
import com.util.MyBatisUtil;
 
public class TestOneToMany {
	
	@Test
	public void testOneToMany() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		PositionMapper positionMapper = sqlSession.getMapper(PositionMapper.class);
		List<Position> list = positionMapper.queryPositionTeacherResultMap();
		
		System.out.println(list);
		
		Position pos = positionMapper.queryPositionTeacherResultMapById(1);
		
		System.out.println(pos);
	}
}

多对多:职位是教授的老师教授的所有学生(一对多对多:只要你愿意可以一直对多下去…)

PositionMapper.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.mapper.PositionMapper"> 
	<resultMap type="Position" id="positionStudentResultMap">
		<!-- <id property="id" column="id"/> -->
		<result property="name" column="t_pos_name"/>
		<collection property="teacherList" javaType="list" ofType="Teacher" >
			<result property="name" column="t_name"/>	
			<collection property="studentList" javaType="list" ofType="Student">
				<result property="name" column="t_stu_name"/>
			</collection>
		</collection>
	</resultMap>
	
	<select id="selectPositionStudentByPosId" resultMap="positionStudentResultMap" parameterType="Integer">
		SELECT p.t_pos_name, t.t_name, s.t_stu_name
		FROM tb_position p
		INNER JOIN tb_teacher t ON p.id = t.position_id
		LEFT JOIN tb_stu_teach st ON st.t_teach_id = t.id
		LEFT JOIN tb_student s ON s.id = st.t_stu_id
		WHERE p.id = #{id}
	</select>
</mapper>

PositionMapper.java接口

    package com.mapper;
     
    import com.pojo.Position;
     
    public interface PositionMapper {
    	public Position selectPositionStudentByPosId(Integer id);
    	
    }

测试:

package com.test;
 
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
 
import com.mapper.PositionMapper;
import com.pojo.Position;
import com.util.MyBatisUtil;
 
public class TestManyToMany {
	
	@Test
	public void testManyToMany() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		PositionMapper positionMapper = sqlSession.getMapper(PositionMapper.class);
		Position pos = positionMapper.selectPositionStudentByPosId(1);
		
		System.out.println(pos);
	}
}

如本文“对您有用”,欢迎随意打赏作者,让我们坚持创作!

0 打赏
Enamiĝu al vi
不要为明天忧虑.因为明天自有明天的忧虑.一天的难处一天当就够了。
543文章 68评论 292点赞 582208浏览

随机文章
PGSQL—格式化时间的函数
5年前
MyBatis笔记7——typeAliases
5年前
Kotlin-函数进阶—高阶函数(十五)
4年前
Kotlin-协程(专)—协程调度(三十四)
4年前
SpringBoot—MyBatis整合多数据源
5年前
博客统计
  • 日志总数:543 篇
  • 评论数目:68 条
  • 建站日期:2020-03-06
  • 运行天数:1904 天
  • 标签总数:23 个
  • 最后更新:2024-12-20
Copyright © 2025 网站备案号: 浙ICP备20017730号 身体没有灵魂是死的,信心没有行为也是死的。
主页
页面
  • 归档
  • 摘要
  • 杂图
  • 问题随笔
博主
Enamiĝu al vi
Enamiĝu al vi 管理员
To be, or not to be
543 文章 68 评论 582208 浏览
测试
测试
看板娘
赞赏作者

请通过微信、支付宝 APP 扫一扫

感谢您对作者的支持!

 支付宝 微信支付