ResultMap
resultmap是我们自定义结果集映射.可以应付复杂映射的情况,
例如 ,简单的自定义映射,一对多,和多对一
resultMap 和 resultTyep 在select标签中只能使用一个
这种情况是不允许的,
resultMap
简单用法 查询
<select id="selectStudent" resultMap="My01">
select * from student1
</select>
这个是简单的resultMap 学生的 自定义映射
如果这个时候我们在xml文件中设置的 自动驼峰命名 标签是无用的
<setting name="mapUnderscoreToCamelCase" value="true"/>
<resultMap type="student1" id="My01">
<id column="s_id" property="sId"/>
<result column="s_age" property="sAge"/>
<result column="s_name" property="sName"/>
</resultMap>
id : 为主键列的封装
result : 为普通列的封装
column : 对应这数据的列名 必须一致
proprety : 指定对应的javaBean中的属性
pass : 如果我们没有在写全javaBean中的属性,那么Myabtis会自动的帮我们封装javaBean中的属性
但是在实际开发中,我们需要将javaBean中的属性,和result属性一一对应,
当我们有多个学生,对应这一个班级的时候,这时候resultMap就可以使用它更强大的功能了
就如mybatis的开发文档所说,世界真的那么简单就好了
在一对一的情况下,我们有不同的写法
比如简答的,
<resultMap type="student1" id="myAndstu01">
<id column="S_ID" property="sId"/>
<result column="S_NAME" property="sName"/>
<result column="S_AGE" property="sAge"/>
<result column="STUC_CLASSID" property="cClassId"/>
<result column="MYC_CLASSID" property="myClass.cClassId"/>
<result column="MYC_CLASSNAME" property="myClass.cClassName"/>
</resultMap>
<select id="selectStudentAndMyClass" resultMap="myAndstu01">
select STU.S_ID S_ID,STU.S_NAME S_NAME,STU.S_AGE S_AGE,STU.C_CLASSID STUC_CLASSID,MY.C_CLASSID myC_CLASSID,MY.c_CLASSNAME Myc_CLASSNAME
from student1 stu,myclass my
where STU.C_CLASSID=MY. C_CLASSID
<!--
条件 where id=#{id}
-->
</select>
<result column="MYC_CLASSID" property="myClass.cClassId"/>
<result column="MYC_CLASSNAME" property="myClass.cClassName"/>
在这里我们使用的 myClass.cClassId ,myClass也就是javaBean中的属性,cClassId也就是myClass中的属性
<!-- 第二种 -->
<resultMap type="student1" id="myAndstu02">
<id column="S_ID" property="sId"/>
<result column="S_NAME" property="sName"/>
<result column="S_AGE" property="sAge"/>
<result column="STUC_CLASSID" property="cClassId"/>
<association property="myClass" javaType="com.prosay.entity.MyClass">
<id column="MYC_CLASSID" property="cClassId"/>
<id column="MYC_CLASSNAME" property="cClassName"/>
</association>
</resultMap>
<select id="selectStudentAndMyClass" resultMap="myAndstu02">
select STU.S_ID S_ID,STU.S_NAME S_NAME,STU.S_AGE S_AGE,STU.C_CLASSID STUC_CLASSID,MY.C_CLASSID myC_CLASSID,MY.c_CLASSNAME Myc_CLASSNAME
from student1 stu,myclass my
where STU.C_CLASSID=MY. C_CLASSID
</select>
看到了第二种方式,我们这使用了联合标签 associaction
其中常用的标签,有
property 对应这联合的属性
javaType 封装的类型
<!-- 第三种方式 -->
<resultMap type="student1" id="myAndstu03">
<id column="S_ID" property="sId"/>
<result column="S_NAME" property="sName"/>
<result column="S_AGE" property="sAge"/>
<result column="C_CLASSID" property="cClassId"/>
<!-- 使用association定义封装规则 -->
<!--
select 表明当前属性是调用select指定方法
查询结果
column 指定将哪一列的值传给这个方法
流程:使用select指顶的方法 查出对象(传入column指定的这列参数)查出对象,
并封装给property指定的属性
-->
<association property="myClass"
select="com.prosay.mapper.MyClassMapper.selectMyClassById"
column="C_CLASSID"
>
</association>
</resultMap>
第三种方式我们使用了分步查询
这里使用了 association 中其他的属性
select 需要查询的其他的id
column 接受上一个查询后的结果,传过来的值
在下面我们看到了执行了两条sql语句
我们在使用分步查询的情况下,可以使用
<!-- 启动延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 是否加载全部 -->
<setting name="aggressiveLazyLoading" value="false"/>
settings中的这两个标签
一般我们也可以在单个操作语句上添加,但是不推荐,因为后期维护更加困难
当我们使用延迟加载的时候,如果我们不使用其他sql语句的数据的时候,他将不会查询
例如
这里我查询了一条学生表的信息,它只执行了一条sql语句
下面我们来尝试,一个班级,查询多个学生的情况
<!-- one 嵌套结果集的方式,使用collection标签定义关联的集合类型的属性封装规则 -->
<resultMap type="myclass" id="one">
<id column="myc_classid" property="cClassId"/>
<result column="MYclassname" property="cClassName"/>
<collection property="student1List" ofType="student1">
<!-- 定义集合中元素的封装规则 -->
<id column="STUS_ID" property="sId"/>
<result column="STUS_NAME" property="sName"/>
<result column="STUS_AGE" property="sAge"/>
<result column="STUC_CLASSID" property="cClassId"/>
</collection>
</resultMap>
在这里我们看见新的标签 collection ,这个标签也就是定义集合封装规则的
<!-- 分步查询 -->
<resultMap type="myclass" id="two">
<id column="C_CLASSID" property="cClassId"/>
<result column="c_classname" property="cClassName"/>
<collection property="student1List"
select="com.prosay.mapper.StudentMapper.selectStudentBycClassIdAndMyClass"
column="C_CLASSID"
fetchType="lazy"
>
</collection>
</resultMap>
<select id="selectMyClassAndStudentPlusByCClassIdStep" resultMap="two">
select C_CLASSID,c_classname from myclass where C_CLASSID = #{id}
</select>
其中有
property : 当前要封装的javaBean中 List<Student>(我们这里查找的是多个学生)中的字段名称 student1list
ofType : 指定List<Student> 中的元素 ,这里是 student
第二种方式 : 分步查询
<!-- 分步查询 -->
<resultMap type="myclass" id="two">
<id column="C_CLASSID" property="cClassId"/>
<result column="c_classname" property="cClassName"/>
<collection property="student1List"
select="com.prosay.mapper.StudentMapper.selectStudentBycClassIdAndMyClass"
column="C_CLASSID"
fetchType="lazy"
>
</collection>
</resultMap>
<select id="selectMyClassAndStudentPlusByCClassIdStep" resultMap="two">
select C_CLASSID,c_classname from myclass where C_CLASSID = #{id}
</select>
这里基本上和assocaition一样,select,column,
扩展:多列的值传递过去,
将多列的值封装map传递,
column="{key1=column1,key2=column2}"
#{key1} = 1 And #{key2}
fetchType="lazy" 表示使用延迟加载
-lazy 延迟
-eager 立即
可以将这一列换成上面扩展的内容