1、mybatis 中 sql 处理
在 mybatis 中支持动态 sql ,sql 语句拼接,自定义映射等功能的。
2、特殊 sql 处理
2.1、模糊查询
1、字符串拼接的方式:'%${param}%' # 单引号不能省略
2、使用concat函数:concat('%',#{param},'%')
3、直接使用字符串形式(常用):"%"#{param}"%"
2.2、插入并自动填充主键
<!-- useGeneratedKeys="true" 使用数据库自增主键,插入数据将自增主键值绑定到实体类对象的属性中(该属性通过keyProperty="id"设置),
注意,这点传递参数必须是实体类对象才可以将返回的主键值绑定到指定属性上。-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into user values(null, #{name},#{age})
</insert>
3、自定义映射 resultMap
3.1、字段名和属性名不一致
1)、为字段起别名;
2)、在mybatis中设置驼峰映射(如果是 spring 项目使用第一种,springboot 项目使用第二种),如下:
<!-- 1、在mybatis核心配置文件中配置驼峰命名开启-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!--2、在application.yml文件中设置-->
mybatis:
configuration:
map-underscore-to-camel-case: true <!--将下划线映射成驼峰-->
3)、通过resultMap设置别名;
<!-- 所有字段和属性都要做映射,property是type中实体类属性名,column是数据库表字段名 -->
<resultMap id="testResultMap" type="com.test.entity.User">
<id column="id" property="id"></id> <!--设置主键映射关系-->
<result column="name" property="name"></result> <!--设置普通字段映射关系-->
<result column="age" property="age"></result>
</resultMap>
3.2、设置多对一映射关系
1)、通过级联属性赋值
<resultMap id="testResultMap" type="com.weilong.entity.User">
<id column="id" property="id"></id> <!--设置主键映射关系-->
<result column="name" property="name"></result> <!--设置普通字段映射关系-->
<result column="age" property="age"></result>
<!--通过级联属性赋值-->
<result column="dept_name" property="dept.name"></result>
<result column="dept_id" property="dept.id"></result>
</resultMap>
2)、通过association设置多对一
<resultMap id="testResultMap" type="com.weilong.entity.User">
<id column="id" property="id"></id> <!--设置主键映射关系-->
<result column="name" property="name"></result> <!--设置普通字段映射关系-->
<result column="age" property="age"></result>
<!--association中的property设置type中的属性名,JavaType指定的是类型-->
<association property="dept" javaType="com.weilong.entity.Dept">
<id column="dept_id" property="id"></id> <!--设置主键映射关系-->
<result column="dept_name" property="name"></result> <!--设置普通字段映射关系-->
</association>
</resultMap>
3)、分步查询(可以设置延迟加载)
<resultMap id="testResultMap" type="com.weilong.entity.User">
<id column="id" property="id"></id> <!--设置主键映射关系-->
<result column="name" property="name"></result> <!--设置普通字段映射关系-->
<result column="age" property="age"></result>
<!--association中的property设置type中的属性名,select设置分步查询的sql唯一标识,column设置分步查询条件,fetchType是在开启延迟加载后设置该分步sql是否需要延迟加载-->
<association property="dept" select="*.*.*Mapper.方法名" column="查询条件" fetchType="lazy|eager">
</association>
</resultMap>
设置延迟加载(对所有的分步查询都是延迟加载,如果需要部分不设置延迟加载,可通 association 和 collection 中的 fetchType 属性设置当前的分步查询是否使用延迟加载,fetchType="lazy(延迟加载)|eager(立即加载))。
<!-- 1、mybatis核心配置文件-->
<settings>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<!-- 2、application.yml文件 -->
mybatis:
configuration:
# 延迟加载的全局开关,当开启时,所有关联对象都会延迟加载
lazy-loading-enabled: true # 延迟加载
# 开启时,任何方法调用都会加载该对象的所有属性,关闭则按需加载
aggressive-lazy-loading: false # 如果设置延迟加载,需要将此项设置为false(默认为false)
8.3、设置一对多映射
1)、使用collection标签设置一对多;
<resultMap id="testResultMap" type="com.weilong.entity.User">
<id column="id" property="id"></id> <!--设置主键映射关系-->
<result column="name" property="name"></result> <!--设置普通字段映射关系-->
<result column="age" property="age"></result>
<collection property="childs" ofType="com.weilong.entity.Children">
<id property="childId" column="id"></id>
<result property="name" column="child_name"></result>
</collection>
</resultMap>
2)、分步查询;
<resultMap id="DeptAndEmpByStepOneResultMap" type="Dept">
<id property="did" column="did"></id> <!--设置主键映射关系-->
<result property="deptName" column="dept_name"></result> <!--设置普通字段映射关系-->
<!--
collection中的property设置type中的属性名,select设置分步查询的sql唯一标识,column设置分步查询条件,fetchType是在开启延迟加载后设置该分步sql是否需要延迟加载。
<collection property="dept" select="*.*.*Mapper.方法名" column="查询条件" fetchType="lazy|eager">
</collection>
-->
<collection property="emps"
select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo"
column="did">
</collection>
</resultMap>
4、动态 sql
Mybatis 框架的动态 SQL 技术是一种根据特定条件动态拼装 SQL 语句的功能,它存在的意义是为了解决拼接 SQL 语句字符串时的痛点问题。
4.1、if 标签
<if test="email != null and email !=''">
and email = #{email}
</if>
<if test="list != null and list.size() != 0">
....
</if>
4.2、where 标签
-
where和if一般结合使用;
-
若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字;
-
若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的 and/or 去掉。
-
注意:where标签不能去掉条件后多余的。
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<if test="empName != null and empName !=''">
emp_name = #{empName}
</if>
<if test="age != null and age !=''">
and age = #{age}
</if>
<if test="sex != null and sex !=''">
and sex = #{sex}
</if>
<if test="email != null and email !=''">
and email = #{email}
</if>
</where>
</select>
4.3、trim 标签
trim 用于去掉或添加标签中的内容。
常用属性:
prefix # 在trim标签中的内容的前面添加某些内容
suffix # 在trim标签中的内容的后面添加某些内容
prefixOverrides # 在trim标签中的内容的前面去掉某些内容
suffixOverrides # 在trim标签中的内容的后面去掉某些内容
# 若trim中的标签都不满足条件,则trim标签没有任何效果
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and|or">
<if test="empName != null and empName !=''">
emp_name = #{empName} and
</if>
<if test="age != null and age !=''">
age = #{age} and
</if>
<if test="sex != null and sex !=''">
sex = #{sex} or
</if>
<if test="email != null and email !=''">
email = #{email}
</if>
</trim>
</select>
4.4、choose、when、otherwise标签
-
choose、when、otherwise 相当于 if...else if..else
-
when至少要有一个,otherwise至多只有一个,所有的when和otherwise加起来只会执行一个。
<select id="getEmpByChoose" resultType="Emp">
select * from t_emp
<where>
<choose>
<when test="empName != null and empName != ''">
emp_name = #{empName}
</when>
<when test="age != null and age != ''">
age = #{age}
</when>
<when test="sex != null and sex != ''">
sex = #{sex}
</when>
<when test="email != null and email != ''">
email = #{email}
</when>
<otherwise>
did = 1
</otherwise>
</choose>
</where>
</select>
4.5、foreach 标签
属性:
collection # 设置要循环的数组或集合
item # 表示集合或数组中的每一个数据
separator # 设置循环体之间的分隔符,分隔符前后默认有一个空格,如` , `
open # 设置foreach标签中的内容的开始符
close # 设置foreach标签中的内容的结束符
<!--批量删除 int deleteMoreByArray(Integer[] eids);-->
<delete id="deleteMoreByArray">
delete from t_emp where eid in
<foreach collection="eids" item="eid" separator="," open="(" close=")">
#{eid}
</foreach>
</delete>
<!--批量添加 int insertMoreByList(@Param("emps") List<Emp> emps);-->
<insert id="insertMoreByList">
insert into t_emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
</foreach>
</insert>
4.6、sql 片段
1)、sql片段,可以记录一段公共sql片段,在使用的地方通过 include 标签进行引入;
2)、声明sql片段: <sql> 标签。
<!--声明sql片段-->
<sql id="empColumns">eid,emp_name,age,sex,email</sql>
<!--引用sql片段-->
<!--List<Emp> getEmpByCondition(Emp emp);-->
<select id="getEmpByCondition" resultType="Emp">
select <include refid="empColumns"></include> from t_emp
</select>
总结:本文介绍 mybatis 中 *Mapper.xml 文件中 sql 编写的规则,详细说明每个部分具体用法。
本人是一个从小白自学计算机技术,对运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:it自学社团。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)