Mybatis处理复杂查询环境

news2025/1/9 2:32:51

复杂查询环境

多对一和一对多

多个工作者对应一个协调人

对于工作者(worker)而言,多个工作者关联一个协调人(coordinator)(多对一,关联)
对于协调人而言,一个协调人有很多工作者(一对多,集合)
在程序开发中,也会遇到类似的情况,这时就会涉及到Mybatis中结果映射的associationcollection

实例

创建数据表

coordinator表

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

INSERT INTO coordinator(`id`, `name`) VALUES(1, "Alex");

worker表

CREATE TABLE `worker`(
	`id` INT(10) NOT NULL,
    `name` VARCHAR(30) DEFAULT NULL,
    `cid` INT(10) DEFAULT NULL,
    PRIMARY KEY (`id`),
    FOREIGN KEY (`cid`) REFERENCES `coordinator` (`id`) 
)ENGINE = INNODB DEFAULT CHARSET=utf8mb4;

INSERT INTO `worker` (`id`, `name`, `cid`) VALUES (1, '小明', '1');
INSERT INTO `worker` (`id`, `name`, `cid`) VALUES (2, '小红', '1');
INSERT INTO `worker` (`id`, `name`, `cid`) VALUES (3, '小方', '1');
INSERT INTO `worker` (`id`, `name`, `cid`) VALUES (4, '小芳', '1');
INSERT INTO `worker` (`id`, `name`, `cid`) VALUES (5, '小王', '1');

环境搭建

创建核心配置文件(mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="db.properties"/>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <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>
</configuration>

创建配置文件(db.properties)

username = root
password = root
url = jdbc:mysql://localhost:3306/mybatis
driver = com.mysql.cj.jdbc.Driver

创建工具类(MybatisUtil)

public class MybatisUtil {
    private  static SqlSessionFactory sqlSessionFactory;
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
             sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

文件准备

①导入相关依赖

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.13</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.16</version>
</dependency>
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.28</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

②新建实体类

Coordinator类

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

Worker类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Worker {
    private int id;
    private String name;
    //工作者需要关联协调人
    private Coordinator coordinator;
}

③创建Mapper接口

CoordinatorMapper

public interface CoordinatorMapper {
    @Select("select * from coordinator where id = #{cid}")
    Coordinator select(@Param("cid") int id);
}

WorkerMapper

public interface WokerMapper {
}

④创建Mapper.xml

CoordinatorMapper.xml

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

</mapper>

WorkerMapper.xml

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

</mapper>

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

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="db.properties"/>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
    <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.louis.dao.CoordinatorMapper"/>
        <mapper class="com.louis.dao.WokerMapper"/>
    </mappers>
</configuration>

⑥测试是否成功

public class MyTest {
    static Logger logger = Logger.getLogger(MyTest.class);
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        CoordinatorMapper mapper = sqlSession.getMapper(CoordinatorMapper.class);
        Coordinator select = mapper.select(1);
        logger.info(select);
        sqlSession.close();
    }
}
//注意导入Logger为:import org.apache.log4j.Logger;

在这里插入图片描述

特别提醒:以上只是为了测试配置文件是否正确。

多对一处理

WorkerMapper接口

public interface WorkerMapper {
    //查询所有的工作人员和它们对应的协调人的信息
    List<Worker> getWorker2();
    List<Worker> getWorker();
}

方式一(按照查询嵌套处理)

WorkerMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.louis.dao.WorkerMapper">
        <!--<select id="getWorker" resultType="com.louis.pojo.Worker">-->
                <!--
                思路:
                1、查询所有的工作人员信息
                2、根据查询出来的工作人员的cid,寻找对应的协调人
                -->
                <!--select w.id, w.name, 
					c.name from worker as w, 
					coordinator as c 
					where w.tid = c.id;-->
                <!--select * from worker;-->
        <!--</select>-->
        <select id="getWorker" resultMap="WorkerCoordinator">
                select * from worker;
        </select>
        <resultMap id="WorkerCoordinator" type="com.louis.pojo.Worker">
            	<!--column 数据库中的字段, property实体类中的属性-->
                <result property="id" column="id"/>
                <result property="name" column="name"/>
                <!--复杂的属性我们需要单独做处理 对象使用association 集合使用collection-->
                <association property="coordinator" column="cid" javaType="com.louis.pojo.Coordinator" select="getCoordinator"/>
        </resultMap>
        <select id="getCoordinator" resultType="com.louis.pojo.Coordinator">
                select * from coordinator where id = #{id};
        </select>
</mapper>

测试

@Test
public void getWorker(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
    List<Worker> worker = mapper.getWorker();
    System.out.println("worker = " + worker);
    sqlSession.close();
}
//结果
worker = [Worker(id=1, name=小明, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=2, name=小红, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=3, name=小方, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=4, name=小芳, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=5, name=小王, coordinator=Coordinator(id=1, name=Alex))]

方式二(按照结果嵌套处理)

WorkerMapper.xml

<!--
方式二:按照结果嵌套处理
思路:
   1、查询所有的工作人员信息
   2、根据查询出来的工作人员的cid,寻找对应的协调人
-->
<select id="getWorker2" resultMap="WorkerCoordinator02">
        <!--使用我们常用的查询语句,并且相应的给一些别名-->
        select w.id as wid, w.name as wname, c.name as cname
        from worker as w, coordinator as c
        where w.cid = c.id;
</select>
<resultMap id="WorkerCoordinator02" type="com.louis.pojo.Worker">
        <result property="id" column="wid"/>
        <result property="name" column="wname"/>
        <association property="coordinator" javaType="com.louis.pojo.Coordinator">
                <result property="name" column="cname"/>
        </association>
</resultMap>

测试

@Test
public void getWorker2(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    WorkerMapper mapper = sqlSession.getMapper(WorkerMapper.class);
    List<Worker> worker = mapper.getWorker2();
    System.out.println("worker = " + worker);
    sqlSession.close();
}
//结果 
worker = [Worker(id=1, name=小明, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=2, name=小红, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=3, name=小方, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=4, name=小芳, coordinator=Coordinator(id=1, name=Alex)), 
Worker(id=5, name=小王, coordinator=Coordinator(id=1, name=Alex))]

一对多处理

比如一个协调人对应多个工作人员,对于协调人而言,就是一对多的关系,除了实体类外和多对一的环境相同。

实体类

Worker

public class Worker {
    private int id;
    private String name;
    private int cid;
}

Coordinator

public class Coordinator {
    private int id;
    private String name;
    //一个协调人协调多个工作人员
    private List<Worker> worker;
}

CoordinatorMapper接口

public interface CoordinatorMapper {
    //获取指定协调人下的所有工作人员和协调人的信息
    Coordinator getCoordinatorTarget(@Param("cid") int cid);
    Coordinator getCoordinatorTarget01(@Param("id") int id);
}

方式一(按照查询嵌套处理)

CoordinatorMapper.xml

<!--按查询嵌套处理-->
<select id="getCoordinatorTarget01" resultMap="CoordinatorWorker01">
    select * from mybatis.coordinator where id = #{id}
</select>
<resultMap id="CoordinatorWorker01" type="com.louis.entity.Coordinator">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <collection property="worker" javaType="ArrayList" ofType="com.louis.entity.Worker" select="getWorkerById" column="id"/>
</resultMap>
<select id="getWorkerById" resultType="com.louis.entity.Worker">
    select * from worker where cid = #{id}
</select>

测试

@Test
public void myTest01(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    CoordinatorMapper mapper = sqlSession.getMapper(CoordinatorMapper.class);
    Coordinator coordinatorTarget = mapper.getCoordinatorTarget(1);
    System.out.println("coordinatorTarget = " + coordinatorTarget);
    sqlSession.close();
coordinatorTarget = Coordinator(id=1, name=Alex, 
	worker=[Worker(id=1, name=小明, cid=0),
			Worker(id=2, name=小红, cid=0),
			Worker(id=3, name=小方, cid=0),
			Worker(id=4, name=小芳, cid=0),
			Worker(id=5, name=小王, cid=0)])

方式二(按照结果嵌套处理)

CoordinatorMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.louis.dao.CoordinatorMapper">
<!--按结果嵌套查询-->
    <select id="getCoordinatorTarget" resultMap="CoordinatorWorker">
        select c.id, c.`name`, w.id as wid, w.`name`as wname
        from coordinator as c, worker as w
        where c.id = w.cid and c.id = #{cid}
    </select>
    <resultMap id="CoordinatorWorker" type="com.louis.entity.Coordinator">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--复杂的属性我们需要单独做处理 对象使用association 集合使用collection
        javaType=""指定属性的类型,集合中泛型信息我们需要使用的是ofType
        -->
        <collection property="worker" ofType="com.louis.entity.Worker">
            <result property="id" column="wid"/>
            <result property="name" column="wname"/>
        </collection>
    </resultMap>
</mapper>

测试

@Test
public void myTest02(){
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    CoordinatorMapper mapper = sqlSession.getMapper(CoordinatorMapper.class);
    Coordinator coordinator = mapper.getCoordinatorTarget01(1);
    System.out.println("coordinator = " + coordinator);
    sqlSession.close();
//结果
coordinatorTarget = Coordinator(id=1, name=Alex, 
	worker=[Worker(id=1, name=小明, cid=0),
 			Worker(id=2, name=小红, cid=0),
			Worker(id=3, name=小方, cid=0),
 			Worker(id=4, name=小芳, cid=0),
 			Worker(id=5, name=小王, cid=0)])

注意:使用association用于(多对一) 和collection用于(一对多),此外

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

ofType用来指定映射到List或集合中的pojo类型,泛型中的约束类型。如:List<worker>

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

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

相关文章

SQL Server表分区

什么是表分区 一般情况下&#xff0c;我们建立数据库表时&#xff0c;表数据都存放在一个文件里。 但是如果是分区表的话&#xff0c;表数据就会按照你指定的规则分放到不同的文件里&#xff0c;把一个大的数据文件拆分为多个小文件&#xff0c;还可以把这些小文件放在不同的…

jvm自带故障处理工具之jmap

jmap是java虚拟机自带的一种内存映像工具。 一般通过jmap可以生成堆的当前使用情况的快照&#xff0c;然后用它来分析或者调优JVM内存使用。 jmap -help jmap -histo:live pid 打印堆的直方图。对于每个Java类&#xff0c;将打印对象数&#xff0c;以字节为单位的内存大小以…

ROS:API操作

目录 一、初始化1.1C版1.2Python版 二、话题与服务相关对象2.1发布对象2.1.1C版2.1.2Python版 2.2订阅对象2.2.1C版2.2.2Python版 2.3服务对象2.3.1C版2.3.2Python版 2.4客户端对象2.4.1C版2.4.2Python版 三、回旋函数3.1C版3.1.1spinOnce()3.1.2spin()3.1.3二者比较 3.2Python…

安装Spark

安装Spark 任务描述 本关任务&#xff1a;完成Spark安装。 相关知识 Apache Spark 是一个新兴的大数据处理通用引擎&#xff0c;提供了分布式的内存抽象。Spark 最大的特点就是快&#xff0c;可比 Hadoop MapReduce 的处理速度快 100 倍。本节将详细说明 Spark 的安装。 下…

C++STL算法之堆算法

堆算法 堆堆算法函数堆算法函数的使用make_heappush_heappop_heapsort_heap 堆 堆就是如图&#xff0c;像这样一种连续的数据&#xff0c;但是注意0的位置不存储数据&#xff0c;目的是为了让编号一置 这里介绍两个概念 大顶堆&#xff1a; 一段内存在二叉数的基础上有序&#…

原生 js (前后端不分离)复选框动态控制表格列的显示隐藏 存储状态

写个div 绑定点击事件 点击设置按钮 让div和复选框显示 <div class"control" οnclick"controlClk()">❁</div> init()// var storeCheckbox window.sessionStorage.getItem(storeCheckbox);function getStore(name) {var storeCheckbox win…

趣谈MySQL 多个%等模糊查询

一、建表并插入数据 1、创建一个people表 DROP TABLE IF EXISTS people; CREATE TABLE people (id int NOT NULL COMMENT 主键,name varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 姓名,sex tinyint NOT NULL COMMENT 性别,age int NOT N…

怎样优雅地增删查改(一):从0开始搭建Volo.Abp项目

软件系统中数据库或者持久层的基本操作功能可以用Curd描述&#xff0c;Curd即 增加&#xff08;Create&#xff09;、更新&#xff08;Update&#xff09;、读取查询&#xff08;Retrieve&#xff09;和删除&#xff08;Delete&#xff09;&#xff0c; 这4个单词的首字母。 在…

Elasticsearch(2)——映射关系

1 什么是映射 映射&#xff08;mapping&#xff09;就像数据库中的 Schema &#xff0c;描述了文档可能具有的字段或属性、每个字段的 数据类型&#xff0c;比如 Text&#xff0c;Keyword&#xff0c;Integer 或 Date &#xff0c;以及 Lucene 是如何索引和存储这些字 段的。 …

VS Code安装及配置教程(Windows)

VS Code安装教程&#xff08;Windows&#xff09; 一、下载1、官网下载&#xff1a;2、网盘下载 二、安装 一、下载 1、官网下载&#xff1a; 点击跳转 2、网盘下载 点击跳转 二、安装 双击运行程序&#xff0c;进行安装&#xff0c;同意许可&#xff0c;点击下一步 选择…

轻松拿捏Jenkins(Linux)+Java11+Docker自动化打包部署

注&#xff1a;本文由笔者小白亲手实践写作&#xff0c;涵盖较全&#xff0c;创作不易&#xff0c;且行且珍惜&#xff01;&#xff01; 历时24小时&#xff0c;包含Jenkins环境构建部署过程中的99%问题&#xff0c;确定不来看一下吗&#xff1f; 文章目录 开篇一、软件包准备J…

华为OD机试真题 Python 实现【任务总执行时长】【2023Q1 100分】

目录 一、题目描述二、输入描述三、输出描述四、补充说明五、解题思路六、Python算法源码七、效果展示1、输入2、输出3、说明 一、题目描述 任务编排服务负责对任务进行组合调度。 参与编排的任务有两种类型&#xff0c;其中一种执行时长为taskA&#xff0c;另一种执行时长为…

Linux项目自动化构建工具——make和makefile

make和makefile 一.基本使用二.make并不是每一次都会进行编译三.原理四.特殊符号 一.基本使用 首先创建一个mycode.c文件&#xff0c;接着使用vim写几行代码。 接着创建一个makefile文件&#xff08;这里的m大写小写均可但需要在当前目录下&#xff09;&#xff0c;并使用vim进…

C语言 - unicode编码与字符串互转

概述 最近项目上需要unicode编码与字符串互转&#xff0c;在此做个笔录。 1、编码环境为 visual studio 21&#xff0c;code如下&#xff1a; #include <stdlib.h> #include <stdio.h> #include <string.h> #include <wchar.h> #include <locale.…

Java SpringBoot集成WebSocket

SpringBoot集成WebSocket 引入依赖WebSocket配置拦截器配置总体配置类WebSocket服务类 控制层测试测试使用在线连接工具&#xff08;自行百度&#xff09;连接地址&#xff1a;ws://IP端口号/websocket测试发送消息测试 公众号&#xff1a;一颗星宇宙 引入依赖 <dependency…

液晶铝薄膜的干蚀特性

引言 对于先进的薄膜晶体管液晶显示器(TFT-LCD)制造工艺来说&#xff0c;薄膜层已逐渐取代传统的湿法蚀刻工艺。对于栅电极&#xff0c;一般使用铝(Al)&#xff0c;在Al中加入一些金属&#xff0c;除了可以保持低电阻率和增强Al薄膜的耐腐蚀性外&#xff0c;还可以防止在后退火…

these parameters are deprecated, see docs for addKeyword

在使用json schema中的自定义关键字时发生该报错&#xff0c;因为直接第一个参数直接传keyname&#xff0c;如下 但是这种方法已经弃用&#xff0c;应该用官方支持的写法&#xff0c;不要直接传keyword,以键值对形式写出来&#xff0c;也有可能是其他书写不规范造成的问题&am…

嵌入式系统移植

一、系统分层 移植的目的 不同架构的处理器指令集不兼容&#xff0c;即便是相同的处理器架构&#xff0c;板卡不同驱动代码也不兼容 Linux是一个通用的内核并不是为某一个特定的处理器架构或板卡设计的&#xff0c;所以从官方获取Linux源码后我们要先经过相应的配置使其与我们当…

企业src-白帽赚钱的合理途径

0、什么是src 安全响应中心&#xff08;Security Response Center&#xff09;&#xff1a;SRC通常是一个组织或者公司设立的部门或团队&#xff0c;负责接收、跟踪和响应安全漏洞报告&#xff0c;以及协调修补措施。SRC与安全研究人员和其他报告者合作&#xff0c;以确保及时…

FastDFS【FastDFS概述(简介、核心概念 、上传机制 、下载机制)】(一)-全面详解(学习总结---从入门到深化)

目录 为什么要使用分布式文件系统 FastDFS概述_简介 FastDFS概述_核心概念 FastDFS概述_上传机制 FastDFS概述_下载机制 为什么要使用分布式文件系统 单机时代 初创时期由于时间紧迫&#xff0c;在各种资源有限的情况下&#xff0c;通常就直接在 项目目录下建立静态文件夹…