MyBatis学习笔记一对多关系

Posted 劳资的睡姿决定发型

tags:

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

有了之前的student表,address表后,再加上一张表,grade年级表,一个年级对应多个学生,在查询grade表的时候,一并查询学生表.
一条grade数据对就多条学生数据,一对多关系.
一.首先完成从grade----> student的单向联结.
1.建表mybatis_grade.
  1. package com.skymr.mybatis.model;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class Grade {  
  6.   
  7.     private int id;  
  8.       
  9.     private String gradeName;  
  10.       
  11.     private List<Student> students;  
  12.   
  13.     public int getId() {  
  14.         return id;  
  15.     }  
  16.   
  17.     public void setId(int id) {  
  18.         this.id = id;  
  19.     }  
  20.   
  21.     public String getGradeName() {  
  22.         return gradeName;  
  23.     }  
  24.   
  25.     public void setGradeName(String gradeName) {  
  26.         this.gradeName = gradeName;  
  27.     }  
  28.   
  29.     public List<Student> getStudents() {  
  30.         return students;  
  31.     }  
  32.   
  33.     public void setStudents(List<Student> students) {  
  34.         this.students = students;  
  35.     }  
  36.       
  37.     public String toString(){  
  38.         return "["+id+","+gradeName+","+students+"]";  
  39.     }  
  40. }  
 
2.GradeMapper接口
  1. package com.skymr.mybatis.mappers;  
  2.   
  3. import com.skymr.mybatis.model.Grade;  
  4.   
  5. public interface GradeMapper {  
  6.   
  7.     public Grade getGrade(int id);  
  8. }  
 
3.GradeMapper.xml映射
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">  
  3. <mapper namespace="com.skymr.mybatis.mappers.GradeMapper">  
  4.     <select id="getGrade" resultMap="gradeMap" parameterType="int">  
  5.         select * from mybatis_grade where id=#{id}  
  6.     </select>  
  7.       
  8.     <resultMap type="Grade" id="gradeMap">  
  9.         <id property="id" column="id"/>  
  10.         <result property="gradeName" column="grade_name"/>  
  11.         <!-- 根据id查询student getStudentsByGradeId -->  
  12.         <!-- column传入grade主键 -->  
  13.         <collection property="students" column="id" select="com.skymr.mybatis.mappers.StudentMapper.getStudentsByGradeId"></collection>  
  14.     </resultMap>  
  15. </mapper>   
 
4.为StudentMapper添加getStudentsByGradeId方法
  1. public List<Student> getStudentsByGradeId(int gradeId);  
  1. <select id="getStudentsByGradeId" resultMap="stuMapWithAddr" parameterType="int">  
  2.     select * from mybatis_Student where grade_id=#{gradeId}  
  3. </select>  
  1. <resultMap type="Student" id="stuMapWithAddr">  
  2.     <id property="id" column="id"/>  
  3.     <result property="name" column="name"/>  
  4.     <result property="age" column="age"/>  
  5.     <association property="address" column="address_id" select="com.skymr.mybatis.mappers.AddressMapper.getAddress">  
  6.     </association>  
  7. </resultMap>  
 
5.测试.
  1. package com.skymr.mybatis.service;  
  2.   
  3. import org.apache.ibatis.session.SqlSession;  
  4. import org.junit.After;  
  5. import org.junit.Before;  
  6. import org.junit.Test;  
  7. import org.slf4j.Logger;  
  8. import org.slf4j.LoggerFactory;  
  9.   
  10. import com.skymr.mybatis.mappers.GradeMapper;  
  11. import com.skymr.mybatis.model.Grade;  
  12. import com.skymr.mybatis.util.MybatisUtil;  
  13.   
  14. public class GradeTest {  
  15.   
  16.     private Logger logger = LoggerFactory.getLogger(GradeTest.class);  
  17.       
  18.     private SqlSession session;  
  19.       
  20.     @Before  
  21.     public void beforeTest(){  
  22.         session = MybatisUtil.openSession();  
  23.     }  
  24.     @After  
  25.     public void afterTest(){  
  26.         session.close();  
  27.     }  
  28.       
  29.     @Test  
  30.     public void testGetGrade(){  
  31.         logger.info("测试取得年级(带学生)");  
  32.         GradeMapper mapper = session.getMapper(GradeMapper.class);  
  33.         Grade grade = mapper.getGrade(1);  
  34.         logger.info(grade.toString());  
  35.     }  
  36.       
  37. }  
 
 
二.再完成student--> Grade的单向连接.
这就和上一节学习的差不多了,
1.Student类中加入Grade属性
  1. private Grade grade;  
  2.     public Grade getGrade() {  
  3.         return grade;  
  4.     }  
  5.     public void setGrade(Grade grade) {  
  6.         this.grade = grade;  
  7.     }  
2.StudentMapper.xml修改
  1. <resultMap type="Student" id="stuMapWithAddr">  
  2.     <id property="id" column="id"/>  
  3.     <result property="name" column="name"/>  
  4.     <result property="age" column="age"/>  
  5.     <association property="address" column="address_id" select="com.skymr.mybatis.mappers.AddressMapper.getAddress">  
  6.     </association>  
  7.     <association property="grade" column="grade_id" select="com.skymr.mybatis.mappers.GradeMapper.getGrade"></association>  
  8. </resultMap>  
 
3.测试
 
  1. @Test  
  2. public void testGetStudent(){  
  3.     logger.info("测试取得学生(带地址)");  
  4.     StudentMapper mapper = session.getMapper(StudentMapper.class);  
  5.     Student stu= mapper.getStudentWithAddr(1);  
  6.     logger.info(stu.toString());  
 
ps:student与Grade类的toString 方法要注意,千万不要循环打印了.
想到了一个问题,Student中包含了Grade,Grade又包含了Student,数据库中会不会循环查询呢?
 
进行验证吧,
(1)把Student类,Grade类的toString 方法去掉
(2)修改测试方法
  1. @Test  
  2. public void testGetStudent(){  
  3.     logger.info("测试取得学生(带地址)");  
  4.     StudentMapper mapper = session.getMapper(StudentMapper.class);  
  5.     Student stu= mapper.getStudentWithAddr(1);  
  6.     logger.info(stu.toString());  
  7.     logger.info(stu.getGrade().toString());  
  8.     logger.info(stu.getGrade().getStudents().toString());  
  9.     logger.info(stu.getGrade().getStudents().get(0).getGrade().toString());  
  10.     logger.info(stu.getGrade().getStudents().get(0).getGrade().getStudents().toString());  
  11. }  
打印结果
  1. 2015-08-31 12:01:26 564 ->[main]--[INFO ]--[StudentTest3]--测试取得学生(带地址)  
  2. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3][email protected]  
  3. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3][email protected]  
  4. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3]--[[email protected]]  
  5. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3][email protected]  
  6. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3]--[[email protected]]  
技术分享
 
结果表明,第一行Student实例与第三行实例不等,之后的实例就相互指引了,数据库中没有循环查询.
数据库中查询了3次:
第1次查询student表,
第2次查询Gradent表,
第3次再查询Student表,其实这次是多余的,可以经过配置去掉.
 
总结:一对多关系与一对一相似,主要的差别是association与connection, association是外键关联主键,一对一,connection是主键关联外键,一对多

以上是关于MyBatis学习笔记一对多关系的主要内容,如果未能解决你的问题,请参考以下文章

mybatis学习笔记(11)-一对多查询

Mybatis框架学习笔记

Mybatis学习笔记—高级映射,延迟加载

Mybatis学习笔记:多对一(association )一对多处理(collection)

Mybatis学习第19节 -- 嵌套查询一对多的配置

MyBatis学习09高级映射之一对多查询