ResultMap
基本使用
适合使用返回值是自定义实体类的情况
映射实体类的数据类型
id:resultMap的唯一标识
column: 库表的字段名
property: 实体类里的属性名
resultType可以直接返回给出的返回值类型,比如String、int、Map,等等,其中返回List也是将返回类型定义为Map,然后mybatis会自动将这些map放在一个List中,resultType还可以是一个对象
<?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:当前库表映射文件的命名空间,唯一的不能重复 -->
<mapper namespace="com.hao947.sql.mapper.PersonMapper">
<!-- type:映射实体类的数据类型 id:resultMap的唯一标识 -->
<resultMap type="person" id="BaseResultMap">
<!-- column:库表的字段名 property:实体类里的属性名 -->
<id column="person_id" property="personId" />
<result column="name" property="name" />
<result column="gender" property="gender" />
<result column="person_addr" property="personAddr" />
<result column="birthday" property="birthday" />
</resultMap>
<!--id:当前sql的唯一标识
parameterType:输入参数的数据类型
resultType:返回值的数据类型
#{}:用来接受参数的,如果是传递一个参数#{id}内容任意,如果是多个参数就有一定的规则,采用的是预编译的形式select
* from person p where p.id = ? ,安全性很高 -->
<!-- sql语句返回值类型使用resultMap -->
<select id="selectPersonById" parameterType="java.lang.Integer"
resultMap="BaseResultMap">
select * from person p where p.person_id = #{id}
</select>
<!-- resultMap:适合使用返回值是自定义实体类的情况
resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型 -->
<select id="selectPersonCount" resultType="java.lang.Integer">
select count(*) from
person
</select>
<select id="selectPersonByIdWithMap" parameterType="java.lang.Integer"
resultType="java.util.Map">
select * from person p where p.person_id= #{id}
</select>
</mapper>
resultType是结果集的一个映射,可以简单的写成resultType="map"或者resultType="hashmap",其中"map"和"hashmap"都是mybatis能够识别的别名,写成"java.util.HashMap"当然也没有问题,在java代码端,是这么写的:
List<Map<String,Object>> list =sqlSession.selectList("User.test");
for(Map<String,Object> map :list){
System.out.println(map.get("id")); //通过map.get("key"),就可以获取你需要的结果。
}
****************************************MyBatis如何写条件查询**************************************************
基本标签语句
<select id="" parameterType="" resultMap="xxResultMap">
sql语句
</select>
id标识该查询;parameterType指参数类型;resultMap指返回类型,这里与下面设置的resultMap关联。
作为查询语句,返回结果是一个List,当选择性的输出字段时,需要添加一个ResultMap属性与之关联。id标识主键,result标识字段。property指向实体类的属性,column指向数据库列名。
拼接条件之前需要加where关键字。
因为可能没有查询条件,所以写成where 1=1。或者用查询的必要条件拼接。
拼接条件为“=”的情况
用 if 判断是否为空,不为空则用AND拼接。变量写成#{xx}
拼接条件为"LIKE"模糊查询,适用于MySql数据库
if 条件一样,另外要用concat作拼接。
like concat('%', #{userName}, '%')
oracle数据库中,模糊查询报错“参数缺失”。
模糊查询的格式问题
法一:用"||"分隔。like '%' || #{userName} || '%'
法二:like concat(concat('%', #{userName}), '%')
Mybatis中实现传统多条件查询
数据表student如下:
已有的数据如下:
我们现在进行如下查询:
查询表中grade>70 age>20 的女生
SQL语句自然如下:
select * from student where sex="女" and grade>70 and age>20;
在数据库中直接执行这句SQL语句:
现在使用Mybatis完成这个操作:
在student.xml中添加如下配置语句:
测试语句:
因为传入的参数有多个 所以需要使用Map来传递
可以得到刚才的答案
这样的查询引出了下面三个问题:
1.无法灵活的添加条件
2.如果只想按照年龄与成绩查询 不能在sex处赋值为空 仍需要新的SQL语句
3.如果采用拼接的方式(其实这样也算改变了SQL语句)非常容易产生格式错误或者顺序错误
动态SQL:if
应用场景1:
假设我们现在需要对student表进行两种操作:
- 查询所有信息
- 根据专业名进行模糊查询
按照现在的方式 我们必须提供2条SQL语句分别应对这两种操作
此时我们介绍一下动态SQL中的if标签在这里的使用:
我们来解释一下这条SQL语句:
这条语句意味着:如果没有传入参数major 那么执行select * from student 即查询所有
如果传入了参数majo 那么执行这句模糊查询
注意:这里的<if test>中的test仅为语法 实际等于if()
测试一下这两种情况:
第二种情况:
应用场景2:
现在需要进行这种查询:
根据姓名与专业来查询数据:如果姓名为空 将只根据专业来查询 如果姓名不为空 将只根据姓名来查询
传统SQL语句如下:
select * from student where name=#{name} and major=#{major};
在上面的SQL语句中我们发现 如果#{name}为空 那么查询结果直接为空 并不能进入“根据专业查询”这一个环节
我们在测试中发现 根据name来查询可以得到正确结果 而name为空 试图根据major来查询时报错
这是因为当major为空 name不为空时 SQL语句如下:
我们发现问题出在这个where上
如何解决这个问题呢?
<where>标签可以自动进行判断
如果任何条件都不成立 那么在SQL语句中不会出现where
如果有条件成立 且这个标签返回的内容是以“AND”或“OR”开头的 会自动去掉这个多出来的and或者or
在测试代码中:
<!-- 导出所有数据 -->
<select id="exportAll" resultMap="map">
SELECT t1.MEDICAL_ID AS medicalId,
ADDRESS AS address,
DATE_START AS dateStart,
DATE_END AS dateEnd,
TIME_START AS timeStart,
TIME_END AS timeEnd,
AMBULANCE_NUM AS ambulanceNum,
NAME AS name,
PHONE AS phone
FROM PM.T_MEETING_MEDICAL t1,PM.T_MEETING_MEDICAL_DOCTOR t2
<where>
t1.MEDICAL_ID = t2.MEDICAL_ID
<if test="address != null and address !='' ">
AND ADDRESS = #{address} </if> <if test="dateStart != null and dateStart !='' "> AND DATE_START = #{dateStart} </if> <if test="dateEnd != null and dateEnd !='' "> AND DATE_END = #{dateEnd} </if> <if test="meetingId != null and meetingId !='' "> AND MEETING_ID = #{meetingId} </if> </where> ORDER BY t1.ADDRESS,t1.DATE_START </select>
public List<Map<String, Object>> exportAll(MeetingMedicalVo meetingMedicalVo);//接口
resultType*****************************************************************************************************************************
resultType是结果集的一个映射,可以简单的写成resultType="map"或者resultType="hashmap",其中"map"和"hashmap"都是mybatis能够识别的别名,写成"java.util.HashMap"当然也没有问题。
说白了,即便使用resultType,mybatis也将使用resultMap进行查询结果的映射。只是映射过程我们是看不见的,方便写代码。
resultMap中id和result的区别:这两者之间的唯一不同是id 表示的结果将是当比较对象实例时用到的标识属性。这帮助来改进整体表现,特别是缓存和嵌入结果映射(也就是联合映射) 。官方原话,简单的理解,就是当某一个列是唯一索引时,用id标签,提高效率。
MyBatis拥有自动封 装功能,只要你提供了返回类型,MyBatis会根据自己的判断来利用查询结果封装对应的对象,所以前面的简单查询中,如果你不在resultMap中明 确的指出id对应哪个字段,title对应哪个字段,MyBatis也会根据自身的判断来帮你封装,MyBatis的自身判断是把查询的field或其对 应的别名与返回对象的属性进行比较,如果相匹配且类型也相匹配,MyBatis则会对其进行赋值。