Mybatis---复杂查询(多表查询)

1.ResultMap结果集映射

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

在这里插入图片描述

  • pojo代码:

    package com.it.pojo;
    public class User {
        private int id;
        private String name;
    
    //    此时属性名和数据库表中的字段名字不相同,结果就是查不出pwd的结果
    //    原因:sql=select name,id,pwd from user。
    //    数据库表中名为pwd而映射表中是password
        
        private String password;
    
    }
    

    没处理之前:

在这里插入图片描述

  • 接口实现.xml代码:

    <?xml version="1.0" encoding="UTF-8" ?>
                <!DOCTYPE mapper
                        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        <mapper namespace="edu.xalead.Dao.UserMapper">
            
    <!--    id为你添加的resultMap标签的名字。。type为要映射的类的名字-->
        <resultMap id="UserMap" type="User">
    <!--    column是列的意思,就是对应数据库表中的列的名字,
            property是属性的意思,也就是对应实体类的属性名字。
    -->
            <result column="pwd" property="password"/>
        </resultMap>
    
            
    <!--方法二:添加一个resultMap标签-->
        <select id="getUserById" resultMap="UserMap">
                select * from mybatis.user where id = #{id}
        </select>
         <!--方法一:起一个别名-->
         <!--<select id="getUserById" resultType="User" parameterType="int">
          select id,name,pwd as password from mybatis_test.m_user where id=#{id}
        </select>-->
     </mapper>
    

    结果:

在这里插入图片描述

2.复杂查询

2.1 环境搭建:

添加2张新表和内容

  • CREATE TABLE `student` (
      `id` int(10) NOT NULL,
      `name` varchar(30) DEFAULT NULL,
      `tid` int(10) DEFAULT NULL,
      PRIMARY KEY (`id`),
      KEY `ftkid` (`tid`),
      CONSTRAINT `ftkid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    CREATE TABLE `teacher` (
      `id` int(10) NOT NULL,
      `name` varchar(30) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
  • 导入lombok

  • 新建实体类Teacherm,Student

  • 建立Mapper接口

  • 建立Mapper.Xml文件

  • 在核心配置文件中绑定我们注册的Mapper接口或文件

  • 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>
        <!--引入外部配置文件-->
        <properties resource="db.properties"/>
        <settings>
            <setting name="logImpl" value="LOG4J"/>
        </settings>
        <typeAliases>
            <package name="edu/xalead/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="edu.xalead.dao.TeacherMapper"/>
            <mapper class="edu.xalead.dao.StudentMapper"/>
        </mappers>
    </configuration>
    

2.2 多对一

查询所有学生对应老师的信息

在这里插入图片描述

  • 多个学生,对应一个老师
  • 对于学生这边而言是关联: 多个学生,关联一个老师【多对一】
  • 对于老师而言是集合,一个老师有很多学生【一对多】

方法一(按查询嵌套处理(子查询))

  • StudentMapper代码为:

    package edu.xalead.dao;
    import edu.xalead.pojo.Student;
    import java.util.List;
    
    public interface StudentMapper {
        //查询所有老师和学生的信息
        public List<Student> getStudent();
    }
    
    
  • 实体Student代码为:

    package edu.xalead.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 edu.xalead.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;
    }
    
  • resources.edu.xalead.Dao.StudentMapper.xml代码为:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--namespacce = 绑定一个对应的Dao/Mapper接口 对应之前的实现接口-->
    <mapper namespace="edu.xalead.dao.StudentMapper">
        <!--
         思路:
            1. 查询所有学生的信息
            2. 根据查出来的tid,去找对应的老师
        -->
    <!--方法一-->
        <select id="getStudent" resultMap="studentTeacher">
            select * from mybatis_test.student
        </select>
        <resultMap id="studentTeacher" type="Student">
            <!--复杂属性处理
            对象用association
            -->
            <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
        </resultMap>
    
        <select id="getTeacher" resultType="teacher">
            select * from mybatis_test.teacher where id = #{tid}
        </select>
    </mapper>
    

测试:

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

结果:

在这里插入图片描述

方法二(按结果嵌套处理(关联查询))

  • 其他与方法一相同,修改resources.edu.xalead.Dao.StudentMapper.xml代码为:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--namespacce = 绑定一个对应的Dao/Mapper接口 对应之前的实现接口-->
    <mapper namespace="edu.xalead.dao.StudentMapper">
        <!--
         思路:
            1. 查询所有学生的信息
            2. 根据查出来的tid,去找对应的老师
        -->
    <!--方法二-->
        <select id="getStudent2" resultMap="studentTeacher2">
            select s.id sid,s.name sname,t.name tname
            from student s,teacher 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>
    </mapper>
    

10.3 一对多

通过一个老师查询多个学生,通过老师查询学生的信息同上有两种方法:

方法一二混合

  • 接口StudentMapper为空,TeacherMapper代码:

    package edu.xalead.dao;
    
    import edu.xalead.pojo.Teacher;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    
    import java.util.List;
    
    public interface TeacherMapper {
        //获取指定老师下的所有学生及老师的信息
        public Teacher getTeacher(@Param("tid") int id);
    
        public Teacher getTeacher2(@Param("tid") int id);
    }
    
    
  • pojo.Student代码:

    package edu.xalead.pojo;
    
    import lombok.Data;
    
    @Data
    public class Student {
        private int id;
        private String name;
        private int tid;
    }
    
    
  • pojo.Teacher代码:

    package edu.xalead.pojo;
    
    import lombok.Data;
    
    import java.util.List;
    
    @Data
    public class Teacher {
        private int id;
        private String name;
        //老师拥有多个学生
        private List<Student> students;
    }
    
    
  • 修改resources.edu.xalead.Dao.TeacherMapper.xml代码为:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--namespacce = 绑定一个对应的Dao/Mapper接口 对应之前的实现接口-->
    <mapper namespace="edu.xalead.dao.TeacherMapper">
    <!--按结果嵌套查询-->
        <select id="getTeacher" resultMap="teacherStudent" parameterType="int">
            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" javaType="ArrayList" ofType="Student">
                <result property="id" column="sid"/>
                <result property="name" column="sname"/>
                <result property="tid" column="tid"/>
            </collection>
        </resultMap>
    
        <!--方法二 按照查询嵌套-->
        <select id="getTeacher2" resultMap="teacherStudent2" parameterType="int">
            select * from mybatis_test.teacher where id = #{tid}
        </select>
    
        <resultMap id="teacherStudent2" type="Teacher">
            <!--没有变的字段也要写出来,否则结果中为空-->
            <result property="id" column="id"/>
            <collection property="students" column="id" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId"></collection>
        </resultMap>
        <select id="getStudentByTeacherId" resultType="Student" parameterType="int">
            select * from mybatis_test.student where tid = #{id}
        </select>
    
    </mapper>
    

测试:

package edu.xalead.dao;

import edu.xalead.pojo.Teacher;
import edu.xalead.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);
        Teacher teacher = mapper.getTeacher2(1);
        System.out.println(teacher);
        sqlSession.close();
    }
}

结果:

在这里插入图片描述

注意:

  1. 关联- association [多对一]
  2. 集合- collection [一对多]
  3. javaType & ofType
    1. javaType 用来指定实体类中属性的类型(接口的返回值类型)
    2. ofType 用来指定映射到List或者集合中的pojo类型,泛型的类型
  4. 在resultMap 映射时,复杂情况时,也要把对应关系写出来到result中,否则结果中该字段为空或0
  5. 两种方法各有优缺,看自己掌握情况,个人推荐第一种
  6. 保证sql的可读性,尽量保证通俗易懂
  7. 注意一对多和多对一中,属性名和字段名的问题!
  8. 如果问题不好排查,可以使用日志,建议使用log4j

面试高频:

  • mysql引擎
  • InnoDB底层原理
  • 索引
  • 索引优化!

欢迎访问我的个人博客:http://www.ayjup.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值