多对一和一对多

  • 多个学生,对应一个老师
  • 对于学生而言,关联: 多个学生,关联一个老师 [多对一]
  • 对于老师而言,集合: 一个老师,有很多学生 [一对多]

1. 复杂表的构建

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

2. 测试环境搭建

1. 导入Lombok

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

2. 新建实体类

package com.wang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name; //学生需要关联一个老师(物理外键)
private Teacher teacher;
}
package com.wang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
private int id;
private String name;
}

3. 建立Mapper接口

package com.wang.dao;

import com.wang.pojo.Student;

import java.util.List;

public interface StudentMapper {

    //查询所有的学生信息,以及对应的老师的信息
List<Student> getStudentInfo();
}
package com.wang.dao;

import com.wang.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select; public interface TeacherMapper { @Select("select * from teacher where id = #{tid}")
Teacher getTeacher(@Param("tid") int id); }

4. 建立Mapper.xml文件

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

5. 在核心配置文件汇总绑定Mapper接口或者文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration 核心配置文件-->
<configuration> <!--引入外部配置文件,由于此处都在resource目录下,直接写文件名-->
<properties resource="db.properties"/> <!--标准的日志工厂实现-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings> <!--可以给实体类起别名-->
<typeAliases>
<typeAlias type="com.wang.pojo.Teacher" alias="Teacher"/>
</typeAliases> <environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${pwd}"/>
</dataSource>
</environment>
</environments> <mappers>
<mapper resource="com/wang/dao/StudentMapper.xml"/>
<!--由于使用了注解,Teacher要用class关联接口!-->
<mapper class="com.wang.dao.TeacherMapper"/>
</mappers> </configuration>

6. 测试查询是否成功

import com.wang.dao.TeacherMapper;
import com.wang.pojo.Teacher;
import com.wang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test; public class MyTest { @Test
public void TestGetTeacher() {
SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher); sqlSession.close();
}
}

3. 多对一处理

1. 按照查询嵌套处理(子查询)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.wang.dao.StudentMapper"> <!--
思路:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师
-->
<select id="getStudentInfo" resultMap="StudentTeacher">
select * from student;
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性,我们需要单独处理
对象:association
集合:collection
-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap> <select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id};
</select> </mapper>

2. 按照结果嵌套处理(连表查询)

<!--===========================================================-->
<!--按照结果嵌套处理-->
<select id="getStudentInfo2" resultMap="StudentTeacher2">
select s.id as sid, s.name as sname, t.name as tname
from student as s, teacher as t
where s.tid = t.id;
</select> <resultMap id="StudentTeacher2" type="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>

4. 一对多处理

1. 环境搭建,修改实体类

package com.wang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; @Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private int id;
private String name;
private int tid;
}
package com.wang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor; import java.util.List; @Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
private int id;
private String name; //一个老师拥有多个学生
private List<Student> students;
}

2. 按照结果嵌套处理

<!--按结果嵌套查询-->
<select id="getTeacherById" resultMap="TeacherStudent">
select s.id as sid, s.name as sname, t.name as tname, t.id as tid
from student as s
inner join teacher as t
on s.tid = t.id and tid = #{tid};
</select>
<!--复杂的属性,我们需要单独处理
对象: association 集合: collection
JavaType="" 指定属性的类型!
对于集合中的泛型信息,我们使用ofType获取!
-->
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<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>

3. 按照查询嵌套处理

<select id="getTeacherById2" resultMap="TeacherStudent2">
select *
from teacher
where id = #{tid};
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayLi st" ofType="Student" select="getStudentByTeacherId" column="id"/>
</resultMap> <select id="getStudentByTeacherId" resultType="Student">
select *
from student
where tid = #{tid}
</select>

此种方式,用于查询的字段必须显示指定才能正确显示!

两种显式指定的方式:

  1. 在SQL语句中指定
  2. 在结果集映射中使用result标签通过property和column指定

5. 小结

  1. association 关联 多对一
  2. collection 集合 一对多
  3. javaType & ofType
    1. javaType 用来指定实体类中属性的类型
    2. ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型

6. 注意点

  • 保证SQL的可读性,尽量保证通俗易懂
  • 注意一对多和多对一中,属性名和字段的问题!
  • 如果问题不好排查错误,可以使用日志,建议使用Log4j

Mybatis-多对一和一对多的更多相关文章

  1. mybatis多对一与一对多

    步骤: 1.创建maven项目 2.编写工具类 3.编写实体类 4.编写mapper接口 5.配置xml 6.测试 多对一:多个学生关联一个老师 工具类: //sqlSessionFactory -- ...

  2. Mybatis 多对一和一对多 学习总结04

    1.Mybatis 组件的声明周期 ​ 声明周期是组件的重要问题,Mybatis也常用语多线程环境,错误使用会造成多线程并发问题,为正确编写Mybatis应用程序,我们要掌握Mybatis组件的声明周 ...

  3. MyBatis多对一,一对多,多对多,一对多关联查询

    一.Person实体类 1 public class Person { 2 private Integer personId; 3 private String name; 4 private Int ...

  4. java web(六):mybatis之一对一、一对多、多对多映射

    前言: 百度百科: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...

  5. 后端框架的学习----mybatis框架(9、多对一处理和一对多处理)

    9.多对一处理和一对多处理 #多对一 <!--按照结果集嵌套查询--> <select id="getAllStudent1" resultMap="S ...

  6. Java基础-SSM之mybatis多对多关联

    Java基础-SSM之mybatis多对多关联 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.准备测试环境(创建数据库表) 1>.创建teas,stus,links表 u ...

  7. mybatis多对一关联

    mybatis多对一关联查询实现 1.定义实体 定义实体的时候需要注意,若是双向关联,就是说双方的属性中都含有对方对象作为域属性出现, 那么在写toString()方法时需要注意,只让某一方输出即可, ...

  8. Hibernate关联映射(单项多对一和一对多、双向一对多)

    最近总是接触着新的知识点来扩展自己的知识面:不停的让自己在原地接触天空的感觉真的很美好!!!革命没有成功,程序员的我们怎么能不努力呢...... 一.用员工和部门来剖析关联映射的原理. 1)从这张截图 ...

  9. 一步步学习NHibernate(5)——多对一,一对多,懒加载(2)

    请注明转载地址:http://www.cnblogs.com/arhat 通过上一章的学习,我们建立了Student和Clazz之间的关联属性,并从Student(many)的一方查看了Clazz的信 ...

  10. MyBatis多对多查询

    -------------------siwuxie095                                 MyBatis 多对多查询         以订单和商品为例,即 一个订单可 ...

随机推荐

  1. C#开发笔记之02-什么时候使用OnXXX方法,这种命名是什么意思?

    C#开发笔记概述 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/958 访问. 你也许经常会看到别人写的代码里有OnXX ...

  2. 编译原理——求解First,Follow,Firstvt和Lastvt集合

    转载地址 http://dongtq2010.blog.163.com/blog/static/1750224812011520113332714/ 学编译原理的时候,印象最深的莫过于这四个集合了,而 ...

  3. python设计模式之建造者模式

    python设计模式之建造者模式 ​ 建造者模式的适用范围:想要创建一个由多个部分组成的对象,而且它的构成需要一步接一步的完成.只有当各个部分都完成了,这个对象才完整.建造者模式表现为复杂对象的创建与 ...

  4. Disruptor极速队列

    参考:http://www.cnblogs.com/haiq/p/4112689.html Disruptor 是线程内通信框架,用于线程里共享数据.LMAX 创建Disruptor作为可靠消息架构的 ...

  5. 【笔记】springCloud--Alibaba--nacos介绍----启动报错解决方案

    Nacos介绍 · 欢迎来到 Nacos 的世界! · Nacos 致力于帮助您发现.配置和管理微服务.Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现.服务配置.服务元数据及流量管 ...

  6. put数据到topic

    基于python3.6 # -*-coding:utf-8 *- __author__ = 'lc_yy' from pykafka import KafkaClient import logging ...

  7. QT下载速度慢的解决方法

    在官网的下载速度实在太慢了 找到了一个镜像网站 https://mirrors.tuna.tsinghua.edu.cn/qt/archive/qt/

  8. Linux文件权限-笔记

    文件权限共10个字符,第一个字符表示该文件是[文件夹]或[文件]——如果是字符“d"则表示该文件是文件夹:如果是字符“-”则表示是文件. 后九个字符,三个一组,共三组,分别表示[所有者权限] ...

  9. iptables初步接触

    0.iptables命令选项输入顺序:iptables -t 表名 <-A/I/D/R> 规则链名 [规则号] <-i/o 网卡名> -p 协议名 <-s 源IP/源子网 ...

  10. 利用python爬取贝壳网租房信息

    最近准备换房子,在网站上寻找各种房源信息,看得眼花缭乱,于是想着能否将基本信息汇总起来便于查找,便用python将基本信息爬下来放到excel,这样一来就容易搜索了. 1. 利用lxml中的xpath ...