MyBatis——Mapper映射文件

一、Mapper文件简述
 Mapper映射文件即前面提到的XxxMapper.xml配置文件,该文件将Mapper接口及其接口方法通过配置的方式进行映射,XxxMapper.xml的主要内容就是各个接口及其接口方法要实现的SQL逻辑。一个XxxMapper.xml文件只能映射一个接口,这也是由dtd约束定义的:

<!ELEMENT mapper (cache-ref | cache | resultMap* | parameterMap* | sql* | insert* | update* | delete* | select* )+>

二、Mapper文件的配置内容
 1、insert、update、delete、select标签分别对应一种数据库操作,其中在执行insert操作后,如果想获取到刚插入的记录在数据库中的id(进行如下配置后插入记录后产生的id才会反射注入到程序中的运行时对象中),需要设置如下:

<!-- mysql数据库 -->
<insert id="add" parameterType="student" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO students(name,schoolName,age,birth)
    VALUES(#{name},#{schoolName},#{age},#{birth})
</insert>  

<!-- Oracle数据库 -->
<insert id="add" parameterType="Person">
	<!-- 在插入数据之前先获取该条记录主键的值,并反射注入到对象中 -->
    <selectKey order="BEFORE" keyProperty="id" resultType="_int">
        select crm_seq.nextval from dual
    </selectKey>
    insert into tbl_person(name,salary,birth,registerTime)
    values(#{name},#{salary},#{birth},#{registerTime});
</insert>  

  Tip:insert、update、delete、select标签中并不是只可以写对应类型的SQL语句,各个标签中都可以写任何SQL语句,比如在<select>标签中写delete语句也是可以正确运行的,其他也是如此,但不推荐这么做
 2、parameterType属性:输入参数类型,支持简单类型、POJO对象、Map、口袋POJO(即将SQL中用到的多个POJO对象的属性封装为一个对象,可以使用Map代替)
  示例①:传入POJO类型,则SQL文中的#{}中获取的值来自于该POJO对象的同名属性

<select id="getByEntity" parameterType="student" resultType="student">
    SELECT * FROM students WHERE name = #{name} and age = #{age}
</select>  

  示例②:模糊查询
   a、使用#{}时SQL文中在#{}的两边无法加%变为 LIKE ‘%#{name}%’,而没有%是没办法完成模糊查询的,就变成了全匹配,只能在调用时传入%,很显然这种方式不够优雅

<select id="getByName" parameterType="string" resultType="student">
    SELECT * FROM students WHERE name LIKE #{name}
</select> 
<!-- 调用时传入% -->
List<Student> stus = mapper.getByName("%y%");

   b、使用$时可以在SQL文中拼接%,但这种方式无法防止SQL注入,是不安全的

<select id="getByName" parameterType="string"  resultType="com.bdm.entities.Student">
	<!-- ${}内的值必须是value或_parameter -->
	SELECT * FROM students WHERE name like '%${value}%'
</select> 
<!-- 调用时会引起sql注入问题,不安全-->
List<Student> stus = mapper.getByName("h' or '1 = 1"); 

   c、上面的两个示例中,a不够优雅,b不够安全,开发中采用的方式是使用#{},然后在SQL文中使用CONCAT()函数拼接%的方式,即安全又优雅

<select id="getByName" parameterType="string" resultType="student">
    SELECT * FROM students WHERE name LIKE CONCAT('%',#{name},'%')
</select> 
<!-- 调用 -->
List<Student> stus = mapper.getByName("黑宋江");

   Tip:使用#{}和${}的区别
    1️⃣#{}可看作是jdbc中的preparedStatement中的占位符,相对比较安全,可以防止sql注入,而${}中的内容类似于拼接sql语句,无法防止sql注入
    2️⃣使用#{}和${}在parameterType是对象(POJO对象、Map、口袋POJO)的时候都是从对象中获取同名属性值填充SQL文,不同的是在高版本的MyBatis中如果parameterType是简单数据类型或String时若使用#{}则#{}中填写任何内容都可以获取到传入的值,而使用\${}时\${}内的内容必须是value或者_paramter才可以。但在低版本的MyBatis中有两种方式,一是在接口声明的方法的入参位置使用@Param注解,然后在#{}中填写注解中的value中,二是若没有@Param则必须填写_parameter,无论高低版本对于${}都可以使用@Param的方式,这一点要尤为注意,例如:

<select id="getByName" parameterType="string" resultType="com.bdm.entities.Student">
	<!-- ${}内的值必须是value或_parameter -->
	SELECT * FROM students WHERE name like '%${_parameter}%'
</select> 
<!-- 调用时会引起sql注入问题,不安全-->
List<Student> stus = mapper.getByName("h' or '1 = 1"); 

    3️⃣使用${}时两边必须加上引号(单引号或者双引号)
  示例③:传入HashMap,当sql语句需要多个数据,而这些数据又没有封装在同一个类(跨POJO)中时可以使用HashMap,几乎在所有情况下都可使用map,不管是parameterType还是resultType

<select id="getByMap" parameterType="hashMap" resultType="cat">
    SELECT * FROM cats WHERE id = #{id} AND name LIKE #{name}
</select>   
<!-- 调用 -->
Map<String,Object> map = new HashMap<String,Object>();
map.put("id", 1);
map.put("name", "%mm%");
Cat cat = mapper.getByMap(map);  

 3、resultType属性:返回值类型
  ①返回简单数据类型:integer、string等
  ②返回单个POJO
  ③返回一个List(配置和返回POJO相同)
  ④返回HashMap(比如想获取查询记录中的几个值,就可以将这条记录的几个值封装到一个map中),比如:

<select id="getById" parameterType="integer" resultType="hashMap">
    SELECT name,age,birth FROM cats WHERE id = #{id}
</select>

 4、resultMap标签:结果集映射,查询字段的column名(可以采用别名的方式)和POJO里面的field一一对应时,resultType可以指定为POJO类型,将查询结果集直接映射为POJO对象,如果不一致就需要使用<resultMap>标签定义映射关系

<!-- type是要映射的类型(在起了别名后可以使用别名),id是映射的id用于在<select>标签中引用 -->
<resultMap type="com.bdm.entities.Student" id="hostMap">
    <id column="id" property="id"/>
    <result column="host_name" property="name"/>
    <result column="host_email" property="email"/>
</resultMap>
<!-- 引用hostMap -->
<select id="getById" parameterType="integer" resultMap="hostMap">
    SELECT * FROM hosts WHERE id = #{id}
</select>  

 5、sql标签:给一段SQL起别名,便于重用重复的SQL代码段以简化XxxMapper.xml的编写,使用<incllude>标签引用

<sql id="allColumns">
	<![CDATA[
		id,
		session_id,
		caller_num,
		called_route,
		called_num,
		call_time,
		call_record_code,
		state,
		create_time
	]]>
</sql>

<!-- 引用 -->
<select id="selectByPK" parameterType="com.bdm.base.SysMissedCallPK" resultMap="SysMissedCallRM">
	select <include refid="allColumns" />
	from sys_missed_call 
	where id = #{id}
</select>

Tip:在SQL文中有可能会出现xml文件中的标签字符,比如<,这时在解析这个XxxMapper.xml文件时就会报错,这时我们可以将SQL问放在<![CDATA[ ]]>中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值