MyBatis的Mapper映射文件

MyBatis映射文件

一、Mybatis文件的整体结构:

<?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="Mapper接口对应的全路径名称">
	<!--可包含多个select、insert、update、resultMap、sql子节点-->
</mapper>	

二、Mapper节点下的几个主要的子节点

在这里插入图片描述

1、select节点说明

  • select:映射查询语句
    作用:主要使用映射sql语句中的插叙语句

    • id:对应的是XxxMapper接口的方法名在命名空间中唯一的标识符,可以被用来引用这条语句。
    • parameterType:对应的是参数的类型
    • resultType:返回的类型,如果返回的是一个集合,需要写集合中存放的类型(泛型)
    • statementType :类型的取值有 STATEMENT (一般的stament语句)、 PERPARED默认,预编译的perparedStatement语句)、CALLABLE(过程)
    • resultMap:复杂的结果集映射(下面会介绍到)。

2、insert、update和detele节点的说明

insert(映射插入语句 )、update(映射更新语句)、 delete(映射删除语句)

  • parameterType:对应的是参数的类型
  • useGeneratedKeys="true"keyProperty="id": 在MySQL中使用主键自增策略获取主键的值,可通过这两个属性并映射到keyProperty指定的主键中去,只有在insertupdate语句中有效

备注:在Mapper文件中,一个sql语句的结束是不需要写 “ ; ”符号的

三、更丰富的用法resultMap、sql 以及动态 sql

1、resultMap复杂的返回值

属性:id 主要用于指定该resultMap标识

1)成员变量全是基本数据类型(对应的包装类)和Sting类的POJO

  • id子节点:主要用于映射主键
 <id column="数据库中对应的字段" property="实体类POJO中对应成员变量" >
  • result 子节点: 用于映射普通属性
  <result column="数据库字段名" property="成员变量名"/>

示例:

<resultMap id="user">
	<!--这里映射的是主键-->
	<id column="id" prorperty="id"/>
	<result column="user_name" property="userName"/>
</resultMap>

2)成员变量包含其他引用的实体类,使用级联进行指定映射

JavaBean实体类的示例:

package com.example.bean;
class User{
    
    
	private Integer id;
	private String userName;
	private Role role;
	/*
	省略setter和getter
	*/
}

class Role{
    
    
	private Integer id;
	private String role_name;
	/*
	省略setter和getter
	*/
}

格式

	<result column="数据库字段名" property="成员变量名.成员变量名">

示例:

<resultMap id="user" type="com.example.bean.User">
	<!--这里映射的是主键-->
	<id column="id" prorperty="id"/>
	<result column="user_name" property="userName"/>
	<result column="rid" property="role.id"/>
	<result column="role_name" property="role.role_name"/>
</resultMap>

3)成员变量包含其他引用的实体类,使用association关联

  • 子节点:association,包含子节点 id、result,进行表字段映射对应JavaBean类的属性
   <association property="成员变量名" javaType="引用类的全路径名称">....</association>

示例:还是上面的JavaBean,使用association

<resultMap id="userUseAssociation">
	<!--这里映射的是主键-->
	<id column="id" prorperty="id"/>
	<result column="user_name" property="userName"/>
	<association>
		<id column="rid" property="role.id"/>
		<result column="role_name" property="role.role_name"/>
	</association>
</resultMap>

4)成员变量包含其他引用的实体类,分段查询

  • 先查询出查出部分需要的数据
  • 再通过查出的数据进行第二次查询
  • 可以使用延迟加载,使用到相应的属性才会进行查询 (fetchType=“lazy”)

示例使用collection:分段查询
JavaBean:

package com.example.bean;
class Employee{
    
    
	private Integer id;
	private String name;
	private Integer departmentId;
	// 省略 getter 和 setter
}

class Department{
    
    
	private Integer id ;
	private departmentName;
	private List<Employee> emplyeeList;
}

Mapper文件:

	<!-- collection:分段查询 -->
	<resultMap type="com.example.bean.Department" id="MyDeptStep">
		<id column="id" property="id"/>
		<id column="department_name" property="departmentName"/>
		<collection property="emplyeeList" 
			select="com.example.EmployeeMapper.getEmpsByDeptId"
			column="{deptId=id}" fetchType="lazy">
		</collection>
	</resultMap>
	<select id="getEmpsByDeptId">
		select * from employee where department_id = #{deptId}
	</select>

拓展

  • 单个值可以直接使用column直接传递,也可使使用封装成Map:column=“{参数名=字段名}”
  • 多列的值传递过去:将多列的值封装map传递:column="{key1=column1,key2=column2}"

2、if:判断

  • test:判断表达式(OGNL) test从参数中取值进行判断,遇见特殊符号应该去写转义字符

  • 格式:

<if test="判断条件">...</test>
  • 为空判断: <if test="name!=null"> ...</if>

  • 空字符串判断:<if test="name!=&quot;&quot;"></if>

  • 使用and进行并列: <if test="name!=null && name!=&quot;&quot;">...</if>

示例:

<select id="getByConditionIf" parameterType="com.example.bean.User">
	select * from user 
	where 
		<if test="id!=null and id>0">
			id = #{id}
		</if>
		<!--不为空且不是空字符串-->
		<if test="userName!=null and userName != &quot;&quot; ">
			and user_name = #{userName}
		</if>
</select>

3、where语句

在上面的if 示例中,如果出现了id为空的情况,会出现and 或者 or在where 关键字之后,Mybatis提供了where节点。

  • 用于结合if条件判断语句进行查询
  • where 语句会把前面的 and | or 排除,避免报错
  • 示例
<select id="getByConditionIf" parameterType="com.example.bean.User">
	select * from user 
	<where>
		<if test="id!=null and id>0">
			id = #{id}
		</if>
		<!--不为空且不是空字符串-->
		<if test="userName!=null and userName != &quot;&quot; ">
			and user_name = #{userName}
		</if>
	</where>	
</select>

4、trim语句

  • 属性

    • prefix="" (前缀):prefix给拼串后的整个字符串加一个前缀
    • prefixOverrides="" (前缀覆盖): 去掉整个字符串前面多余的字符
    • suffix=""(后缀):suffix给拼串后的整个字符串加一个后缀
    • suffixOverrides=""(后缀覆盖):去掉整个字符串后面多余的字符
  • 作用:后面多出的and或者or where标签不能解决

  • 示例

<select id="getByConditionTrim" parameterType="com.example.bean.User">
	select * from user 
	<trim prefix="where" prefixOverridess="and">
		<if test="id!=null and id>0">
			id = #{id}
		</if>
		<!--不为空且不是空字符串-->
		<if test="userName!=null and userName != &quot;&quot; ">
			and user_name = #{userName}
		</if>
	</trim>
</select>

5、set语句

  • 用于根据条件进行更新的操作
  • set会删除结尾可能会有多余的
  • 示例
<update id="updateBySet" paramterType="com.example.bean.User">
	update user
	<set>
		<if test="userName!=null and userName != &quo;&quo;">
			user_name = #{userName},
		</if>
		<if test="address!=null and address!= &quo;&quo;">
			address = #{address}
		</if>
	</set>
	where id = #{id}
</update>

set语句也可以使用trim

  • 使用trim进行替换set
<update id="updateByTrim" paramterType="com.example.bean.User">
	update user
	<trim prefix="set" suffixOverrides=","> 
		<if test="userName!=null and userName != &quo;&quo;">
			user_name = #{userName},
		</if>
		<if test="address!=null and address!= &quo;&quo;">
			address = #{address}
		</if>
	</trim>
	where id = #{id}
</update>

6、foreach语句

作用:用于遍历集合的

  • 属性

    • collection:指定要遍历的集合, list类型的参数会特殊处理封装在map中,map的key就叫list
    • item:将当前遍历出的元素赋值给指定的变量
    • separator:每个元素之间的分隔符
    • open:遍历出所有结果拼接一个开始的字符
    • close:遍历出所有结果拼接一个结束的字符
    • index:索引, 遍历list的时候是index就是索引,item就是当前值;遍历map的时候index表示的就是map的key,item就是map的值
    • #{变量名}:就能取出变量的值也就是当前遍历出的元素
  • 示例

	 <select id="getUserByConditionForeach" resultType="com.example.bean.User">
	 	select * from user
	 	<foreach collection="ids" item="id" separator=","
	 		open="where id in(" close=")">
	 		#{id}
	 	</foreach>
	 </select>

7、choose、when、otherwise语句

在不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

  • 可以根据传入的值进行不同条件的插叙
<select id="getUserByChoose" resultType="com.example.bean.User">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
  	<!--如果名字不为空,就根据名字查-->
    <when test="userName != null">
      AND user_name like #{userName}
    </when>
    <!--如果地址不为空,就根据名字查-->
    <when test="address != null">
      AND address like #{address}
    </when>
    <otherwise>
      AND  sex= 1
    </otherwise>
  </choose>
</select>

8、sql的用法

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值

  • 抽取可重用的sql片段。方便后面引用
    • 1、sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
    • 2、include来引用已经抽取的sql:
    • 3、include还可以自定义一些property,sql标签内部就能使用自定义的属性
      示例
<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>
  • 注意点

    • include-property:取值的正确方式${prop}, 不能使用#{prop}这种方式

9、#{} 和${}的区别

  • #{}:以预编译的形式,将参数设置到sql语句中,即预编译时的使用 “?”,实际执行的时候是传入的值,可以预防SQL注入
  • ${}:是取出值,先直接拼接在sql语句中,会有安全问题,大多数请求下使用#{}

使用${}的情况:

  • 原生jdbc不支持占位符的地方,需要使用${}进行取值
  • 分库分表的情况
  • 排序等

猜你喜欢

转载自blog.csdn.net/Hicodden/article/details/114464018