MyBatis关联映射

Posted 神剑战王

tags:

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

一.Mybatis中表与表之间的关系分为一下4类以及关系:

1)一对一

2)一对多

3)多对一

4)多对多

  • 一对一:一个班主任只属于一个班级,一个班级也只能有一个班主任
  • 一对多:一个班级有多个学生,一个学生只属于一个班级
  • 多对多:一个学生可以选多门课,一门课可以有多个学生

二.多表查询

 

多表查询 方法一

 

select a.*,b.* from student a,school b  where a.t_sid=b.t_id

 

 

 

select a.*,b.t_name from student a,school b  where a.t_sid=b.t_id

 

 

 

select a.*,b.t_name from student a,school b  where a.t_sid=b.t_id and b.t_id=1

 

 

 

多表查询 方法二

 

select student.*,school.* from student inner join school on student.t_sid=school.t_id

 

 

 

select student.*,school.t_name from student inner join school on student.t_sid=school.t_id

 

 

 

select student.*,school.t_name from student inner join school on student.t_sid=school.t_id and school.t_id=1

 

3  mybatis多对一

 

要查询多个表中信息:有三种方法:

 

方法一:

<resultMap type="com.softjx.model.Student" id="StudentMap1">
  <result column="t_id" property="id"/>
  <result column="t_name" property="studentName" />
  <result column="t_age" property="age"/>
  <result column="t_enterdate" property="enterDate"/>
  <result column="t_sid" property="sid"/>
<!—关联字段-->
  <result column="t_id1" property="school.id"/>
  <result column="t_name1" property="school.schoolName"/>

  </resultMap>


<!-- 根据id查询数据表中的一条记录 -->
<select id="getStudentId1"  resultMap="StudentMap1">
 select a.t_id,a.t_name,a.t_age,a.t_enterdate,a.t_sid,b.t_id as t_id1,b.t_name as t_name1 from student a,school b  where a.t_sid=b.t_id and a.t_id=#{id};
</select>

方法二:使用association定义关联的单个对象

<resultMap type="com.softjx.model.Student" id="StudentMap2">
  <result column="t_id" property="id"/>
  <result column="t_name" property="studentName" />
  <result column="t_age" property="age"/>
  <result column="t_enterdate" property="enterDate"/>
  <result column="t_sid" property="sid"/>
    <!--  association可以指定联合的javaBean对象
        property="school":指定哪个属性是联合的对象
        javaType:指定这个属性对象的类型[不能省略]
        -->
  <association property="school" javaType="com.softjx.model.School">
            <id column="t_id" property="id"/>
            <result column="t_name" property="schoolName"/>
  </association>
  </resultMap>
  

<!-- 根据id查询数据表中的一条记录 -->
<select id="getStudentId2"  resultMap="StudentMap2">
 select a.t_id,a.t_name,a.t_age,a.t_enterdate,a.t_sid,b.t_id as t_id1,b.t_name as t_name1 from student a,school b  where a.t_sid=b.t_id and a.t_id=#{id};
</select>

方法三:使用association进行分步查询

 

1)、先按照t_id查询学生信息

 

2)、根据查询学生信息中的t_sid值去学校表查出学校的信息

 

3)、学校信息设置到学生中;

1、先按照t_id查询学生信息
2、根据查询学生信息中的t_sid值去学校表查出学校的信息
    3、学校信息设置到学生中;

<resultMap type="com.softjx.model.Student" id="StudentMap3">
  <result column="t_id" property="id"/>
  <result column="t_name" property="studentName" />
  <result column="t_age" property="age"/>
  <result column="t_enterdate" property="enterDate"/>
  <result column="t_sid" property="sid"/>
<!-- association定义关联对象的封装
    select:表明当前属性再去调用哪个方法查出的结果
    column:指定根据当前表中哪一列的值传给这个方法             
     流程:使用select指定的方法查出对象,并封装给property指定的属性
-->
  <association property="school" 
             select="com.softjx.dao.SchoolMapper.getSchoolId"
             column="t_sid">
 </association>
 
  </resultMap>

使用association进行分步查询,可以是立即加载,延迟加载;

可以使用延迟加载(懒加载);(按需加载)

Student==>School:

我们每次查询Student对象的时候,都将一起查询出来,(立即加载)。

学校信息在我们使用的时候再去查询(延迟加载);

 

分段查询的基础之上(懒加载)加上两个配置在全局配置文件中config.xml:

<settings>

<setting name="lazyLoadingEnabled" value="true"/>

<setting name="aggressiveLazyLoading" value="false"/>

</settings>

4  mybatis一对多

方法一:使用collection标签

1)在学校中有一个集合类型,指向多个学生

private List<Student> students;
    
    
    public List<Student> getStudents() {
        return students;
    }
    public void setStudents(List<Student> students) {
        this.students = students;
    }
2)在SchoolMapper.xml文件中配置collection标签,标签中ofType:指定集合里面元素的类型,property:指定bean的属性名。
<resultMap type="com.softjx.model.School" id="SchoolMap1">
         <result column="t_id" property="id"/>
         <result column="t_name" property="schoolName" />
        <!-- 
            collection定义关联集合类型的属性 
            ofType:指定集合里面元素的类型
        -->
        <collection property="students" ofType="com.softjx.model.Student">
            <!-- 定义这个集合中元素的封装规则 -->
             <result column="t_id1" property="id"/>
             <result column="t_name1" property="studentName" />
             <result column="t_age" property="age"/>
             <result column="t_enterdate" property="enterDate"/>
             <result column="t_sid" property="sid"/>
        </collection>
    </resultMap>



<select id="getSchoolId1" resultMap="SchoolMap1">
select b.t_id as t_id,b.t_name as t_name ,a.t_id as t_id1 ,a.t_name as t_name1,a.t_age,a.t_enterdate, a.t_sid from school b, student a where b.t_id=a.t_sid and b.t_id=#{id}
</select>

方法二:使用collection分段:

 

1)首先要根据学校编号在学生表中查询所有学生:

<!-- 根据学生的学校id查询所有的学生 -->


public List<Student> getStudentsBySchoolId(Integer sid);


<select id="getStudentsBySchoolId" resultMap="StudentMap">
 select * from student where t_sid=#{sid};
</select>

2)Collection分段代码:

<!-- sid是方法的参数名,t_id是字段名 -->
    <resultMap type="com.softjx.model.School" id="SchoolMap2">
        <result column="t_id" property="id"/>
        <result column="t_name" property="schoolName" />
        <collection property="students" 
            select="com.softjx.dao.StudentMapper.getStudentsBySchoolId"
            column="{sid=t_id}" fetchType="lazy">
        </collection>
    </resultMap>
    
    
<select id="getSchoolId2" resultMap="SchoolMap2">
        select * from school where t_id=#{id}
    </select>

5  mybatis一对多,多对一

多对一关系:

//根据id查询学生,包括学生的学校
//property="school",column="t_sid" column是当前表中关联字段名t_sid
//查询一个用户
    @Select("select * from student where t_id=#{id}")
    @Results({@Result(property="id",column="t_id")
             ,@Result(property="studentName",column="t_name")
             ,@Result(property="age",column="t_age")
             ,@Result(property="enterDate",column="t_enterdate")
             ,@Result(property="sid",column="t_sid")
             ,@Result(property="school",column="t_sid",one=@One(select="com.softjx.dao.SchoolMapper.getSchoolId",fetchType=FetchType.EAGER))
     
            })
    public Student getStudentId1(Integer id);

一对多的关系:
//根据学生的学校id查询所有的学生
    @Select("select * from student where t_sid=#{sid}")
    @Results({@Result(property="id",column="t_id")
             ,@Result(property="studentName",column="t_name")
             ,@Result(property="age",column="t_age")
             ,@Result(property="enterDate",column="t_enterdate")
             ,@Result(property="sid",column="t_sid")
            })
    public List<Student> getStudentsBySchoolId(Integer sid);

2.
//根据id查询学校
    //property="students",column="t_id" column是当前表中的主键字段名t_id
    @Select("select * from school where t_id=#{id}")
    @Results({@Result(property="id",column="t_id")
             ,@Result(property="schoolName",column="t_name")
             ,@Result(property="students",column="t_id",many=@Many(select="com.softjx.dao.StudentMapper.getStudentsBySchoolId",fetchType=FetchType.LAZY))
            })
    public School getSchoolId1(Integer id);
  

以上是关于MyBatis关联映射的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis关联查询,表字段相同,resultMap映射问题的解决办法

mybatis第二天——大纲待更新

mybatis第二天

MyBatis关联映射

Mybatis关联映射

EF添加关联的提示问题:映射从第 260 行开始的片段时有问题: