目录
MyBatis中多对一关系的三种处理方法
1.通过级联属性赋值
1)mapper
2)mapper.xml
3)测试代码
4)测试结果
2.通过标签
1)mapper
2)mapper.xml
3)测试代码
4)测试结果
3.分步查询
1)mapper
2)mapper.xml
3)测试代码
4)测试结果
附录
1)ManyToOneMapper
2)ManyToOneMapper.xml
3)ManyToOneMapperTest
4)sql
studentSql
classesSql
MyBatis中多对一关系的三种处理方法
1.通过级联属性赋值
1)mapper
/**
* 级联属性赋值
*/
Student queryStudentAndClasses(int id);
2)mapper.xml
<!--级联属性赋值--> <resultMap id="studentByJiLian" type="org.xiji.enty.Student"> <!--id映射--> <id property="id" column="id"/> <!--学生名字映射--> <result property="studentName" column="studentName"/> <result property="studentAge" column="studentAge"/> <result property="classId" column="classId"/> <!--级联赋值--> <result property="classes.id" column ="classId"/> <result property="classes.className" column="className"/> </resultMap> <select id="queryStudentAndClasses" resultMap="studentByJiLian"> select * from student left join classes on student.classId = classes.id where student.id=#{id} </select>
注:设置resultMap之后,使用resultMap接受查询结果,不是通过resultType接受查询结果
解释:
- <resultMap> 标签
- 定义了一个名为 studentByJiLian 的结果映射,指定其类型为 org.xiji.enty.Student。
- <id> 标签
- 映射 Student 类的 id 属性到数据库表中的 id 列。
- <result> 标签
- 映射 Student 类的 studentName、studentAge 和 classId 属性分别到数据库表中的 studentName、studentAge 和 classId 列。
- 级联属性映射
- classes 是 Student 类的一个属性,表示关联的班级信息。
- <result property="classes.id" column="classId"/> 映射 classes 对象的 id 属性到数据库表中的 classId 列。
- <result property="classes.className" column="className"/> 映射 classes 对象的 className 属性到数据库表中的 className 列。
3)测试代码
/** * 级联属性赋值 */ @Test public void testManyToOne(){ Student student = manyToOneMapper.queryStudentAndClasses(1); System.out.println(student.toString()); }
4)测试结果
2.通过<association>标签
1)mapper
/**
* association
*/
Student queryStudentAndClassesByAssociation(int id);
2)mapper.xml
<!--association赋值--> <resultMap id="associationByResultMap" type="org.xiji.enty.Student"> <!--id映射--> <id property="id" column="id"/> <!--学生名字映射--> <result property="studentName" column="studentName"/> <result property="studentAge" column="studentAge"/> <result property="classId" column="classId"/> <!--association--> <association property="classes" javaType="org.xiji.enty.Classes"> <id property="id" column="classId"/> <result property="className" column="className"/> </association> </resultMap> <select id="queryStudentAndClassesByAssociation" resultMap="associationByResultMap"> select * from student left join classes on student.classId = classes.id where student.id=#{id} </select>
注:设置resultMap之后,使用resultMap接受查询结果,不是通过resultType接受查询结果
解释:
- <resultMap> 标签
- 定义了一个名为 associationByResultMap 的结果映射,指定其类型为 org.xiji.enty.Student。
- <id> 标签
- 映射 Student 类的 id 属性到数据库表中的 id 列。
- <result> 标签
- 映射 Student 类的 studentName、studentAge 和 classId 属性分别到数据库表中的 studentName、studentAge 和 classId 列。
- <association> 标签
- 映射 Student 类的 classes 属性到 org.xiji.enty.Classes 类型的对象。
- 内部包含两个子标签:
- <id>:映射 Classes 类的 id 属性到数据库表中的 classId 列。
- <result>:映射 Classes 类的 className 属性到数据库表中的 className 列。
3)测试代码
/** * association */ @Test public void testManyToOneByassociation(){ Student student = manyToOneMapper.queryStudentAndClassesByAssociation(2); System.out.println(student.toString()); System.out.println(student.getClasses().toString()); }
4)测试结果
3.分步查询
1)mapper
/**
* 分步查询
*/
Student queryStudentAndClassesByStep(int id);
2)mapper.xml
<!--分步查询--> <resultMap id="stepByResultMap" type="org.xiji.enty.Student"> <id property="id" column="id"/> <result property="studentName" column="studentName"/> <result property="studentAge" column="studentAge"/> <result property="classId" column="classId"/> <association property="classes" select="queryClassesByStep" column="classId"> <id property="id" column="id"/> <result property="className" column="className"/> </association> </resultMap> <!--第一步--> <select id="queryStudentAndClassesByStep" resultMap="stepByResultMap" > select * from student where id=#{id} </select> <!--第二步--> <select id="queryClassesByStep" resultType="org.xiji.enty.Classes"> select * from classes where id=#{id} </select>
注:设置resultMap之后,使用resultMap接受查询结果,不是通过resultType接受查询结果
解释:
- <resultMap> 标签
- 定义了一个名为 stepByResultMap 的结果映射,指定其类型为 org.xiji.enty.Student。
- 基本属性映射
- <id>:映射 Student 类的 id 属性到数据库表中的 id 列。
- <result>:映射 Student 类的 studentName、studentAge 和 classId 属性分别到数据库表中的 studentName、studentAge 和 classId 列。
- <association> 标签
- 映射 Student 类的 classes 属性到 org.xiji.enty.Classes 类型的对象。
- 使用 select 属性指定一个子查询语句 queryClassesByStep,该查询将根据 classId 获取班级信息。
- column 属性指定用于子查询的列名,这里是 classId。
3)测试代码
/** * 分步查询 */ @Test public void testManyToOneByStep(){ Student student = manyToOneMapper.queryStudentAndClassesByStep(3); System.out.println(student.toString()); System.out.println(student.getClasses().toString()); }
4)测试结果
附录
1)ManyToOneMapper
package org.xiji.mapper; import org.apache.ibatis.annotations.Mapper; import org.xiji.enty.Student; @Mapper public interface ManyToOneMapper { /** * 级联属性赋值 */ Student queryStudentAndClasses(int id); /** * association */ Student queryStudentAndClassesByAssociation(int id); /** * 分步查询 */ Student queryStudentAndClassesByStep(int id); }
2)ManyToOneMapper.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.xiji.mapper.ManyToOneMapper"> <!--级联属性赋值--> <resultMap id="studentByJiLian" type="org.xiji.enty.Student"> <!--id映射--> <id property="id" column="id"/> <!--学生名字映射--> <result property="studentName" column="studentName"/> <result property="studentAge" column="studentAge"/> <result property="classId" column="classId"/> <!----> <result property="classes.id" column ="classId"/> <result property="classes.className" column="className"/> </resultMap> <select id="queryStudentAndClasses" resultMap="studentByJiLian"> select * from student left join classes on student.classId = classes.id where student.id=#{id} </select> <!--association赋值--> <resultMap id="associationByResultMap" type="org.xiji.enty.Student"> <!--id映射--> <id property="id" column="id"/> <!--学生名字映射--> <result property="studentName" column="studentName"/> <result property="studentAge" column="studentAge"/> <result property="classId" column="classId"/> <!--association--> <association property="classes" javaType="org.xiji.enty.Classes"> <id property="id" column="classId"/> <result property="className" column="className"/> </association> </resultMap> <select id="queryStudentAndClassesByAssociation" resultMap="associationByResultMap"> select * from student left join classes on student.classId = classes.id where student.id=#{id} </select> <!--分步查询--> <resultMap id="stepByResultMap" type="org.xiji.enty.Student"> <id property="id" column="id"/> <result property="studentName" column="studentName"/> <result property="studentAge" column="studentAge"/> <result property="classId" column="classId"/> <association property="classes" select="queryClassesByStep" column="classId"> <id property="id" column="id"/> <result property="className" column="className"/> </association> </resultMap> <!--第一步--> <select id="queryStudentAndClassesByStep" resultMap="stepByResultMap" > select * from student where id=#{id} </select> <!--第二步--> <select id="queryClassesByStep" resultType="org.xiji.enty.Classes"> select * from classes where id=#{id} </select> </mapper>
3)ManyToOneMapperTest
import org.apache.ibatis.annotations.Mapper; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; import org.xiji.enty.Student; import org.xiji.mapper.ManyToOneMapper; @SpringJUnitConfig(locations = {"classpath:springConfig.xml"}) public class ManyToOneMapperTest { @Autowired private ManyToOneMapper manyToOneMapper; /** * 级联属性赋值 */ @Test public void testManyToOne(){ Student student = manyToOneMapper.queryStudentAndClasses(1); System.out.println(student.toString()); } /** * association */ @Test public void testManyToOneByassociation(){ Student student = manyToOneMapper.queryStudentAndClassesByAssociation(2); System.out.println(student.toString()); System.out.println(student.getClasses().toString()); } /** * 分步查询 */ @Test public void testManyToOneByStep(){ Student student = manyToOneMapper.queryStudentAndClassesByStep(3); System.out.println(student.toString()); System.out.println(student.getClasses().toString()); } }
4)sql
studentSql
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '学生id', `studentName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生姓名', `studentAge` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '学生年龄', `classId` int NULL DEFAULT NULL COMMENT '班级id', PRIMARY KEY (`id`) USING BTREE, INDEX `classId`(`classId` ASC) USING BTREE, CONSTRAINT `classId` FOREIGN KEY (`classId`) REFERENCES `classes` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, '张三', '18', 1); INSERT INTO `student` VALUES (2, '李四', '20 ', 1); INSERT INTO `student` VALUES (3, '小久', '21', 1); INSERT INTO `student` VALUES (4, 'xiji', '22', 1); SET FOREIGN_KEY_CHECKS = 1;
classesSql
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for classes -- ---------------------------- DROP TABLE IF EXISTS `classes`; CREATE TABLE `classes` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '班级id', `className` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '班级名称', PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of classes -- ---------------------------- INSERT INTO `classes` VALUES (1, '一班'); INSERT INTO `classes` VALUES (2, '二班'); INSERT INTO `classes` VALUES (3, '三班'); INSERT INTO `classes` VALUES (5, '五班'); SET FOREIGN_KEY_CHECKS = 1;