Mybatis(4)——ResultMap
<!--自定义某个javaBean的封装规则 type:自定义规则的Java类型 id:唯一id,方便引用 --> <resultMap type="entity.stu" id="MySimpleStu"> <!--指定主键列的封装规则 id定义主键会底层有优化; column:指定查出来的数据表的哪一列 property:指定对应的javaBean属性 --> <id column="id" property="id"/> <!-- 定义普通列封装规则 ,这里是因为名字不一样修改一下封装规则--> <result column="gender" property="stuGender"/> <!-- 其他不指定的列会自动封装:但是我们只要写resultMap就把全部的映射规则都写上。 --> <result column="name" property="name"/> <result column="addr" property="addr"/> </resultMap> <!-- resultMap:自定义结果集映射规则; --> <select id="getStudent" resultMap="MySimpleStu"> select * from student where id=#{id} </select> <!-- 需求:级联查询,查询学生的同时查询他的college --> <select id="getStudentandConnege01" resultMap="MyDifficultStu"> SELECT s.id id,s.name name,gender,addr,s.c_id cid,c.name cname FROM student s ,college c WHERE s.c_id=c.collegdid AND s.id=#{id} </select> <select id="getStudentandConnege02" resultMap="MyDifficultStu2"> SELECT s.id id,s.name name,gender,addr,s.c_id cid,c.name cname FROM student s ,college c WHERE s.c_id=c.collegdid AND s.id=#{id} </select> <!-- 第一种方式: 联合查询:级联属性封装结果集 只需要在resultMap中指定级联就可以了 --> <resultMap type="entity.stu" id="MyDifficultStu"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="addr" property="addr"/> <result column="gender" property="stuGender"/> <result column="cid" property="college.id"/> <result column="cname" property="college.name"/> </resultMap> <!-- 第二种方式:同样是级联查询,但是使用了<association>的标签 使用association定义关联的单个对象的封装规则; --> <resultMap type="entity.stu" id="MyDifficultStu2"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="addr" property="addr"/> <result column="gender" property="stuGender"/> <!-- association可以指定联合的javaBean对象 property="dept":指定哪个属性是联合的对象 javaType:指定这个属性对象的类型[不能省略] --> <association property="college" javaType="entity.college"> <id column="cid" property="id"/> <result column="cname" property="name"/> </association> </resultMap> <!-- 使用association进行分步查询: 第三种方法
首先根据学生id找到学生记录,然后找到大学id 根据大学id找到大学信息 把查询到的大学信息填充到学生对象中。 --> <resultMap type="entity.stu" id="StuByStep"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="addr" property="addr"/> <result column="gender" property="stuGender"/> <!-- association定义关联对象的封装规则 select:表明当前属性是调用select指定的方法查出的结果 column:为被调用的select方法传入参数 流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性 --> <association property="college" select="Mapperinterface.collegeMapper.getcollege" column="c_id"> </association> </resultMap>
根据大学的id得到大学的信息,以及大学中的所有的学生,这里也是使用合并查询以及分步查询两种方式
<select id="getCollegeandAllStu" resultType="entity.college" resultMap="getCollegeandAllStuResultMap"> select s.id id,s.name name,s.gender gender,addr,c.name cname,collegdid from student s left join college c on c_id=collegdid where collegdid=#{id} </select> <resultMap id="getCollegeandAllStuResultMap" type="entity.college"> <id column="collegdid" property="id"/> <result column="cname" property="name"/> <collection property="students" ofType="entity.stu"> <id column="id" property="id"/> <result column="name" property="name"/> <result column="gender" property="stuGender"/> <result column="addr" property="addr"/> </collection> </resultMap> <!-- 针对于查询一个List的结果非常简单,注意类型就是List中的元素的类型 --> <select id="getAllstu" resultType="entity.stu"> SELECT * FROM student where c_id=#{id} </select> <select id="getCollegeandAllStuByStep" resultMap="getCollegeandAllStuByStepResultMap"> SELECT * FROM college where collegdid=#{id} </select> <resultMap id="getCollegeandAllStuByStepResultMap" type="entity.college"> <id column="collegdid" property="id"></id> <result column="name" property="name"></result> <collection property="students" select="getAllstu" column="collegdid"/> </resultMap>
上面给出了分段查询的例子
<resultMap id="getCollegeandAllStuByStepResultMap" type="entity.college"> <id column="collegdid" property="id"></id> <result column="name" property="name"></result> <collection property="students" select="getAllstu" column="collegdid"/> </resultMap>
其中<collection>里面的column就是传入的参数,如果想要传入多值,使用 {param1=..,param2=...}的方式
例如
<collection property="students" select="getAllstu" column="{id=collegdid,anotherid=外面传入的一个值}"/>
另外
<collection>里面的fetchType默认是lazy,延迟加载,改为eager就是立即加载,不用修改全局配置
<!-- 扩展:多列的值传递过去: 将多列的值封装map传递; column="{key1=column1,key2=column2}" fetchType="lazy":表示使用延迟加载; - lazy:延迟 - eager:立即 -->
<!-- =======================鉴别器============================ -->
<!-- <discriminator javaType=""></discriminator>
鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为
封装Employee:
如果查出的是女生:就把部门信息查询出来,否则不查询;
如果是男生,把last_name这一列的值赋值给email;
-->
<resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpDis">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<!--
column:指定判定的列名
javaType:列值对应的java类型 -->
<discriminator javaType="string" column="gender">
<!--女生 resultType:指定封装的结果类型;不能缺少。/resultMap-->
<case value="0" resultType="com.atguigu.mybatis.bean.Employee">
<association property="dept"
select="com.atguigu.mybatis.dao.DepartmentMapper.getDeptById"
column="d_id">
</association>
</case>
<!--男生 ;如果是男生,把last_name这一列的值赋值给email; -->
<case value="1" resultType="com.atguigu.mybatis.bean.Employee">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="last_name" property="email"/>
<result column="gender" property="gender"/>
</case>
</discriminator>
</resultMap>