Mybatis之resultMap结果集映射

2022-06-22 11:29:31

解决属性名和字段名不一致的问题

在这里插入图片描述
在这里插入图片描述
当实体类中的属性与数据库中的字段名不匹配时,结果不会将数据存入实体类中
在这里插入图片描述
解决方法一:

select*from t_user

将原来的SQL语句改成(起别名):

select id,username,passwordas pwd,gender,regist_timefrom t_user

解决方式二:
通过resultMap结果集映射:
在这里插入图片描述
在这里插入图片描述

<!--    select查询语句--><resultMapid="userMap"type="User"><!--        column表示数据库中的字段,property表示实体类中的属性--><resultcolumn="id"property="id"/><resultcolumn="username"property="username"/><resultcolumn="password"property="pwd"/><resultcolumn="gender"property="gender"/><resultcolumn="regist_time"property="regist_time"/></resultMap><selectid="selectUsers"resultMap="userMap">
        select * from t_user</select>

运行结果:
在这里插入图片描述
注意:对于数据库其他字段和实体类中的属性相一致时,我们可以不必进行一一映射,只需要将对应的字段和属性映射即可

<!--    select查询语句--><resultMapid="userMap"type="User"><!--        column表示数据库中的字段,property表示实体类中的属性--><resultcolumn="password"property="pwd"/></resultMap><selectid="selectUsers"resultMap="userMap">
        select * from t_user</select>

Mybatis多对一查询

使用java实现sql语句

select s.id,s.`name`,t.`name`as 授课老师from`student` s,`teacher` twhere s.tid=t.id

在这里插入图片描述

  1. 数据库设计
CREATETABLE`teacher`(`id`INT(10)NOTNULL,`name`VARCHAR(30)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8INSERTINTO teacher(`id`,`name`)VALUES(1,'陈老师');CREATETABLE`student`(`id`INT(10)NOTNULL,`name`VARCHAR(30)DEFAULTNULL,`tid`INT(10)DEFAULTNULL,PRIMARYKEY(`id`),FOREIGNKEY(`tid`)REFERENCES`teacher`(`id`))ENGINE=INNODBDEFAULTCHARSET=utf8INSERTINTO`student`(`id`,`name`,`tid`)VALUES('1','小明','1');INSERTINTO`student`(`id`,`name`,`tid`)VALUES('2','小红','1');INSERTINTO`student`(`id`,`name`,`tid`)VALUES('3','小张','1');INSERTINTO`student`(`id`,`name`,`tid`)VALUES('4','小李','1');INSERTINTO`student`(`id`,`name`,`tid`)VALUES('5','小王','1');
  1. 建立实体类
    Student类:
@DatapublicclassStudent{//学生的idprivateint id;//学生的名字private String name;//多个学生可以是同一个老师,即多对一private Teacher teacher;}

Teacher类:

@DatapublicclassTeacher{//老师idprivateint id;//老师的名字private String name;}
  1. 编写接口类:
publicinterfaceStudentMapper{//查询学生对应的所有老师
    List<Student>queryStudents();}

按查询嵌套处理

  1. 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"><mappernamespace="dao.StudentMapper"><!--
    需求:获取所有学生及对应老师的信息
    思路:
        1. 获取所有学生的信息
        2. 根据获取的学生信息的老师tid->获取该老师的信息
        3. 思考问题,这样学生的结果集中应该包含老师,该如何处理呢,数据库中我们一般使用关联查询?
            1. 做一个结果集映射resultMap:students
            2. students结果集的类型为 Student
            3. 学生中老师的属性为teacher,对应数据库中为tid。
               多个 [1,...)学生关联一个老师=> 一对一,一对多
            4. 查看官网找到:association 一个复杂类型的关联;使用它来处理关联查询
    --><resultMapid="students"type="Student"><!--association关联属性  property属性名 javaType属性类型 column在多的一方的表中的列名(学生表中的tid)--><associationproperty="teacher"javaType="Teacher"column="tid"select="getTeacher"/></resultMap><selectid="queryStudents"resultMap="students">
        select * from student</select><!--
        这里传递过来的id,只有一个属性的时候,下面可以写任何值
        association中column多参数配置:
            column="{key=value,key=value}"
            其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
            即查询到所有column="tid"的值会传递给下面id作为值查询
        --><selectid="getTeacher"resultType="Teacher">
        select * from teacher where id=#{tid}</select></mapper>
  1. 在Mybatis核心配置文件注册mapper
<!--    注册接口Mapper映射--><mappers><!--        使用class绑定接口--><mapperclass="dao.StudentMapper"/></mappers>
  1. 测试类:
publicclassTest{@org.junit.Testpublicvoidtest(){//通过封装好的工具类获取SqlSession会话
        SqlSession sqlSession= MyBatisUtils.getSqlSession();//通过接口类型class获取接口对象实例(动态代理)
        StudentMapper mapper= sqlSession.getMapper(StudentMapper.class);//执行接口中的方法
        List<Student> students= mapper.queryStudents();for(Student student: students){
            System.out.println(student);}
        sqlSession.commit();//关闭SqlSession
        sqlSession.close();}}
  1. 结果:
    在这里插入图片描述
    按照结果嵌套处理

Mapper.xml配置文件中sql语句:

<resultMapid="students"type="Student"><!--association关联属性  property属性名 javaType属性类型 --><resultproperty="id"column="sid"/><resultproperty="name"column="sname"/><!--        将关联的teacher表中的属性名与被查的列名匹配--><associationproperty="teacher"javaType="Teacher"><resultproperty="name"column="tname"/></association></resultMap><selectid="queryStudents"resultMap="students">
        select s.`id` sid,s.`name` sname,t.`name` tname from `student` s,`teacher` t where s.tid=t.id</select>

结果:

在这里插入图片描述

Mybatis一对多查询

  1. 创建实体类
    Student类
@DatapublicclassStudent{privateint id;private String name;privateint tid;}

Teacher类

@DatapublicclassTeacher{privateint id;private String name;//一个老师对应多个学生private List<Student> students;}
  1. 编写接口类
publicinterfaceTeacherMapper{//通过老师的id查询所有的学生
    TeachergetTeacherById(@Param("id")int id);}

按结果嵌套处理
3. 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"><mappernamespace="dao.TeacherMapper"><!--
    思路:
        1. 从学生表和老师表中查出学生id,学生姓名,老师姓名,老师id
        2. 对查询出来的操作做结果集映射
            1. 集合的话,使用collection!
                JavaType和ofType都是用来指定对象类型的
                JavaType是用来指定pojo中属性的类型
                ofType指定的是映射到list集合属性中pojo的类型。
    --><selectid="getTeacherById"resultMap="TeacherToStudents"parameterType="int">
        select s.id sid,s.`name` sname,s.tid tid,t.`name` tname
        from student s,teacher t where s.tid=t.id and t.id=#{id}</select><resultMapid="TeacherToStudents"type="Teacher"><resultproperty="id"column="tid"/><resultproperty="name"column="tname"/><collectionproperty="students"javaType="ArrayList"ofType="Student"><resultproperty="id"column="sid"/><resultproperty="name"column="sname"/><resultproperty="tid"column="tid"/></collection></resultMap></mapper>
  1. 在mybatis.xml核心配置文件中注册mapper
<!--    注册接口Mapper映射--><mappers><!--        使用class绑定接口--><mapperclass="dao.TeacherMapper"/></mappers>
  1. 测试类:
publicclassTest{@org.junit.Testpublicvoidtest(){//通过封装好的工具类获取SqlSession会话
        SqlSession sqlSession= MyBatisUtils.getSqlSession();//通过接口类型class获取接口对象实例(动态代理)
        TeacherMapper mapper= sqlSession.getMapper(TeacherMapper.class);//执行接口中的方法
        Teacher teacher= mapper.getTeacherById(1);
        System.out.println(teacher);
        sqlSession.commit();//关闭SqlSession
        sqlSession.close();}}
  1. 结果:
    在这里插入图片描述
    按照查询嵌套处理

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"><mappernamespace="dao.TeacherMapper"><!--
    思路:
        1. 从学生表和老师表中查出学生id,学生姓名,老师姓名,老师id
        2. 对查询出来的操作做结果集映射
            1. 集合的话,使用collection!
                JavaType和ofType都是用来指定对象类型的
                JavaType是用来指定pojo中属性的类型
                ofType指定的是映射到list集合属性中pojo的类型。
    --><selectid="getTeacherById"resultMap="TeacherToStudents"parameterType="_int">
        select id,name
        from teacher   where id=#{id}</select><resultMapid="TeacherToStudents"type="Teacher"><resultproperty="id"column="id"/><resultproperty="name"column="name"/><collectionproperty="students"javaType="ArrayList"ofType="Student"select="queryStudentsByUid"column="id"></collection></resultMap><selectid="queryStudentsByUid"resultType="Student">
        select id,name,tid from student where tid=#{id}</select></mapper>

结果:
在这里插入图片描述

注意collection 中的 <result property="" column="" 这里的property和column是相对于主表中的,即getTeacherById中的查询语句,而使用了select进行查询时列字段必须和java实体类字段必须一致,否则不会被赋值其中

在这里插入图片描述

在这里插入图片描述

  • 作者:chenhui_Sun
  • 原文链接:https://blog.csdn.net/weixin_45608165/article/details/113583004
    更新时间:2022-06-22 11:29:31