Mybatis学习笔记-关联表查询的问题

来源:互联网 发布:淘宝挖掘冷门暴利行业 编辑:程序博客网 时间:2024/06/05 22:17

在前面几篇博客中已经学习了Mybatis的基本使用,可以使用Mybatis进行数据库的CRUD操作,并通过xml和注解的方式进行了实现,也学习了下解决字段名和属性名不一致的问题;在实际开发中数据库表之间可能存在一对多,一对一等的表间关系,此文记录下Mybatis中联表查询的相关问题。

需求

数据库中存在两张表,一张班级表,一张老师表;表之间的关系为:一个班级只能有一个老师,一个老师也只能属于一个班级,为一对一的关系;老师表中的id为班级表外键。

功能:通过班级id查询班级信息和老师信息。

创建数据库和测试数据

CREATE TABLE teacher(    t_id INT PRIMARY KEY AUTO_INCREMENT,     t_name VARCHAR(20));CREATE TABLE class(    c_id INT PRIMARY KEY AUTO_INCREMENT,     c_name VARCHAR(20),     teacher_id INT);ALTER TABLE class ADD CONSTRAINT fk_teacher_id FOREIGN KEY (teacher_id) REFERENCES teacher(t_id);   INSERT INTO teacher(t_name) VALUES('LS1');INSERT INTO teacher(t_name) VALUES('LS2');INSERT INTO class(c_name, teacher_id) VALUES('bj_a', 1);INSERT INTO class(c_name, teacher_id) VALUES('bj_b', 2);

创建实体类

Classes.class

package com.taowd.mybatis.entry;public class Classes {    private String id;    private String name;    private Teacher teacher;    public String getId() {        return id;    }    public void setId(String 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 "Classes [id=" + id + ", name=" + name + ", teacher=" + teacher + "]";    }}

Teacher.class

package com.taowd.mybatis.entry;public class Teacher {    private String id;    private String name;    public String getId() {        return id;    }    public void setId(String 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 + "]";    }}

定义sql映射文件

<?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="mapper.ClassMapper">    <!-- 解决方案1:嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 封装联表查询的数据(去除重复的数据) -->    <select id="getClassInfo" parameterType="int" resultMap="ClassResultMap">        select *        from teacher t,class c where c.teacher_id =t.t_id and c.c_id=#{id}    </select>    <resultMap type="_Classes" id="ClassResultMap">        <id property="id" column="c_id" />        <result property="name" column="c_name" />        <association property="teacher" javaType="_Teacher">            <id property="id" column="t_id" />            <result property="name" column="t_name" />        </association>    </resultMap>    <!-- 方式二:嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型 SELECT * FROM class WHERE c_id=1;         SELECT * FROM teacher WHERE t_id=1 //1 是上一个查询得到的teacher_id的值 -->    <select id="getClass2" parameterType="int" resultMap="ClassResultMap2">        select *        from class where c_id=#{id}    </select>    <resultMap type="_Classes" id="ClassResultMap2">        <id property="id" column="c_id" />        <result property="name" column="c_name" />        <association property="teacher" column="teacher_id"            select="getTeacher">        </association>    </resultMap>    <select id="getTeacher" parameterType="int" resultType="_Teacher">        SELECT        t_id id, t_name name FROM teacher WHERE t_id=#{id}    </select></mapper>

测试代码

package com.taowd.mybatis.test;import org.apache.ibatis.session.SqlSession;import org.junit.Test;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.taowd.mybatis.entry.Classes;import com.taowd.mybatis.utils.MybatisUtils;public class TestClasses {    private static final Logger logger = LoggerFactory.getLogger(TestOrders.class);    @Test    public void getClassesInfo() {        // 注意此处默认不是自动提交事务的        SqlSession session = MybatisUtils.getFactory().openSession(true);// 创建自动提交事物的Session对象        String sql = "mapper.ClassMapper.getClassInfo";        Classes result = session.selectOne(sql, 1);        logger.info("获取到的数据:" + result.toString());    }    @Test    public void GetClassessInfo2() {        SqlSession session = MybatisUtils.getFactory().openSession();// 因为仅仅是查询,所以不用自动提交事务        String sql = "mapper.ClassMapper.getClass2";        Classes result = session.selectOne(sql, 2);        logger.info("获取的数据:" + result.toString());    }}

项目结构+测试结果

这里写图片描述

项目源码

源码下载

注意事项

在测试时发生额报错,报错截图如下:
这里写图片描述
这里写图片描述

分析原因为:mybatis的映射文件的命令空间与接口的全限定名不一致导致的,讲过检查确实如此,因此在编写配置文件时一定要小心,放置写错,能赋值粘贴的尽量复制粘贴。