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

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

这里则产生了:

一对一关系,从老师角度:老师对职位一对一

一对多关系,从职位角度:职位对老师一对多

多对多关系:查找被教授教导的所有学生(首先职位对老师一对多,老师再对学生再对多、这里便有了一对多对多)

数据表:

老师表

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中的目录结构如下:

希望您明白sqlMapConfig该如何配置,以及jdbc.properties和log4j的作用。

贴出POJO中的三个实体(注意:以下的POJO都用了lombok来快速生成setter和getter等,lomok具体使用,请见此文):

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也不用写在实体中(一般我们也不使用外键)

再贴另一个MybatisUtil.java工具类

package com.util;

import java.io.IOException;
import java.io.InputStream; import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory = null; static {
String resource = "sqlMapConfig.xml";
// 首先要加载核心配置文件:从classpath下开始找。
InputStream in;
try {
in = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
}
} public static SqlSession getSqlSession() { return sqlSessionFactory.openSession();
} public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}

一对一:老师对职位

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);
}
}

Mybatis一对一、一对多、多对多查询。+MYSQL的更多相关文章

  1. mybatis 一对一 一对多 多对多

    一对一 一对多 多对多

  2. Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作

    Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作,单表查询,多表查询 一丶表与表之间的关系 背景: ​ ​ ​  ​ ​ 由于如果只使用一张表存储所有的数据,就会操作数 ...

  3. Mybatis 多表实现多对一查询、添加操作

    Mybatis 多表实现多对一查询.添加操作 学习内容: 1. 多对一之添加操作 1.1.需求 1.2.数据库表(多对一或一对多,数据库外键都是设置在多的一方) 1.3.类设计 1.4.Mapper ...

  4. JPA级联(一对一 一对多 多对多)注解【实际项目中摘取的】并非自己实际应用

    下面把项目中的用户类中有个:一对一  一对多  多对多的注解对应关系列取出来用于学习      说明:项目运行正常 问题类:一对多.一对一.多对多 ============一对多 一方的设置 @One ...

  5. Mybatis 多表实现多对多查询、添加操作

    Mybatis 多表实现多对多查询.添加操作 学习内容: 1. 多对多之添加操作 1.1.需求 1.2.数据库表(多对多数据库设计需要设计中间表) 1.3.类设计 1.4.Mapper 接口和 Map ...

  6. day 69-70 一对一 一对多 多对一联表查询

    day 69 orm操作之表关系,多对多,多对一 多对一/一对多, 多对多{类中的定义方法} day69 1. 昨日内容回顾 1. 单表增删改查 2. 单表查询API 返回QuerySet对象的: 1 ...

  7. Django ORM 一对一,一对多,多对多, 添加,批量插入和查询

    模型类 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_ ...

  8. JPA 一对一 一对多 多对一 多对多配置

    1 JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...

  9. JAVA日记之mybatis-3一对一,一对多,多对多xml与注解配置

    1.Mybatis多表查询1.1 一对一查询1.1.1 一对一查询的模型用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的 ...

  10. 使用NHibernate(7)-- 一对一 && 一对多 && 多对多

    1, 一对一. 对于数据量比较大的时候,考虑查询的性能,肯能会把一个对象的属性分到两个表中存放:比如用户和用户资料,经常使用的一般是Id和用户名,用户资料(学校,籍贯等)是不经常被查询的,所以就会分成 ...

随机推荐

  1. 基于IDEA的JAVA开发[第一集]:在Linux上安装IDEA

    1,因为买了荣耀的magicbook pro 锐龙版,系统是Linux,以后打算直接在Linux上开发.本来熟悉Myeclipse,下载了Myeclipse2017 for Linux,但是安装中出现 ...

  2. mybatis-4-Mapper映射文件

    Mapper映射文件 映射文件的Mapper标签包含标签 1.CDUS增删改查 2.参数处理 (1)直接传入参数 单个参数 //传入当个参数 public Employee getEmployeeBy ...

  3. virtualbox结合nat和host-only设置固定ip的环境

    需求 平时在做一些实验或学习的时候,比如rocketmq.kafaka.zookeeper等,需要在虚拟机上创建几个虚拟机组成集群来做实验:一般有两个要求: 虚拟机能访问网络,需要下载安装东西 虚拟机 ...

  4. .net core工具组件系列之Redis—— 第一篇:Windows环境配置Redis(5.x以上版本)以及部署为Windows服务

    Cygwin工具编译Redis Redis6.x版本是未编译版本(官方很调皮,所以没办法,咱只好帮他们编译一下了),所以咱们先下载一个Cygwin,用它来对Redis进行编译. Cygwin下载地址: ...

  5. PAT乙级:1053 住房空置率 (20分)

    PAT乙级:1053 住房空置率 (20分) 题干 在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给 ...

  6. 如何访问网络损伤仪WANsim的控制界面

    一台全新的WANsim网络损伤仪的默认IP地址为192.168.1.199.网络损伤仪的控制界面部署在 8080 端口. 所以,我们在成功连接了WANsim之后,只需要在控制电脑上打开谷歌浏览器,访问 ...

  7. 【Azure Developer】【Python 】使用 azure.identity 和 azure.common.credentials 获取Azure AD的Access Token的两种方式

    问题描述 使用Python代码,展示如何从Azure AD 中获取目标资源的 Access Token. 如要了解如何从AAD中获取 client id,client secret,tenant id ...

  8. 第十篇 -- 下拉列表框QComboBox

    效果图: ui_ComboBox.py # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'ui ...

  9. Fast Run:提高 MegEngine 模型推理性能的神奇功能

    作者:王博文 | 旷视 MegEngine 架构师 一.背景 对于深度学习框架来说,网络的训练/推理时间是用户非常看中的.在实际生产条件下,用户设计的 NN 网络是千差万别,即使是同一类数学计算,参数 ...

  10. 过渡——transition

    ① 设置参与过渡的属性 transition-property:  ;      all / transform / 参与过渡的属性 ② 设置过渡的时长 transition-duration:  s ...