一、ResultMap介绍
-
ResultMap元素是mybatis中最强大的元素。
-
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
-
ResultMap 最优秀的地方在于,虽然你已经对他相当了解了,但是根本就不需要显式地调用他们。
-
属性介绍
resultMap中:
column:数据库中的字段
property:实体类中的属性
id:resultMap的名字
type:对应的实体类
然后在引用它的语句中设置
resultMap
属性就行了(注意我们去掉了resultType
属性) -
使用示例:
在mapper文件中:
<!-- 显式配置resultMap--> <resultMap id="userResultMap" type="User"> <result property="id" column="user_id" /> <result property="username" column="user_name"/> <result property="password" column="hashed_password"/> </resultMap> <!-- 使用--> <select id="selectUsers" resultMap="userResultMap"> select user_id, user_name, hashed_password from some_table where id = #{id} </select>
这样数据库字段:user_id, user_name, hashed_password就可以映射到实体类中的属性:id,username,password中去了
二、多对一
首先搭建环境,创建两个有依赖的表:
每个老师对应多个学生,多个学生对应一个老师
教师表:
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
`id` int(10) NOT NULL,
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '张老师');
学生表:
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(10) NOT NULL,
`name` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`tid` int(10) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `fktid`(`tid`) USING BTREE,
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '小明', 1);
INSERT INTO `student` VALUES (2, '小虎', 1);
INSERT INTO `student` VALUES (3, '萧红', 1);
INSERT INTO `student` VALUES (4, '小李', 1);
INSERT INTO `student` VALUES (5, '小王', 1);
实体类:
public class Student {
private int id;
private String name;
//一个学生对应一个老师
private Teacher teacher;
}
public class Teacher {
private int id;
private String name;
}
搭建环境并测试:
1、思路一
按照查询嵌套处理
查询所有学生的信息,根据查询出来的学生tid寻找对应的老师 :子查询
mapper文件:
<select id="studentList" resultMap="StudentTeacher">
select * from student
</select>
<resultMap id="StudentTeacher" type="entity.Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--复杂的属性需要单独处理 对象:association 集合:collection-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher">
</association>
</resultMap>
<select id="getTeacher" resultType="entity.Teacher">
select * from teacher where id=#{tid}
</select>
结果:
可以看到student类中的的属性对象teacher就关联起来了
2、思路二
按照结果嵌套处理
先在sql中查出所有信息,再根据结果一一对应
mapper:
<select id="studentList2" resultMap="StudentTeacher2">
select s.id sid,s.name sname,t.id ttid,t.name tname
from student s,teacher t
where s.tid=t.id
</select>
<resultMap id="StudentTeacher2" type="entity.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="id" column="ttid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
结果:
3、说明:
此处的tid名字不一定需要一一对应,mybatis会根据情况自动判断
三、一对多
数据库同上
实体类:
public class Student {
private int id;
private String name;
private int tid;
}
public class Teacher {
private int id;
private String name;
//一个老师对应多个学生
private List<Student> students;
}
测试:
1、思路一
按照查询嵌套处理
先查询老师信息,再根据老师的id查找学生 :子查询
mapper文件:
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id =#{tid}
</select>
<resultMap id="TeacherStudent2" type="entity.Teacher">
<result property="id" column="id"/>
<collection property="students" javaType="ArrayList" ofType="entity.Student" select="getStudentByTeachetId" column="id">
</collection>
</resultMap>
<select id="getStudentByTeachetId" resultType="entity.Student">
select * from student where tid=#{tid}
</select>
结果:
可以看到Teacher类中的的List属性就关联起来了
2、思路二
按照结果嵌套处理
先在sql中查出所有信息,再根据结果一一对应
mapper:
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname ,t.name tname,t.id tid
from student s,teacher t
where s.tid=t.id and t.id =#{tid}
</select>
<resultMap id="TeacherStudent" type="entity.Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--复杂的属性需要单独处理 对象:association 集合:collection
javaType 指定属性的类型
集合中的泛型信息用ofType处理
-->
<collection property="students" ofType="entity.Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>
结果:
可以看到Teacher类中的的List属性就关联起来了
四、小结
1、关联–association 多对一
2、集合–collection 一对多
3、JavaType & ofType
1、JavaType 用来指定实体类中属性的类型
2、ofType用来指定映射到List或者集合中的实体类型,泛型中的约束类型
4、注意:
sql的可读性
注意一对多多对一中属性名和字段对应的问题
慢Sql问题