Mybatis定制映射(resultMap)
Mybatis框架在Mapper文件中,将查询到的结果封装到我们指定的实体对象中的时候,默认是遵循同名映射的规则。
当我们实体的属性和数据库列名不同时,可以在sql中使用as为列起一个于实体属性相同的别名
如果映射关系比较复杂,我们也可以通过定制resultMap来指定列名和实体属性的映射
一、单表查询
使用方式在注释中说明
<?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">
<!-- namespace配置对应的DAO接口 -->
<mapper namespace="wangda.dao.UserDAO">
<!-- id为该resultMap的唯一标识 type为封装的目标实体 与select中的resultType同义 -->
<resultMap id="user_resultMap" type="wangda.entity.User">
<!-- id标签为主键专属 column为列名 property为属性名 -->
<id column="id" property="id"/>
<!-- result为普通列-->
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="gender" property="gender"/>
<result column="regist_time" property="registTime"/>
</resultMap>
<!-- 不再使用resultType用resultMap代替, 内容填resultMap的唯一标识id-->
<select id="queryUserByUsername" resultMap="user_resultMap">
select id, username, password, gender, regist_time
from k_user
where username like concat('%',#{username},'%')
</select>
</mapper>
二、级联查询(一对一关系)
当我们涉及到多表查询时,其数据封装仅仅依靠Mybatis默认的同名规则已经不太够用了。因为可能涉及到这样的实体类封装,passenger类中有passport的引用类型变量。
这样我们就需要resultMap指定映射关系来解决数据绑定的问题了
与单表查询不同的是,我们需要一个association标签来对对象引用类型的属性进行详细数据封装指定(具体使用请参照代码)
<?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="wangda.dao.PassengerDAO">
<resultMap id="passenger_passport" type="wangda.entity.Passenger">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<!--association用于详解数据封装,javaType指定该引用类属性的实体类-->
<association property="passport" javaType="wangda.entity.Passport">
<!--association的内部与resultMap单表查询时的使用方式相同-->
<id column="passId" property="id"/>
<result column="nationality" property="nationality"/>
<result column="expire" property="expire"/>
</association>
</resultMap>
<select id="queryPassengerById" resultMap="passenger_passport">
<!--级联查询、关联查询-->
select k_passengers.id,k_passengers.name,k_passengers.sex,k_passengers.birthday,
k_passports.id as passId,k_passports.nationality,k_passports.expire
from k_passengers join k_passports
on k_passengers.id = #{id}
</select>
</mapper>
三、级联查询(一对多关系)
一对多关系在数据库中的表现:多的那个表存放一的id作为外键
一对多关系在面向对象中的表现:一创建一个多的实体的List
所以导致数据封装出现一个新的问题,如果将多方打包实体,再将其打包为List存入一方的属性中。方法就是
使用collection标签代替association标签,代表这是一个集合引用类型
多对一关系的resultMap和一对一关系类似,只是方法的返回为集合类型
<?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="wangda.dao.DepartmentDAO">
<resultMap id="department_employees" type="wangda.entity.Department">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="location" property="location"/>
<!--cllection表示集合 此外需要使用ofType指定集合的泛型-->
<collection property="employees" ofType="wangda.entity.Employee">
<id column="emp_id" property="id"/>
<result column="name" property="name"/>
<result column="salary" property="salary"/>
</collection>
</resultMap>
<select id="queryDepartmentById" resultMap="department_employees">
select k_departments.id,k_departments.name,k_departments.location,
k_employees.id emp_id,k_employees.name emp_name,k_employees.salary
from k_departments join k_employees
<!-- on是在临时表生成时筛选 -->
on k_departments.id = k_employees.dept_id
where k_departments.id = #{id}
</select>
</mapper>
四、级联查询(多对多关系)
在多对多关系中,resultMap中标签的使用并没有新的出现,根据需要封装的数据是引用类型还是集合类型选择association和collection就可以了。
但在多对多关系中值得****的是面对对象中多对多关系的表示方式和多对多关系查询时的级联查询如何写。
多对多关系在面向对象中的表示方式是:在双方实体中均加入对方的集合类型的属性
级联查询如何书写:首先使用其中一方联合中间表做,id=?_id筛选出和其中一方关联的数据,然后再join另一个张表再选择另一方和中间表关联的数据
<?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="wangda.dao.SubjectDAO">
<resultMap id="subject_student" type="wangda.entity.Subject">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="grade" property="grade"/>
<collection property="students" ofType="wangda.entity.Student">
<id column="stu_id" property="id"/>
<result column="stu_name" property="name"/>
<result column="sex" property="sex"/>
</collection>
</resultMap>
<select id="querySubjectById" resultMap="subject_student">
select k_subjects.id, k_subjects.name,k_subjects.grade,
k_students.id stu_id,k_students.name stu_name, k_students.sex
from k_subjects join k_stu_sub
on k_subjects.id = k_stu_sub.subject_id
join k_students
on k_students.id = k_stu_sub.student_id
where k_subjects.id = #{id}
</select>
</mapper>
五、总结
在实体类中 一方,添加多方集合;多方添加一方对象
在resultMap中:
持有对象关系属性,使用:
<association property="对应属性" javaTpye="封装类"
持有集合关系属性,使用:
<collection property="对应属性" ofType="封装类"
如果本文对您有帮助,请帮我点个赞哦