• 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]--com.skymr.mybatis.model.Student@1bbc3eb  
    3. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3]--com.skymr.mybatis.model.Grade@3b8a9a  
    4. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3]--[com.skymr.mybatis.model.Student@1089c2c]  
    5. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3]--com.skymr.mybatis.model.Grade@3b8a9a  
    6. 2015-08-31 12:01:27 067 ->[main]--[INFO ]--[StudentTest3]--[com.skymr.mybatis.model.Student@1089c2c]  
     
    结果表明,第一行Student实例与第三行实例不等,之后的实例就相互指引了,数据库中没有循环查询.
    数据库中查询了3次:
    第1次查询student表,
    第2次查询Gradent表,
    第3次再查询Student表,其实这次是多余的,可以经过配置去掉.
     
    总结:一对多关系与一对一相似,主要的差别是association与connection, association是外键关联主键,一对一,connection是主键关联外键,一对多
  • 相关阅读:
    获取枚举Description的Name
    MVC 3 RequiredIf validator for multiple values
    js关闭页面(兼容浏览器)
    js实现复制到剪切板
    Reverse Integer
    303. Range Sum Query
    326.Power of Three
    328. Odd Even Linked List
    面试基础知识点
    javaSE学习博客与笔记
  • 原文地址:https://www.cnblogs.com/bkyliufeng/p/6291775.html
Copyright © 2020-2023  润新知