初学Mybatis之多对一查询 association 和一对多查询 collection

news2024/11/17 15:52:09

XML 映射器

多对一:关联(association)

一对多:集合(collection)

mysql 创建教师、学生表,插入数据

create table `teacher`(
	id int(10) primary key,
    `name` varchar(30) default null
) 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',1);
insert into student (id,`name`,tid) values (2,'学生2',1);
insert into student (id,`name`,tid) values (3,'学生3',1);

pom.xml 导入相应 jar 包

  <dependencies>
    <!-- mysql驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.33</version>
    </dependency>

    <!-- mybatis驱动 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.16</version>
    </dependency>

    <!-- junit驱动 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
    </dependency>

    <!-- lombok驱动 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.34</version>
    </dependency>
  </dependencies>

  <!-- 在build中配置resources,防止资源导出失败 -->
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>

      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>

resources 目录下创建 db.properties

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username=root
password=root

resources 目录下创建 mybatis-config.xml

<?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>

    <!-- 引入外部配置文件 -->
    <properties resource="db.properties"/>

    <settings>
        <!-- 日志工厂实现 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!-- 扫描实体类的包 -->
    <typeAliases>
        <package name="com.demo.pojo"/>
    </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="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="com.demo.dao.TeacherMapper"/>
        <mapper class="com.demo.dao.StudentMapper"/>
    </mappers>

</configuration>

MybatisUtils 工具类:

package com.demo.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            //获取sqlSessionFactory对象
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

        /*
        有了SqlSessionFactory,就可以获得SqlSession的实例
        SqlSession提供了在数据库执行SQL命令所需的所有方法
        可以通过SqlSession实例来执行已映射的SQL语句
         */
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession(true);
        }
}

实体类与表字段一致

Teacher 类:

package com.demo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

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

 Student 类:

(因为 tid 设置了外键,直接写 int tid 则无法关联,所以通过组合的方式关联进来)

package com.demo.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;
}

TeacherMapper 接口:

import com.demo.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);
}

 同理,写个 StudentMapper 接口

resources 目录创建同包名

TeacherMapper.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.demo.dao.TeacherMapper">

</mapper>

同理,创建 StudentMapper.xml

在核心配置文件 mybatis-config.xml 绑定注册:

    <mappers>
        <mapper class="com.demo.dao.TeacherMapper"/>
        <mapper class="com.demo.dao.StudentMapper"/>
    </mappers>

测试类:

package com.demo.dao;

import com.demo.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class MyTest {
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        System.out.println(mapper.getTeacher(1));
        sqlSession.close();
    }
}

输出结果:

测试环境搭建步骤:

1.导入 Lombok 依赖

2.新建实体类 Teacher、Student

3.建立 Mapper 接口

4.建立 Mapper.xml 文件

5.在核心配置文件中绑定注册 Mapper 接口或者文件

6.测试查询是否成功

多对一处理:

StudentMapper 实体类:

package com.demo.dao;

import com.demo.pojo.Student;

import java.util.List;

public interface StudentMapper {
    //查询所有学生信息,以及对应教师信息
    List<Student> getStudent();
}

方法一:查找嵌套,根据查询出来的学生 tid,寻找对应的教师

StudentMapper.xml:

关联:association

集合:collection

javaType:对象类型

<?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.demo.dao.StudentMapper">
    <select id="getStudent" resultMap="tid">
        select * from student
    </select>
    <resultMap id="tid" type="student">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <!-- 关联:association -->
        <!-- 集合:collection -->
        <!-- javaType:对象类型 -->
        <association property="teacher" column="tid" javaType="teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="teacher">
        select * from teacher where id = #{tid}
    </select>
</mapper>

association 关联的 property 是 Student 类的组合

 测试类:遍历数组

package com.demo.dao;

import com.demo.pojo.Student;
import com.demo.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class MyTest {
    @Test
    public void getStudent(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> studentList = mapper.getStudent();
        for(Student student : studentList){
            System.out.println(student);
        }
        sqlSession.close();
    }
}

 运行结果如下:

方法二:结果嵌套

StudentMapper.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.demo.dao.StudentMapper">
    <select id="getStudent" resultMap="tid">
        select s.id sid,s.name sname,s.tid stid,t.name tname from student s,teacher t where s.tid = t.id;
    </select>
    <resultMap id="tid" type="Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
            <result property="id" column="stid"/>
        </association>
    </resultMap>
</mapper>

 结果如下:

Mybatis 多对一查询方式:

1.子查询

2.联表查询 

一对多处理:

Student 类:

package com.demo.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;
}

Teacher 类:

package com.demo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String name;
    //一名教师教导多名学生
    private List<Student> students;
}

 TeacherMapper 接口:

package com.demo.dao;

import com.demo.pojo.Teacher;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface TeacherMapper {
    List<Teacher> getTeacher();

    //获取指定教师下所有学生及教师的信息
    Teacher getTeacherById(@Param("tid") int id);
}

TeacherMapper.xml:

方法一:结果嵌套查询

javaType 指定属性的类型,ofType 应用于集合中的泛型信息

<?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.demo.dao.TeacherMapper">

    <select id="getTeacher" resultType="teacher">
        select * from teacher
    </select>

    <!-- 结果嵌套查询 -->
    <!-- resultMap 结果集映射 -->
    <select id="getTeacherById" 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 = #{tid};
    </select>
    <resultMap id="TeacherStudent" type="teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!-- 集合:collection -->
        <!-- javaType指定属性的类型,ofType应用于集合中的泛型信息 -->
        <collection property="students" ofType="student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>
</mapper>

测试类:

package com.demo.dao;

import com.demo.pojo.Teacher;
import com.demo.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class MyTest {
    @Test
    public void getTeacher(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        for (Teacher teacher : mapper.getTeacher()) {
            System.out.println(teacher);
        }
        sqlSession.close();
    }

    @Test
    public void getTeacherById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        System.out.println(mapper.getTeacherById(1));
        sqlSession.close();
    }
}

运行结果:

方法二:查询嵌套

    <select id="getTeacherById" resultMap="TeacherStudent">
        select * from teacher where id = #{tid}
    </select>

    <resultMap id="TeacherStudent" type="teacher">
        <collection property="students" javaType="ArrayList" ofType="student" select="tid" column="id"/>
    </resultMap>

    <select id="tid" resultMap="student">
        select * from student where tid = #{tid}
    </select>

总结:

1.关联:association(多对一)

2.集合:collection(一对多) 

3. javaType 用来指定实体类中属性的类型

4. ofType 用来指定映射到 List 或集合中的 pojo 类型,泛型中的约束类型

注意点:

1.保证 SQL 可读性

2.注意一对多或多对一属性名和字段

3.使用 Log4j 日志排查错误

综上,还需了解 Mysql 引擎、InnoDB 底层原理、索引、索引优化等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1955949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Meta 发布地表最大、最强大模型 Llama 3.1

最近这一两周看到不少互联网公司都已经开始秋招提前批了。不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球友解…

简单几步,把浏览器书签转换成导航网页

废话不多说直奔主题上干货 Step 1 下载浏览器书签 1&#xff0c;电脑浏览器点击下载Pintree Pintree 是一个开源项目&#xff0c;旨在将浏览器书签导出成导航网站。通过简单的几步操作&#xff0c;就可以将你的书签转换成一个美观且易用的导航页面。 2. 安装 Pintree B…

《Java初阶数据结构》----10.<Map和Set---TreeSet和TreeMapHashSet和HashMap >

前言&#xff1a; 大家好&#xff0c;我目前在学习java。我准备利用这个暑假&#xff0c;来复习之前学过的内容&#xff0c;并整理好之前写过的博客进行发布。如果博客中有错误或者没有读懂的地方。热烈欢迎大家在评论区进行讨论&#xff01;&#xff01;&#xff01; 喜欢我文…

高并发内存池(四)Page Cache的框架及内存申请实现

目录 一、Page Cache的框架梳理 二、Page Cache的实现 2.1PageCache.h 2.2VirtualAlloc 2.3std::unordered_map _idSpanMap,> 2.4Page Cache.cpp 一、Page Cache的框架梳理 申请内存&#xff1a; 1. 当central cache向page cache申请内存时&#xff0c;page cache先检…

2024年7月29日 十二生肖 今日运势

小运播报&#xff1a;2024年7月29日&#xff0c;星期一&#xff0c;农历六月廿四 &#xff08;甲辰年辛未月甲午日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;羊、虎、狗 需要注意&#xff1a;兔、牛、鼠 喜神方位&#xff1a;东北方 财神方位&#xff1a;…

论文阅读:Deformable DETR: Deformable Transformers for End-to-End Object Detection

论文阅读&#xff1a;Deformable DETR: Deformable Transformers for End-to-End Object Detection Deformable DETR: 基于稀疏空间采样的注意力机制&#xff0c;让DCN与Transformer一起玩&#xff01; - 知乎 (zhihu.com) 【Deformable DETR 论文源码解读】Deformable Trans…

Linux嵌入书学习—数据结构——栈(seqstak)

一、栈&#xff1b; 定义&#xff1a; 是限定仅在表尾&#xff08;栈顶&#xff09;进行插入和删除操作的线性表 栈又称为 后进先出&#xff08;Last In First Out&#xff09; 的线性表&#xff0c;简称 LIFO 结构 栈顶&#xff08;Top&#xff09; 栈顶是栈中允许进行添加&…

构建大规模账号池与本地部署:GitHub爬虫项目详解

账号池搭建 必要性 常见登录方式&#xff1a; 基于Session Cookie的登录基于JWT的登录&#xff1a;登录生成JWT字符串 账号池存储cookie或者JWT字符串 方便后续发请求爬取数据 本地部署 conda建立一个虚拟环境 conda create -n new_env python3.x # 替换 x 为你需要的 P…

【 C++ 】 类和对象的学习

前言&#xff1a; &#x1f618;我的主页&#xff1a;OMGmyhair-CSDN博客 目录 引言&#xff1a; 一、类的作用域 二、计算类对象的大小 三、this指针 this指针❓1 this指针❓2 this指针❓3 引言&#xff1a; 通过类我们可以对数据和方法进行封装 封装的意义&#xf…

【Android】实现一个优雅的自定义底部导航栏(速通安卓大作业必备)

文章目录 前言一、实现思路二、代码实现流程①修改theme&#xff1a;②在color文件中添加颜色&#xff1a;③添加图标文件④添加选中时布局的背景⑤修改布局文件⑥按钮效果图&#xff1a;⑦修改MainActivity中的代码⑦创建各个界面的Fragment⑧运行结果&#xff1a; 三、 总结 …

【学术会议征稿】第五届人工智能与教育国际学术会议(ICAIE 2024)

第五届人工智能与教育国际学术会议&#xff08;ICAIE 2024&#xff09; 2024 5th International Conference on Artificial Intelligence and Education 第五届人工智能与教育国际学术会议&#xff08;ICAIE 2024&#xff09;由集美大学诚毅学院主办&#xff0c;闽南师范大学…

福昕PDF编辑器v13专业版 授权版

福昕高级PDF编辑器是一款功能强大的PDF文件编辑软件&#xff0c;提供多种实用的编辑功能。 软件截图&#xff1a; 使用说明&#xff1a; 解压后&#xff0c;双击start.bat来运行软件 下载地址&#xff1a;FoxitPDFEditor-Pro-v13 解压密码&#xff1a;helloh 下载时可能会有…

动手学大模型应用开发笔记--用dash开发一个大模型知识库

简介 动手学&#xff0c;把自己学到的东西动手自己做出来并输出&#xff0c;是最好的学习方式。最近一直在关注和使用各种ai工具&#xff0c;也在学一些ai开发的知识&#xff0c;看到datawhale的开源学习教程&#xff0c;动手学大模型开发( [github.com/datawhalech…])这个教…

高频面试题基本总结回顾(含笔试高频算法整理)暂存篇

干货分享&#xff0c;感谢您的阅读&#xff01; &#xff08;暂存篇---后续会删除&#xff0c;完整版和持续更新见高频面试题基本总结回顾&#xff08;含笔试高频算法整理&#xff09;&#xff09; 备注&#xff1a;引用请标注出处&#xff0c;同时存在的问题请在相关博客留言…

dockerfile部署镜像 ->push仓库 ->虚拟机安装建木 ->自动部署化 (详细步骤)

目录 创建私服仓库 vi /etc/docker/daemon.json vim deploy.sh判断脚本内容 创建 建木 后端部署 命名空间 设置密码用户名 创建git仓库 gitignore文件内容 图形项目操作 git maven docker镜像 点击流程日志 vim /etc/docker/daemon.json 执行部署脚本 ip 开发…

代码性能优化(3)——聊聊多线程

代码的性能优化&#xff0c;有些是从逻辑层面进行的&#xff0c;比如同时对50W个人发放奖励&#xff0c;可以改成用户登录的时候&#xff0c;自动领取有没奖励&#xff0c;或者统计每日的每个业务员的销售额和实时累积的销售额&#xff0c;将实时sum函数改成&#xff0c;每一笔…

24种设计模式介绍与6大设计原则(电子版教程)

前言 您是一个初级的 coder,可以从中领会到怎么设计一段优秀的代码&#xff1b;您是一个高级程序员&#xff0c;可以从中全面了解到设计模式以及 Java 的边角技术的使用&#xff1b;您是一个顶级的系统分析师&#xff0c;可以从中获得共鸣&#xff0c;寻找到项目公共问题的解决…

StarRock3.3 安装部署

服务器前置要求&#xff1a; 1、内存>32GB 2、JDK 8 is not supported, please use JDK 11 or 17 1、安装 wget https://releases.starrocks.io/starrocks/StarRocks-3.3.0.tar.gz tar zxvf StarRocks-3.3.0.tar.gz 2、FE服务启动 2.1 配置FE节点(默认配置&#xff0c;…

dns和 openELB

DNS yum -y install bind允许其他的主机来监听&#xff0c;允许其他的主机来查询&#xff0c;改这两个地方就行了。 把需要解析的文件都添加进来&#xff0c;cp -p的意思是保留原来的权限控制 注意本地dns放在 DNS1 二、负载均衡 OpenELB Layer2 模式 BGP模式 OpenELB …

DBeaver使用SQL脚本编辑器

文章目录 1 新建脚本2 选择数据库3 编写脚本【按行执行】参考 1 新建脚本 2 选择数据库 3 编写脚本【按行执行】 光标放到需要执行的行上&#xff0c;点击【最上面的按钮】 或者选中某片代码&#xff0c;然后执行 也可以编写一个脚本然后执行 参考 dbeaver安装和使用教程 …