前言

我们知道在项目开发中之前使用数据库查询,都是基于jdbc,进行连接查询,然后是高级一点jdbcTemplate进行查询,但是我们发现还是不是很方便,有大量重复sql语句,与代码偶合,效率低下,于是就衍生出来ORM框架,如Mybatis,Hibernate,还有SpringBoot的,Spring Data JPA

条件查询

我们知道在mybatis mapper文件中条件查询符,如>=,<,之类是不能直接写的会报错的需要转移一下 如下图表

详细内容参考

常见的条件查询操作有

我们通过mybatis 提供的特有标签进行条件判断,达到动态拼接sql语句

if标签 where标签 choose when otherwise标签 foreach标签

快速入门

if标签

语法:

<if test="xxx != null and xxx != ''">

test中写判断条件 参数直接paramN或者别名 多个条件使用and或者or连接

只要条件成立就拼接在Sql语句中,都成立就全部都拼接

注意where子句中加上1=1来规避and的风险

如下例子:

<select id="selg" resultType="log">
select * from log where 1=1
<if test="param1!=null and param1!=''">
and outno=#{param1}
</if>
<if test="param2!=null and param2!=''">
and inno=#{param2}
</if>
</select>

where标签

对上面if标签条件判断where连接做了处理会自动的给Sql语句添加where关键字,并将第一个and去除

上面sql可以改造成如下:

<select id="selg" resultType="log">
select * from log
<where>
<if test="param1!=null and param1!=''">
and outno=#{param1}
</if>
<if test="param2!=null and param2!=''">
and inno=#{param2}
</if>
</where> </select>

choose when otherwise标签

类似于Java语法中的,case,switch语句判断

条件只要有一个成立,其他的就不会再判断了。如果没有成立的条件则默认执行otherwise中的内容

上面sql可以改造成如下:

<select id="selg" resultType="log">
select * from log
<where>
<choose>
<when test="param1!=null and param1!=''">
and outno=#{param1}
</when>
<when test="param2!=null and param2!=''">
and inno=#{param2}
</when>
<otherwise>
and 1=1
</otherwise>
</choose>
</where> </select>

foreach标签

语法:

  <foreach collection="idList" item="id" open="(" separator="," close=")">
</foreach>
  1. collection:要遍历的集合对象
  2. item:记录每次遍历的结果
  3. open:在结果的左边添加内容
  4. separator:结果和结果之间的内容
  5. close:在最后添加的内容

常用于in查询,和批量插入操作 如下案例:

<select id="selF" parameterType="list" resultType="account">
select * from account where ano in
<foreach collection="list" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>

<insert id="insertBatch">
INSERT INTO t_user
(id, name, password)
VALUES
<foreach collection ="userList" item="user" separator =",">
(#{user.id}, #{user.name}, #{user.password})
</foreach >
</insert>

其他标签使用参考点击进入·

场景案例

  1. 当我们需要对多张表的关联数据进行复杂动态条件查询的时候,就需要用到 if标签进行判断 如下

根据用户手机号姓名年龄性别,等进行动态条件检索,这个时候我们需要动态通过调节去拼接sql 当条件满足sql语句加上对应条件差许

<select id="findUsersByUser" resultType="cn.soboys.kmall.sys.entity.User">
select tu.USER_ID,tu.USERNAME,tu.SSEX,td.DEPT_NAME,tu.MOBILE,tu.EMAIL,tu.STATUS,tu.CREATE_TIME,
td.DEPT_ID
from t_user tu left join t_dept td on tu.DEPT_ID = td.DEPT_ID
where tu.ADMIN_TYPE_ID &gt;= 0 AND tu.ADMIN_TYPE_ID &lt;= #{userParams.adminType}
<if test="userParams.roleId != null and userParams.roleId != ''">
and (select group_concat(ur.ROLE_ID)
from t_user u
right join t_user_role ur on ur.USER_ID = u.USER_ID,
t_role r
where r.ROLE_ID = ur.ROLE_ID
and u.USER_ID = tu.USER_ID and r.ROLE_ID=#{userParams.roleId})
</if> <if test="userParams.mobile != null and userParams.mobile != ''">
AND tu.MOBILE =#{userParams.mobile}
</if>
<if test="userParams.username != null and userParams.username != ''">
AND tu.USERNAME like CONCAT('%',#{userParams.username},'%')
</if>
<if test="userParams.ssex != null and userParams.ssex != ''">
AND tu.SSEX =#{userParams.ssex}
</if>
<if test="userParams.status != null and userParams.status != ''">
AND tu.STATUS =#{userParams.status}
</if>
<if test="userParams.deptId != null and userParams.deptId != ''">
AND td.DEPT_ID =#{userParams.deptId}
</if>
<if test="userParams.createTime != null and userParams.createTime != ''">
AND DATE_FORMAT(tu.CREATE_TIME,'%Y%m%d') BETWEEN substring_index(#{userParams.createTime},'#',1) and substring_index(#{userParams.createTime},'#',-1)
</if>
</select>

对应mapper对应的方法

<T> IPage<User> findUsersByUser(Page<T> page, @Param("userParams") SearchUserParams userParams);

对应参数实体对象

@Data
public class SearchUserParams {
private String username;
private String mobile;
private String status;
private String ssex;
private Long deptId;
private String createTime;
private long adminType;
private String roleId;
}

通过if标签去判断条件是否满足,满足就拼接对应sql

注意在上面我们提到的条件拼接第一个是where连接,而不是and应规避and风险保证sql语法正确 如下

<select id="findSearchCouponsPage" parameterType="cn.soboys.kmall.bean.web.params.SearchCouponParams" resultType="coupon">
select *
from coupon c
left join user_coupon uc on c.coupon_id = uc.coupon_id
WHERE 1 = 1
<if test="couponParams.userId != null and couponParams.userId != ''">
and uc.user_id =#{couponParams.userId}
</if>
<if test="couponParams.status != null and couponParams.status != ''">
and c.status =#{couponParams.status}
</if>
<if test="couponParams.couponId != null and couponParams.couponId != ''">
and c.coupon_id =#{couponParams.couponId}
</if>
<if test="couponParams.couponType != null and couponParams.couponType != ''">
and c.type =#{couponParams.couponType}
</if>
</select>

我们可以通过假定给他一个默认条件 WHERE 1 = 1来解决,也可以通过嵌套where标签来解决

mybatis的mapper特殊字符转移以及动态SQL条件查询的更多相关文章

  1. 8.mybatis动态SQL模糊查询 (多参数查询,使用parameterType)

    多参数查询,使用parameterType.实例: 用户User[id, name, age] 1.mysql建表并插入数据 2.Java实体类 public class User { public ...

  2. MyBatis基础入门《十七》动态SQL

    MyBatis基础入门<十七>动态SQL 描述: >> 完成多条件查询等逻辑实现 >> 用于实现动态SQL的元素主要有: > if > trim > ...

  3. Mysql动态多条件查询

    动态多条件查询是一类经常遇到的问题. 在Mysql里面可以用语句简单的解决. SELECT * FROM product WHERE price = IF('{0}' = '', price, '{0 ...

  4. EntityFramework动态多条件查询与Lambda表达式树

              在常规的信息系统中, 我们有需要动态多条件查询的情况, 例如UI上有多个选择项可供用户选择多条件查询数据. 那么在.net平台Entity Framework下, 我们用Lambd ...

  5. MyBatis入门3_mapper.xml优化(parameterType简写_NameSpace简写_sql片段_特殊字符处理)_动态SQL

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! 优化 1.起别名(一般不用,写全方便查看类出处) 以前 ...

  6. MyBatis 实践 -动态SQL/关联查询

    MyBatis 实践 标签: Java与存储 动态SQL 动态SQL提供了对SQL语句的灵活操作,通过表达式进行判断,对SQL进行拼接/组装. if 对查询条件进行判断,如果输入参数不为空才进行查询条 ...

  7. MyBatis的动态SQL操作--查询

    查询条件不确定,需要根据情况产生SQL语法,这种情况叫动态SQL,即根据不同的情况生成不同的sql语句. 模拟一个场景,在做多条件搜索的时候,

  8. Spring+SpringMVC+MyBatis深入学习及搭建(五)——动态sql

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6908763.html 前面有讲到Spring+SpringMVC+MyBatis深入学习及搭建(四)——My ...

  9. Java数据持久层框架 MyBatis之API学习七(动态 SQL详解)

    对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...

随机推荐

  1. pikachu PHP反序列化 XXE SSRF

    PHP反序列化在理解这个漏洞前,你需要先搞清楚php中serialize(),unserialize()这两个函数. 另外这个漏洞一般是在代码审计的时候发现的,在扫描或者黑盒测试的时候很难发现.1.序 ...

  2. DVWA-全等级文件包含

    DVWA简介 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...

  3. K8s 部署 Gitlab CI Runner

    K8s 版本:1.20.6 GitLab CI 最大的作用是管理各个项目的构建状态.因此,运行构建任务这种浪费资源的事情交给一个独立的 Gitlab Runner 来做就会好很多,而且 Gitlab ...

  4. Windows安装Svn客户端

    一.下载程序 官网地址,选择最新64位下载. 下载完成 二.安装过程 点击下一步 点击下一步 选择安装目录 点击安装 安装完成 三.修改中文 下载中文包 下载完成 点击下一步 安装完成 点击设置 选择 ...

  5. Centos7 出现Welcome to emergency mode!【紧急模式】

    Centos7 出现Welcome to emergency mode![紧急模式] 做mount挂载时,修改了  /etc/fstab 文件,导致Centos7重启时出现如下图所示错误:   输入r ...

  6. 查看linux系统是物理机还是虚拟机

    物理机,返回机器型号 [root@laocalhost ~]# dmidecode -s system-product-name S910-X31E 虚拟机 [root@dev01-188 ~]# d ...

  7. DataTable 读取每一行的内容

    foreach (DataRow item in dataTable.Rows) { for (int i = 0; i < dataTable.Columns.Count; i++) { Co ...

  8. asp.net core 声明controller的方法

    1, 对类名直接添加Controller, 如TestController. 2,  继承Controller 类. 3, 对类名添加controller的属性, 如[Controller]

  9. .Net Core WebApi(三)--使用 IdentityServer4 4.1.1 踩坑记录

    目的:创建IdentityServer 并通过PostMan验证获取token 第一次配置如下 public class Config { public static IEnumerable<A ...

  10. Navicat查询出的数据有时候不能更改?

    Navicate查出数据只读,一种情况是查询没带出主键(唯一索引),无法更新数据