5.mybatis一对一表关联查询

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5.mybatis一对一表关联查询相关的知识,希望对你有一定的参考价值。

方式一:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集,封装联表查询的数据(去除重复的数据)
  SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}

方式二:嵌套查询,通过执行另外一个SQL 映射语句来返回预期的复杂类型
  SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}
  SELECT t.tid id, t.tname name FROM teacher t WHERE t.tid = #{id} //使用上面查到的tid


 

2种都用到了resultMap和association(关联),区别:

  方式1中的association中,用到javaType,代表关联的实体类型

  方式2中的association中,不用javaType,但是用到column(代表第一条sql查询的结果的外键作为第二条sql的查询条件)和select(第二条sql语句)


 

实例:

有班级class[id, name, teacher],对应的老师teacher[id, name],它们的关系是一对一。

插入表数据:

--teacher表
INSERT INTO `mybatis`.`teacher`(`tid`,`tname`) VALUES ( NULL,老师A);
INSERT INTO `mybatis`.`teacher`(`tid`,`tname`) VALUES ( NULL,老师B);
--class表
INSERT INTO `mybatis`.`class`(`cid`,`cname`,`tid`) VALUES ( NULL,一年级,1);
 INSERT INTO `mybatis`.`class`(`cid`,`cname`,`tid`) VALUES ( NULL,二年级,2);

Java实体类:

public class Teacher {
    private int id;
    private String name;
    
    
    public Teacher() {
        super();
    }
    public Teacher(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Teacher [id=" + id + ", name=" + name + "]";
    }
    
}
public class Clazz {
    private int id;
    private String name;
    private Teacher teacher;
    
    public Clazz(int id, String name, Teacher teacher) {
        super();
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    }
    public Clazz() {
        super();
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Teacher getTeacher() {
        return teacher;
    }
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
    @Override
    public String toString() {
        return "Clazz [id=" + id + ", name=" + name + ", teacher=" + teacher
                + "]";
    }
    
}

 

第一种方式: 嵌套结果,使用嵌套结果映射来处理重复的联合结果的子集,封装联表查询的数据(去除重复的数据)

SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}

 

teacherMapper.xml:

<!-- 查询班级及其老师信息 -->
    <select id="getClazz" parameterType="int" resultMap="getClazzMap">
        SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}
    </select>
    
    <resultMap type="Clazz" id="getClazzMap">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <!-- 关联班级对应的teacher -->
        <association property="teacher" javaType="Teacher">
            <id property="id" column="tid"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>

Java测试类:

/**
     * 方式一:嵌套结果
     * @author 魅力_小生
     *
     */
    @Test
    public void getClazz1(){
        //创建session,设置事务为true
        SqlSession session = MyBatisUtil.getSessionFactory().openSession(true);
        String statement = "com.mlxs.mybatis.test4.clazzMapper.getClazz";
        Clazz clazz = session.selectOne(statement, "2");
        System.out.println("clazz--->"+clazz);
        session.close();
    }

结果:

clazz--->Clazz [id=2, name=二年级, teacher=Teacher [id=2, name=老师B]]

 

 

第二种方式:嵌套查询,通过执行另外一个SQL 映射语句来返回预期的复杂类型

SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}
SELECT t.tid id, t.tname name FROM teacher t WHERE t.tid = #{id} //使用上面查到的tid

 

teacherMapper.xml:

<!-- 
     一对一 关联查询:
     
         方式二:嵌套查询,通过执行另外一个SQL 映射语句来返回预期的复杂类型
         SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}
         SELECT t.tid id, t.tname name FROM teacher t WHERE t.tid = #{id} //使用上面查到的tid
      -->
    <!-- 查询班级及其老师信息 -->
    <select id="getClazz2" parameterType="int" resultMap="getClazzMap2">
        SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}
    </select>
    <select id="getTeacher" parameterType="int" resultType="Teacher">
        SELECT t.tid id, t.tname name FROM teacher t WHERE t.tid = #{id}
    </select>
    
    <resultMap type="Clazz" id="getClazzMap2">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
        <!-- 关联班级对应的teacher,将查询class表返回的tid参数传给getTeacher,也就是getTeacher中的#{id} -->
        <association property="teacher" column="tid" select="getTeacher"/>
    </resultMap>

Java测试类:

/**
     * 方式二:嵌套查询,通过执行另外一个SQL 映射语句来返回预期的复杂类型
         SELECT * FROM class c,teacher t WHERE c.tid = t.tid AND c.cid=#{id}
         SELECT t.tid id, t.tname name FROM teacher t WHERE t.tid = #{id} //使用上面查到的tid
     * @author 魅力_小生
     *
     */
    @Test
    public void getClazz2(){
        //创建session,设置事务为true
        SqlSession session = MyBatisUtil.getSessionFactory().openSession(true);
        String statement = "com.mlxs.mybatis.test4.clazzMapper.getClazz2";
        Clazz clazz = session.selectOne(statement, "2");
        System.out.println("clazz--->"+clazz);
        session.close();
    }

结果:

clazz--->Clazz [id=1, name=一年级, teacher=Teacher [id=1, name=老师A]]

 

以上是关于5.mybatis一对一表关联查询的主要内容,如果未能解决你的问题,请参考以下文章

spring Data jpa 一对多关联 动态查询怎么写

MyBatis_关联关系查询

MyBatis高级篇 - 关联查询(一对多)

5. MyBatis 缓存

10.关联关系查询

oracle02--多表关联查询