resultMap如何处理复杂映射问题

2025-04-11 16:50

本文主要是介绍resultMap如何处理复杂映射问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《resultMap如何处理复杂映射问题》:本文主要介绍resultMap如何处理复杂映射问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教...

resultMap复杂映射问题

resultMap如何处理复杂映射问题

  • association:关联(多对一的情况)
  • collection: 集合(一对多的情况)
  • JavaType: 用来指定实体类中属性的类型。
  • ofType: 用来指定映射到List或集合中POJO的类型,泛型的约束类型。

Ⅰ 多对一查询:学生——老师

数据库表:

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

resultMap如何处理复杂映射问题

(1) 创建实体类POJO

@Data
public class Student {
    private int id;
    private String name;
    private Teacher teacher;
}
@Data
public class Teacher {
    private int id;
    private String name;
}

(2) 创建学生实体类对应的接口

public interface StudentMapper {

    //查询所有学生的信息
    List<Student> getStudent();
    List<Student> getStudent2();
}

(3) 编写学生接口对应的Mapper.XML

为了达到和接口在同一个包中的效果,在resource文件夹下新建包结构com.glp.dao:

resultMap如何处理复杂映射问题

<?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.glp.dao.StudentMapper">

<!--按照结果查询——联表查询-->
    <select id="getStudent2" resultMap="StudentMap2">
         select s.id sid,s.name sname,t.name tname from student s, teacher t where s.tid=t.id;
    </select>

    <resultMap id="StudentMap2" type="Student">
         <result property="id" column="sid"/>
         <result property="name" column="sname"/>

        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>


    <!--按照查询嵌套处理——子查询-->
        <select id="getStudent" resultMap="StudentMap" >
           select * from student;
     php   </select>

    <resultMap id="StudentMap" 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 teapythoncher where id = #{id};
        </select>

</mapper>

在多对一查询中,需要用到teacher这个表,每个学生都对应着一个老师。而property只能处理单个属性,像teacher这种复杂属性(内含多个属性)需要进行处理。处理复杂对象要用association 。

方式一:

  • 联表查询(直接查出所有信息,再对结果进行处理)
   <resultMap id="StudentMap2" type="Student">
         <result property="id" column="sid"/>
         <result property="name" column="sname"/>

        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

直接查询出学生和老师,然后用association去取老师里面的属性property。

方式二:

  • 子查询(先查出学生信息,再拿着学生中的tid,去查询老师的信息)
  <resultMap id="StudentMap" type="Student">
        <result property="id" column="id"/>http://www.chinasem.cn
        <result property="name" column="name"/>
        <!--复杂属性:对象association-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>
        
        <select id="getTeacher" resultType="Teacher">
            select * from teacher where id = #{id};
        </select>

在resultMap中引入属性association,通过javaType指定property="teacher"的类型,javaType="Teacher"。通过select引入子查询(嵌套查询)。

resultMap如何处理复杂映射问题

这里是拿到学生中的tid,去查找对应的老师。

(4)在核心配置类中引入Mapper

db.properties:数据库连接参数配置文件

driver = com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&chracterEncoding=utf8
username =root
password =mysql

mybatis.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>


    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="mysql"/>
    </properties>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <typeAlias type="com.glp.POJO.Student" alias="Student"/>
        <typeAlias type="com.glp.POJO.Teacher" alias="Teacher"/>
    </typeAliases>


    <environments default="development">

        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" valwww.chinasem.cnue="${driver}"/>
                <property name="url" value="${url}}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>

    </environments>

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

</configuration>

注意:

要保证接口和Mapper.xml都在同一个包中。

(5) 测试

public class UserDaoTest {
    @Test
    public void getStudent(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> list = mapper.getStudent();

        for (Student stu:list ) {
            System.out.println(stu);
        }
        sqlSession.close();
    }

    @Test
    public void getStudent2(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        List<Student> list = mapper.getStudent2();

        for (Student stu:list ) {
            System.out.println(stu);
        }
        sqlSession.close();
    }
}

Ⅱ 一对多查询:老师——学生

resultMap如何处理复杂映射问题

(1)实体类

@Data
public class Student {
    private int id;
    private String name;
    private int tid;
}
@Data
public class Teacher {
    private int id;
    private String name;
    private List<Student> students;
}

(2) 接口

package com.glp.dao;

public interface TeacherMapper {

    Teacher getTeacher(@Param("tid") int id);

    Teacher getTeacher2(@Param("tid") int id);
}

(3)接js口对应的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.glp.dao.TeacherMapper">

  <!--方式一          =======================                  -->
    <select id="getTeacher" 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 property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>


    <!--方式二          =======================                  -->

    <select id="getTeacher2" resultMap="TeacherStudent2">
        select * from teacher where id = #{tid};
         <!--这里的tid和接口中指定的属性名相同-->
    </select>

    <resultMap id="TeacherStudent2" type="Teacher">
	    <result property="id" column="id"/>
        <result property="name" column="name"/>
           <!--上面的两个可以省略-->
        <collection property="students"  column="id" javaType="ArrayList" ofType="Student"  select="getStuById"/>
    </resultMap>

    <select id="getStuById" resultType="Student">
        select * from student where tid=#{tid};
           <!--查询老师对应的学生,#{tid}-->
    </select>
</mapper>

方式一:

  • 联表查询,需要写复杂SQL
  • collection 用来处理集合,ofType用来指定集合中的约束类型
  • 联合查询时,查询出所以结果,然后再解析结果中的属性,将属性property赋予到collection中。

方式二:

  • 子查询,需要写复杂映射关系

resultMap如何处理复杂映射问题

resultMap如何处理复杂映射问题

查询学生时,需要拿着老师的id去查找,column用来给出老师的id。

(4)测试:

package com.glp.dao;
public class UserDaoTest {

    @Test
    public void getTeacher(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);

        Teacher teacher = mapper.getTeacher(1);

        System.out.println(teacher);

        sqlSession.close();
    }


    @Test
    public void getTeacher2(){
        SqlSession sqlSession = MyUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);

        Teacher teacher = mapper.getTeacher2(1);

        System.out.println(teacher);

        sqlSession.close();
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。

这篇关于resultMap如何处理复杂映射问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154183

相关文章

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

MyBatis模糊查询报错:ParserException: not supported.pos 问题解决

《MyBatis模糊查询报错:ParserException:notsupported.pos问题解决》本文主要介绍了MyBatis模糊查询报错:ParserException:notsuppo... 目录问题描述问题根源错误SQL解析逻辑深层原因分析三种解决方案方案一:使用CONCAT函数(推荐)方案二:

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

Spring 中的循环引用问题解决方法

《Spring中的循环引用问题解决方法》:本文主要介绍Spring中的循环引用问题解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录什么是循环引用?循环依赖三级缓存解决循环依赖二级缓存三级缓存本章来聊聊Spring 中的循环引用问题该如何解决。这里聊

Spring Boot中JSON数值溢出问题从报错到优雅解决办法

《SpringBoot中JSON数值溢出问题从报错到优雅解决办法》:本文主要介绍SpringBoot中JSON数值溢出问题从报错到优雅的解决办法,通过修改字段类型为Long、添加全局异常处理和... 目录一、问题背景:为什么我的接口突然报错了?二、为什么会发生这个错误?1. Java 数据类型的“容量”限制

关于MongoDB图片URL存储异常问题以及解决

《关于MongoDB图片URL存储异常问题以及解决》:本文主要介绍关于MongoDB图片URL存储异常问题以及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录MongoDB图片URL存储异常问题项目场景问题描述原因分析解决方案预防措施js总结MongoDB图

SpringBoot项目中报错The field screenShot exceeds its maximum permitted size of 1048576 bytes.的问题及解决

《SpringBoot项目中报错ThefieldscreenShotexceedsitsmaximumpermittedsizeof1048576bytes.的问题及解决》这篇文章... 目录项目场景问题描述原因分析解决方案总结项目场景javascript提示:项目相关背景:项目场景:基于Spring