MyBatis中多对一关系的三种处理方法
目录
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 mapperPUBLIC "-//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 {@Autowiredprivate ManyToOneMapper manyToOneMapper;/*** 级联属性赋值*/@Testpublic void testManyToOne(){Student student = manyToOneMapper.queryStudentAndClasses(1);System.out.println(student.toString());}/*** association*/@Testpublic void testManyToOneByassociation(){Student student = manyToOneMapper.queryStudentAndClassesByAssociation(2);System.out.println(student.toString());System.out.println(student.getClasses().toString());}/*** 分步查询*/@Testpublic 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;