Mybaits 关联查询

一、简介:

关联查询主要用于多表查询,数据库表与表之间存在关系,同样的类与类之间也存在关系,关联映射就是通过映射来描述这种关系,包括(一对一,一对多,多对多),mybatis 提供了高级的关联查询功能,可以很方便地将数据库获取的结果集映射到定义的Java Bean 。

二、使用:

关联查询主要包括俩个步骤:

1.修改实体类之间的关系。

2.映射文件里配置<resultMap>对查询结果集进行封装。写对应的SQL语句。

数据库表如下:

 

说明:一个班级对应一个老师 ,一个班级对应多个学生  teacherId 和 classId分布为外键 

第一步:描述实体类之间的关系(持有对方当成自己的属性)

Classes:

public class Classes {
    private Integer cid;

    private String className;

    private Teacher teacher;        //一对一

    private Set<Student> studentSet;//一对多

    private Classes classes;        //测试对同一表懒加载
    //省略get set 下同
}

Teacher:

public class Teacher {
    private Integer tid;

    private String name;
    //get set 
}

Student:

public class Student {
    private Integer sid;

    private String name;

    private Integer classId;

    private Classes classes;
    //get set
}

第二步:配置<resultMap>(关联查询主要是在<resultMap>元素中,用<association>配置一对多,用<collection>配置一对多)

ClassesMapper.xml

  <resultMap id="ClassesTeaResultMap" type="Classes" ><!--这里设置了别名,所有直接可以使用类名-->
    <id column="cid"  jdbcType="INTEGER" property="cid"/>
    <result column="className" jdbcType="VARCHAR" property="className"/>
    <association property="teacher" javaType="Teacher"><!--持有的一个对象-->
      <id column="tid" javaType="INTEGER" property="tid"/>
      <result column="teacherName" jdbcType="VARCHAR" property="name"/>
    </association>
  </resultMap>

 <select id="selectByPrimaryKey" resultMap="ClassesTeaResultMap" parameterType="java.lang.Integer" >
    select  c.cid,c.className,t.tid ,t.name as teacherName
    from classes c,teacher t
    where cid = #{cid,jdbcType=INTEGER} and c.teacherId = t.tid
  </select>

 <resultMap id="ClassesStuResultMap" type="Classes" >
    <id column="cid"  jdbcType="INTEGER" property="cid"/>
    <result column="className" jdbcType="VARCHAR" property="className"/>
    <collection property="studentSet" ofType="Student"><!--包含多个对象-->
      <result column="name" property="name"/>
    </collection>
  </resultMap>

<select id="selectClassStuByPrimaryKey" resultMap="ClassesStuResultMap" parameterType="java.lang.Integer" >
    select  c.cid,c.className,s.name
    from classes c,student s
    where cid = #{cid,jdbcType=INTEGER} and s.classId = c.cid
  </select>

说明:

  • resultMap 里的id不能重复,对应select标签里面的resultMap属性值
  • id 标签代表的是主键列
  • result标签表示的是非主键列
  • colunm 代表的是查询结果集的列名,有可能不是数据库中的列名(起别名)
  • property 表示的是Java Bean的属性名
  • javaType 为类名(没配置别名需要写包名+类名)
  • association标签代表的是一的一方,比如一个班级的一个老师
  • collection标签代表的多的一方,比如一个班级的多个学生                   注意:ofType="Student" 而不是javaType
  • select 标签注意SQL语句写法,这里采用的是表连接可以避免(N+1)问题,除非使用懒加载才会选择嵌套子查询。
  • select 标签id对应接口的方法名字,不能重复
  • ResultMap中conlum的数量与查询结果集个数相同

测试 :

说明:在测试前不要忘记将映射文件配置到mybatis配置文件中,采用接口方式调用方法要在接口写对应的方法名。

package org.lanqiao.dao;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.lanqiao.entity.Classes;
import org.lanqiao.entity.Student;

import java.io.IOException;
import java.io.Reader;

public class StudentMapperTest {
    SqlSessionFactory sqlSessionFactory;
    Reader reader;//读取配置文件
    SqlSession session = null;
    @Before
    public  void loadXml(){
        try {
            reader = Resources.getResourceAsReader("mybatis-Config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
            session = sqlSessionFactory.openSession();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testSelectStuClassByPrimaryKey() {
        ClassesMapper classesMapper = session.getMapper(ClassesMapper.class);
        Classes classes = classesMapper.selectByPrimaryKey(1);
        System.out.println(classes.getClassName());
        System.out.println(classes.getTeacher().getName());
        System.out.println(classes.getTeacher().getTid());
    }
    @After
    public void afterTest(){
        if (reader !=null){
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (session !=null){
            session.close();
        }

    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mybatis是一种流行的Java持久层框架,可以对数据库进行操作。在mybatis中,实现一对多关联查询可以使用两种方式:嵌套查询和嵌套结果映射。嵌套查询是指在主查询中执行子查询来获取关联对象的数据,而嵌套结果映射是指在主查询的结果映射中包含关联对象的映射。 对于嵌套查询,可以使用select标签在主查询中执行子查询。例如,假设有一个班级和学生的关联关系,可以使用如下的SQL语句进行一对多关联查询: ``` <select id="getBanjiWithStudents" resultType="Banji"> SELECT * FROM Banji WHERE id = #{id} </select> <select id="getStudentsByBanjiId" resultType="Student"> SELECT * FROM Student WHERE banji_id = #{id} </select> ``` 然后,在Mapper接口中定义对应的方法: ``` public interface BanjiMapper { Banji getBanjiWithStudents(int id); } ``` 在配置文件中进行映射: ``` <mapper namespace="com.example.BanjiMapper"> <select id="getBanjiWithStudents" resultType="Banji"> SELECT * FROM Banji WHERE id = #{id} </select> <select id="getStudentsByBanjiId" resultType="Student"> SELECT * FROM Student WHERE banji_id = #{id} </select> </mapper> ``` 然后可以通过调用`getBanjiWithStudents`方法来进行一对多关联查询。 对于嵌套结果映射,可以使用association和collection标签来进行配置。例如: ``` <resultMap id="banjiResultMap" type="Banji"> <id property="id" column="id"/> <result property="name" column="name"/> <collection property="students" ofType="Student"> <id property="id" column="student_id"/> <result property="name" column="student_name"/> </collection> </resultMap> ``` 然后,在Mapper接口中定义对应的方法: ``` public interface BanjiMapper { Banji getBanjiWithStudents(int id); } ``` 在配置文件中进行映射: ``` <mapper namespace="com.example.BanjiMapper"> <resultMap id="banjiResultMap" type="Banji"> <id property="id" column="id"/> <result property="name" column="name"/> <collection property="students" ofType="Student"> <id property="id" column="student_id"/> <result property="name" column="student_name"/> </collection> </resultMap> <select id="getBanjiWithStudents" resultMap="banjiResultMap"> SELECT b.id, b.name, s.id as student_id, s.name as student_name FROM Banji b LEFT JOIN Student s ON b.id = s.banji_id WHERE b.id = #{id} </select> </mapper> ``` 同样可以通过调用`getBanjiWithStudents`方法来进行一对多关联查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值