说明:在完成了一对一关联测试以后,发现了一个问题,就是上一篇博文中,只是单向的一对一,于是就想怎么样才能改成双向的呢。抱着这个想法开始先看一对多关联映射,然后回过头去看一对一的双向关联映射就直接迎刃而解了。
1.首先,没有重新搭建开发环境,直接在一对一关联的项目中添加多对多关联映射的实例。此处打码后贴出
2.pom.xml
本文件中还是用上一文章中提到的代码就可以了,然后由于开启了延迟加载功能,所以在编译项目的时候,提示我需要添加cglib的支持(也就是少jar包了),添加以下依赖即可。
<!-- https://mvnrepository.com/artifact/cglib/cglib --><dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version></dependency>
3.mybatis的全局配置文件就不在粘贴,有需要就参考前一篇文章,下面从SQL脚本开始
CREATE TABLE tb_clazz ( id INT PRIMARY KEY AUTO_INCREMENT, CODE VARCHAR(18), NAME VARCHAR(18));INSERT INTO tb_clazz(CODE , NAME)VALUES('j1601','Java就业班');CREATE TABLE tb_student ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(18), sex VARCHAR(18), age INT, clazz_id INT, FOREIGN KEY (clazz_id) REFERENCES tb_clazz(id));INSERT INTO tb_student (NAME,sex,age,clazz_id)VALUES('jack','男',23,1), ('rose','女',18,1), ('tom','男',21,1),
('alice','女',20,1);
4.实体类:
Clazz.java
public class Clazz implements Serializable{ private static final long serialVersionUID = 1L; private int id; private String code; private String name; //一个班级可有多个学生,所以班级和学生是一对多的关系
private List<Student> students;
/**省略set和get方法*/
}
Student.java
public class Student implements Serializable{ private static final long serialVersionUID = 1L; private int id; private String name; private String sex; private int age; //学生和班级是多对一的关系,即一个学生只能属于一个班级
private Clazz clazz;
/**省略set和get方法*/
}
5.映射文件(对应的接口略)
ClazzMapper.xml
<?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="org.fkit.mapper.ClazzMapper"> <!-- 根据id查询班级信息,返回resultMap --> <select id="selectClazzById" parameterType="int" resultMap="clazzResultMap"> select * from tb_clazz where id = #{id} </select> <resultMap type="org.fkit.domain.Clazz" id="clazzResultMap"> <id property="id" column="id"/> <result property="code" column="code"/> <result property="name" column="name"/> <!-- 一对多关联映射:collection fetchType="lazy"表示懒加载 ,使用懒加载时需要在mybatis的全局配置文件中配置相应的信息 select属性表示会使用column属性的id值作为参数执行StudentMapper中定义的selectStudentByClazzId查询班级 对应的所有学生数据,查询出的数据将被封装到property表示的students对象当中 --> <collection property="students" fetchType="lazy" javaType="ArrayList" column="id" ofType="org.fkit.domain.Student" select="org.fkit.mapper.StudentMapper.selectStudentByClazzId"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="sex" column="sex"/> <result property="age" column="age"/> </collection> </resultMap>
</mapper>
StudentMapper.xml
<?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="org.fkit.mapper.StudentMapper"> <!-- 根据id查询学生信息,多表连接,返回resultMap --> <select id="selectStudentById" parameterType="int" resultMap="studentResultMap"> select * from tb_clazz c,tb_student s where c.id = s.clazz_id and s.id = #{id} </select> <!-- 根据班级id查询学生信息,返回resultMap --> <select id="selectStudentByClazzId" parameterType="int" resultMap="studentResultMap"> select * from tb_student where clazz_id = #{id} </select> <!-- 映射Student对象的resultMap --> <resultMap type="org.fkit.domain.Student" id="studentResultMap"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="sex" column="sex"/> <result property="age" column="age"/> <!-- 多对一关联映射:association 因为<select id="selectStudentById"……/>的SQL语句是一条 多表连接,关联tb_clazz表的同时查询了班级数据,所以以下的association只是 简单的装载数据。 --> <association property="clazz" javaType="org.fkit.domain.Clazz"> <id property="id" column="id"/> <result property="code" column="code"/> <result property="name" column="name"/> </association> </resultMap>
</mapper>
6.测试类(注:测试的时候遇到点小问题,就是在测根据id查询Student信息时,不知道为什么获取不到Student的name值,不过这不影响我们学习一对多这个示例)
public class OneToManyTest { public static void main(String[] args) throws Exception { // 读取mybatis-config.xml文件 InputStream inputStream = Resources.getResourceAsStream("mybatis/mybatis-config.xml"); // 初始化mybatis,创建SqlSessionFactory类的实例 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream); // 创建Session实例 SqlSession session = sqlSessionFactory.openSession(); OneToManyTest t = new OneToManyTest(); //t.testSelectClazzById(session); t.testSelectStudentById(session); // 提交事务 session.commit(); // 关闭Session session.close(); } // 测试一对多,查询班级Clazz(一)的时候级联查询学生Student(多) public void testSelectClazzById(SqlSession session){ // 获得ClazzMapper接口的代理对象 ClazzMapper cm = session.getMapper(ClazzMapper.class); // 调用selectClazzById方法 Clazz clazz = cm.selectClazzById(1); // 查看查询到的clazz对象信息 System.out.println(clazz.getId() + " "+ clazz.getCode() + " "+clazz.getName()); // 查看clazz对象关联的学生信息 List<Student> students = clazz.getStudents(); for(Student stu : students){ System.out.println(stu.getName()); } } // 测试多对一,查询学生Student(多)的时候级联查询 班级Clazz(一) public void testSelectStudentById(SqlSession session){ // 获得StudentMapper接口的代理对象 StudentMapper sm = session.getMapper(StudentMapper.class); // 调用selectStudentById方法 Student stu = sm.selectStudentById(1); // 查看查询到的Student对象信息 System.out.println(stu); // 查看Student对象关联的班级信息 System.out.println(stu.getClazz().getName()); }}