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