J2EE系列之MyBatis学习笔记(五)-- mybatis关系映射(一对多映射)
来源:互联网 发布:海外淘宝首页 编辑:程序博客网 时间:2024/05/22 23:05
这一篇博客讲述一对多关系映射。以班级学生为例。
在上一个工程的基础上:
1.数据库中新建表t_grade,并添加数据:
把这个表和t_student建立一对多关联:
表t_student中添加字段gradeId:
2.新建类Grade:
package com.test.model;import java.util.List;public class Grade {private Integer id;private String gradeName;private List<Student> students;public Integer getId() {return id;}public void setId(Integer 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;}@Overridepublic String toString() {return "Grade [id=" + id + ", gradeName=" + gradeName + ", students=" + students + "]";}}2.新建Grade的数据库操作接口GradeMapper:
package com.test.mappers;import com.test.model.Grade;public interface GradeMapper {public Grade findById(Integer id);}
这里只有一个方法,就是根据id查询年级信息。
3.实现这个方法:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.test.mappers.GradeMapper"><resultMap type="Grade" id="GradeResult"><id property="id" column="id"/><result property="gradeName" column="gradeName"/><collection property="students" column="id" select="com.test.mappers.StudentMapper.findByGradeId"></collection></resultMap><select id="findById" parameterType="Integer" resultMap="GradeResult">select * from t_grade where id=#{id}</select></mapper>
这里和一对多类似。定义的结果映射中,通过<collection>标签实现关联:把查询结果的列id的值传入到com.test.mappers.StudentMapper.findByGradeId方法中,
这个方法的执行结果赋值给Grade类对象的students属性。
4.这里在StudentMapper中添加通过年级Id查询学生信息的方法:
public Student findByGradeId(Integer gradeId);
StudentMapper.xml中实现这个方法:
<select id="findByGradeId" parameterType="Integer" resultMap="StudentResult">select * from t_student where gradeId=#{gradeId}</select>
5.新建测试类GradeTest:
package com.test.service;import org.apache.ibatis.session.SqlSession;import org.apache.log4j.Logger;import org.junit.After;import org.junit.Before;import org.junit.Test;import com.test.mappers.GradeMapper;import com.test.model.Grade;import com.test.util.SqlSessionFactoryUtil;public class GradeTest {private static Logger logger = Logger.getLogger(GradeTest.class);private SqlSession sqlSession = null;private GradeMapper gradeMapper = null;@Beforepublic void setUp() throws Exception {sqlSession = SqlSessionFactoryUtil.openSession();gradeMapper = sqlSession.getMapper(GradeMapper.class);}@Afterpublic void tearDown() throws Exception {sqlSession.close();}@Testpublic void testFindGradeWithStudent() {logger.info("查询年级(带学生信息)");Grade grade = gradeMapper.findById(2);System.out.println(grade);}}
运行测试函数,控制台输出为:
[main] INFO com.test.service.GradeTest - 查询年级(带学生信息)Grade [id=2, gradeName=大二, students=[Student [id=4, name=李四2, age=11, address=Address [id=2, sheng=广西省, shi=南宁市, qu=兴宁区]], Student [id=5, name=王五, age=15, address=Address [id=1, sheng=广西省, shi=南宁市, qu=青秀区]]]]这里通过年级查询出来这个年级的所有学生信息。
说一下执行过程:
1)运行测试方法,学生id=2传入到GradeMapper.xml中的findById方法中。执行这个方法的sql语句,查询结果为:
2)按照结果映射GradeResult封装返回结果:
2.1)把id列的值付给Grade类对象的id属性,把gradeName列的值付给Grade类对象的gradeName属性。扫描到<collection>标签的时候把id列的值传给StudentMapper.xml中的findByGradeId方法。
2.2)执行findByGradeId方法的sql语句,得到查询结果:
按照结果映射StudentResult封装返回结果:还会到t_address中查询出学生的地址信息(这个过程在一对一关系映射中
讲过),这里就不再讲述过程了。
3)得到带有学生的年级结果后打印出年级信息。
以上就实现了查询年级信息的时候查询出年级的所有学生信息。
进一步的讲,在查询学生信息的时候,我们也希望能够查询出学生所在的班级信息。为此进行如下修改:
1.在Student类中添加属性grade:
生成这个属性的get和set方法,并重新Student类的toString方法。
2.修改StudentMapper.xml中的结果映射StudentResult为:
<resultMap type="Student" id="StudentResult"><id property="id" column="id"/><result property="name" column="name"/><result property="age" column="age"/><association property="address" column="addressId" select="com.test.mappers.AddressMapper.findById"></association><association property="grade" column="gradeId" select="com.test.mappers.GradeMapper.findById"></association></resultMap>
这里多添加了一个通过把列gradeId的值传给GradeMapper.findById方法获取相应的班级信息,并把班级信息传给grade属性。
3.StudentTest3类中新建测试方法:
@Testpublic void testFindStudentWithGrade() {logger.info("查询学生(带年级)");Student student = studentMapper.findStudentWithAddress(2);System.out.println(student);}运行这个测试方法:
程序报错了,报错为栈溢出。出现这个问题的原因是程序陷入了死循环。这个方法中有打印学生信息,
Student类的toString方法中显示在打印学生信息的时候会打印学生所在的班级信息。Grade类的toString方法显示打印
班级信息的时候会打印班级中的学生信息。这样就陷入了打印死循环。
为了解决这个问题,修改一下Grade类的toString方法:
@Overridepublic String toString() {return "Grade [id=" + id + ", gradeName=" + gradeName + "]";}
这里只打印年级信息,而不再打印年级中的学生信息了。
运行上述测试方法,控制台输出为:
[main] INFO com.test.service.StudentTest - 查询学生(带年级)Student [id=2, name=李四, age=11, address=Address [id=2, sheng=广西省, shi=南宁市, qu=兴宁区], grade=Grade [id=1, gradeName=大一]]
这里输出了学生信息以及学生所在的班级和地址信息。
- J2EE系列之MyBatis学习笔记(五)-- mybatis关系映射(一对多映射)
- J2EE系列之MyBatis学习笔记(四)-- mybatis关系映射(一对一映射)
- J2EE系列之Hibernate4学习笔记(五)--关联关系一对多映射
- J2EE系列之Hibernate4学习笔记(四)--关联关系一对多映射
- Mybatis笔记之三 -- 映射关系(一对多)
- Mybatis 一对多关系映射
- MyBatis一对多关系映射
- MyBatis映射关系一对多
- J2EE系列之MyBatis学习笔记(三)-- 使用XML配置SQL映射器
- J2EE系列之MyBatis学习笔记(十)-- 使用注解配置sql映射器
- J2EE系列之MyBatis学习笔记(十一)-- 使用注解配置sql映射器
- J2EE系列之MyBatis学习笔记(十二)-- 使用注解配置sql映射器
- MyBatis高级映射之-一对一(一对多)关联映射
- MyBatis学习笔记(五)一对多关系
- Mybatis 一对多(OneToOne)关系映射
- mybatis 一对多的映射关系
- Mybatis 一对多(OneToOne)关系映射
- Mybatis 一对多(OneToOne)关系映射
- Git使用文档(张高伟)
- ElasticSearch建立索引报错
- 设计模式-Builder模式
- 直播-拉流和推流概述 转载
- 三栏网页宽度自适应布局方法
- J2EE系列之MyBatis学习笔记(五)-- mybatis关系映射(一对多映射)
- linux中批量修改文件名/文件内容(rename sed)
- svm:简介及总结
- 在大公司工作3年以上的人,如何摆脱螺丝钉的现实?
- HiWATER
- 深入浅出UE4网络
- 信息批量提取工具bulk-extractor
- ss-libev 源码解析local篇(4): server_recv_cb之STAGE_STREAM
- View绘制过程