注:当sql语句需要参数时,可以用parameter指定参数类型,但事实上即使不予指定mybatis也可以自行解析。
当sql语句是查询时,需要指定resultType,即返回值类型,但增删改是受影响的行数,不需要指定
1.两大作用(配置结果类型):
- 解决数据表列名和javabean属性不一致的问题
- 提供一对一、一对多、多对多等高级映射
2.当实体类对象与数据库字段不匹配时:
- 方案1:使用sql语句as 起别名的方式修改查询结果的名称
- 方案2:使用resultMap,完成数据库字段与实体类属性的映射。(可被多个sql语句共用)
<!--
解决列名和实体类属性不匹配方法
1. select id,name ,age,sex,height,s_address as address from student_tb where id = #{id}
2. 使用 resultmap
1.声明resultMap标签 在内部完成映射
2.查询结果使用resultMap="studentMap1" 应用声明的resultMap的id
-->
<!-- 定义一个 resultMap
使用resultMap 完成 数据库列名到 实体类的映射
<id property="id" column="id"></id> 实体类属性与数据表 主键列名 映射
<result property="name" column="name"></result> 实体类属性与 普通列名 映射
-->
<resultMap id="studentMap1" type="com.qfedu.entity.Student">
<id property="id" column="id"></id> <!-- 主键-->
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
<result property="address" column="s_address"></result>
</resultMap>
<select id="findStudentById" resultMap="studentMap1" parameterType="int">
select id,name ,age,sex,height,s_address from student_tb where id = #{id}
</select>
3.一对一:
使用一对一查询时,在一个实体类中添加另一实体类属性。用resultMap实现映射关系时,使用association连接,javaType为封装的类型。
如下:在Score中添加Student属性,以及getter和setter方法
映射关系
<!--定义 resultType 来接收getAllScoreWithStudent2 查询结果-->
<!--
一对一查询
<association 解决一对一问题
property="student" 对应Score 中 student属性
column="studentid" 对应Score_tb 与 student_tb关联的外键 列名,可以不写
javaType="Student" 将其他非Score 中的字段写入Student 类
<result property="name" column="name"></result> 写入student对应的属性
-->
<resultMap id="scoreMap1" type="Score">
<id column="scoreid" property="scoreid"></id>
<result column="couresename" property="couresename"></result>
<result column="score" property="score"></result>
<result column="studentid" property="studentid"></result>
<association property="student" column="studentid" javaType="Student" >
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
<result property="sAddress" column="s_address"></result>
</association>
</resultMap>
<select id="getAllScoreWithStudent2" resultMap="scoreMap1">
SELECT a.*,b.* FROM score_tb a LEFT JOIN student_tb b ON a.studentid = b.id;
</select>
3.一对多
一对多是在一个类中包含另一个类list的集合,在映射时,使用Collection,ofType为封装类型。注意封装类型与一对一不同
如下:在学生实体中。添加score集合
映射关系:
<!--
<collection 解决一对多问题
property="scoreList" 将collection 组成的成绩集合放置到 student对象中
column="id" 根据相同 的学生id组成集合
ofType="Score" 将学生id组成集合 每一个item 生成一个 Score
-->
<resultMap id="studentWithScoreMap" type="Student">
<id column="id" property="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
<result property="sAddress" column="s_address"></result>
<collection property="scoreList" column="id" ofType="Score">
<id property="scoreid" column="scoreid"></id>
<result property="couresename" column="couresename"></result>
<result property="score" column="score"></result>
<result property="studentid" column="id"></result>
</collection>
</resultMap>
<!-- 查询所有的学生并包含成绩-->
<select id="findAllStudentWithScore" resultMap="studentWithScoreMap">
SELECT * FROM student_tb a LEFT JOIN score_tb b ON a.id = b.studentid
</select>
4.多对多
表之间的多对多关系稍微复杂,需要一个中间表来表示
中间表有三个字段,其中两个字段分别作为外键指向各自一方的主键,由此通过中间表来表示多对多关系,通过一个表联合另一个中间表可以表示为一对多关系。
多对多,其实可以从一方到另一方表示为一对多关系,反之亦然
student_role_tb : id,studentid, roieid
如:查找职位,并包含对应的学生信息,一个职位可能有很多学生,如组长,一对多关系
第一步: 在role实体中添加student属性,
第二步:书写映射关系,按一对多即可
<resultMap id="roleWithStudent" type="Role">
<id property="roleid" column="roleid"></id>
<result property="rolename" column="rolename"></result>
<!--property role表中的属性-->
<collection property="studentList" column="studentid" ofType="Student">
<id column="id" property="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
<result property="sAddress" column="s_address"></result>
</collection>
</resultMap>
<select id="findAllRoleWithStudent" resultMap="roleWithStudent">
select r.*,sr.studentid, s.* from role_tb r LEFT JOIN student_role_tb sr on r.roleid=sr.roleid
LEFT JOIN student_tb s on s.id = sr.studentid
</select>
反之亦然,如:查找学生并包含职位信息,也是一对多关系
第一步: 在student实体中添加role属性,
第二步:书写映射关系,按一对多即可
<!--多对多中的一对多-->
<resultMap id="studentWithRole" type="Student">
<id property="id" column="id"></id>
<result property="name" column="name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="height" column="height"></result>
<result property="sAddress" column="s_address"></result>
<collection property="roleList" column="roleid" ofType="Role">
<id property="roleid" column="roleid"></id>
<result property="rolename" column="rolename"></result>
</collection>
</resultMap>
<select id="findAllStudentWithRole" resultMap="studentWithRole">
select s.*,sr.studentid, r.* from student_tb s LEFT JOIN student_role_tb sr on s.id = sr.studentid
LEFT JOIN role_tb r on r.roleid = sr.roleid;
</select>