- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章基于mybatis 动态SQL查询总结由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
××项目需要提供系统部分函数第三方调用接口,基于安全性和避免暴露数据库表信息的基础上进行函数接口的设计,根据第三方调用身份的权限提供某张表的自定义集合.
本项目基于mybatis的持久层框架,支持定制化的SQL,这样可以避免拼接sql语句的痛苦.
例如拼接时要确保不能添加空格,还要注意去掉列表的最后一个列名的都逗号.
基于OGNL的表达式的mybatis框架可以彻底解决这种痛苦.
1
2
3
4
5
6
7
8
9
10
|
<
select
id=
"queryColumns"
resultType=
"map"
parameterType=
"java.util.HashMap"
>
select
column_name columnName, data_type dataType, column_comment columnComment
from
information_schema.columns
where
table_name = #{tablename}
and
column_name
in
<foreach collection=
"columnsArray"
item=
"column_name"
index
=
"index"
open
=
"("
close
=
")"
separator=
","
>
#{column_name}
</foreach>
</
select
>
|
1
2
3
4
5
6
7
|
<
select
id=
"query1"
resultType=
"map"
parameterType=
"java.util.HashMap"
>
select
<foreach collection=
"columnsArray"
item=
"item"
index
=
"index"
open
=
" "
separator=
", "
close
=
" "
>
${item}
</foreach>
from
#{tableName} tn
</
select
>
|
1
2
3
4
5
6
7
8
9
10
11
12
|
<
select
id=
"query2"
resultType=
"map"
parameterType=
"java.util.HashMap"
>
select
<foreach collection=
"columnsArray"
item=
"item"
index
=
"index"
open
=
""
separator=
","
close
=
""
>
${item}
</foreach>
from
#{tableName} db
where
<if test =
"name !=null"
>
db.
name
=#{
name
}
and
</if>
db.LastModifyTime
between
#{datestart,jdbcType=
TIMESTAMP
}
and
#{dateend,jdbcType=
TIMESTAMP
}
</
select
>
|
Mybatis 的Mapper.xml语句中parameterType向SQL语句传参有两种方式:#{}和${} 。
我们经常使用的是#{},一般解说是因为这种方式可以防止SQL注入,简单的说#{}这种方式SQL语句是经过预编译的,它是把#{}中间的参数转义成字符串,举个例子:
1
|
select
*
from
student
where
studentName = #{
name
}
|
预编译后,会动态解析成一个参数标记符?:
1
|
select
*
from
student
where
studentName = ?
|
而使用${}在动态解析时候,会传入参数字符串 。
1
|
select
*
from
student
where
studentName =
'lyrics'
|
-看完上面的一些例子,可以看到主要用到了if 、foreach等元素,mybatis之前的版本,有很多的元素需要了解,而mybatis大大精简了元素种类,现在只需要学习以下几个元素:
-if 。
-choose(when,otherwise) 。
-trim(where,set) 。
-foreach 。
-- 引用[http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html] 。
if 。
动态SQL通常要做的是根据条件包含where子句的一部分。比如:
1
2
3
4
5
6
7
|
<
select
id=
"findActiveBlogWithTitleLike"
resultType=
"Blog"
>
SELECT
*
FROM
BLOG
WHERE
state = ‘ACTIVE'
<if test=
"title != null"
>
AND
title
like
#{title}
</if>
</
select
>
|
这条语句提供了一种可选的查找文本功能。如果没有传入“title”,那么所有处于“ACTIVE”状态的BLOG都会返回;反之若传入了“title”,那么就会对“title”一列进行模糊查找并返回 BLOG 结果(细心的读者可能会发现,“title”参数值是可以包含一些掩码或通配符的).
如果希望通过“title”和“author”两个参数进行可选搜索该怎么办呢?首先,改变语句的名称让它更具实际意义;然后只要加入另一个条件即可.
1
2
3
4
5
6
7
8
9
|
<
select
id=
"findActiveBlogLike"
resultType=
"Blog"
>
SELECT
*
FROM
BLOG
WHERE
state = ‘ACTIVE'
<if test=
"title != null"
>
AND
title
like
#{title}
</if>
<if test=
"author != null and author.name != null"
>
AND
author_name
like
#{author.
name
}
</if>
</
select
>
|
choose,when,otherwise 。
有时我们不想应用到所有的条件语句,而只想从中择其一项。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句.
还是上面的例子,但是这次变为提供了“title”就按“title”查找,提供了“author”就按“author”查找的情形,若两者都没有提供,就返回所有符合条件的 BLOG(实际情况可能是由管理员按一定策略选出 BLOG 列表,而不是返回大量无意义的随机结果).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
select
id=
"findActiveBlogLike"
resultType=
"Blog"
>
SELECT
*
FROM
BLOG
WHERE
state = ‘ACTIVE'
<choose>
<
when
test=
"title != null"
>
AND
title
like
#{title}
</
when
>
<
when
test=
"author != null and author.name != null"
>
AND
author_name
like
#{author.
name
}
</
when
>
<otherwise>
AND
featured = 1
</otherwise>
</choose>
</
select
>
|
trim, where, set 。
前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。现在回到“if”示例,这次我们将“ACTIVE = 1”也设置成动态的条件,看看会发生什么.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<
select
id=
"findActiveBlogLike"
resultType=
"Blog"
>
SELECT
*
FROM
BLOG
WHERE
<if test=
"state != null"
>
state = #{state}
</if>
<if test=
"title != null"
>
AND
title
like
#{title}
</if>
<if test=
"author != null and author.name != null"
>
AND
author_name
like
#{author.
name
}
</if>
</
select
>
|
如果这些条件没有一个能匹配上会发生什么?最终这条 SQL 会变成这样:
1
2
|
SELECT
*
FROM
BLOG
WHERE
|
这会导致查询失败。如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样
1
2
3
|
SELECT
*
FROM
BLOG
WHERE
AND
title
like
‘someTitle'
|
这个查询也会失败。这个问题不能简单地用条件句式来解决,如果你也曾经被迫这样写过,那么你很可能从此以后都不会再写出这种语句了.
MyBatis 有一个简单的处理,这在 90% 的情况下都会有用。而在不能使用的地方,你可以自定义处理方式来令其正常工作。一处简单的修改就能达到目的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<
select
id=
"findActiveBlogLike"
resultType=
"Blog"
>
SELECT
*
FROM
BLOG
<
where
>
<if test=
"state != null"
>
state = #{state}
</if>
<if test=
"title != null"
>
AND
title
like
#{title}
</if>
<if test=
"author != null and author.name != null"
>
AND
author_name
like
#{author.
name
}
</if>
</
where
>
</
select
>
|
where 元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。而且,若语句的开头为“AND”或“OR”,where 元素也会将它们去除.
如果 where 元素没有按正常套路出牌,我们可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:
1
2
3
|
<trim prefix=
"WHERE"
prefixOverrides=
"AND |OR "
>
...
</trim>
|
prefixOverrides 属性会忽略通过管道分隔的文本序列(注意此例中的空格也是必要的)。它的作用是移除所有指定在 prefixOverrides 属性中的内容,并且插入 prefix 属性中指定的内容.
类似的用于动态更新语句的解决方案叫做 set。set 元素可以用于动态包含需要更新的列,而舍去其它的。比如:
1
2
3
4
5
6
7
8
9
10
|
<
update
id=
"updateAuthorIfNecessary"
>
update
Author
<
set
>
<if test=
"username != null"
>username=#{username},</if>
<if test=
"password != null"
>
password
=#{
password
},</if>
<if test=
"email != null"
>email=#{email},</if>
<if test=
"bio != null"
>bio=#{bio}</if>
</
set
>
where
id=#{id}
</
update
>
|
这里,set 元素会动态前置 SET 关键字,同时也会删掉无关的逗号,因为用了条件语句之后很可能就会在生成的 SQL 语句的后面留下这些逗号。(译者注:因为用的是“if”元素,若最后一个“if”没有匹配上而前面的匹配上,SQL 语句的最后就会有一个逗号遗留) 。
若你对 set 元素等价的自定义 trim 元素的代码感兴趣,那这就是它的真面目:
1
2
3
|
<trim prefix=
"SET"
suffixOverrides=
","
>
...
</trim>
|
注意这里我们删去的是后缀值,同时添加了前缀值.
foreach 。
动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:
1
2
3
4
5
6
7
8
9
|
<
select
id=
"selectPostIn"
resultType=
"domain.blog.Post"
>
SELECT
*
FROM
POST P
WHERE
ID
in
<foreach item=
"item"
index
=
"index"
collection=
"list"
open
=
"("
separator=
","
close
=
")"
>
#{item}
</foreach>
</
select
>
|
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符.
-释义:
-collection :collection属性的值有三个分别是list、array、map三种,分别对应的参数类型为:List、array、map,上面传的参数为数组,所以值为array 。
-item : 表示在迭代过程中每一个元素的别名 。
-index :表示在迭代过程中每次迭代到的位置(下标) 。
-open :前缀 。
-close :后缀 。
-separator :分隔符,表示迭代时每个元素之间以什么分隔 。
我们通常可以将之用到批量删除、添加等操作中.
你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数.
当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素.
当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值.
以上为个人经验,希望能给大家一个参考,也希望大家多多支持我.
原文链接:https://www.cnblogs.com/jc1997/p/10915286.html 。
最后此篇关于基于mybatis 动态SQL查询总结的文章就讲到这里了,如果你想了解更多关于基于mybatis 动态SQL查询总结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1、定义 设 \(u\) 和 \(v\) 为一张图上的任意两个节点。令 \(c(u, v)\) 为它们之间的边的容量, \(f(u, v)\) 为它们之间的流量,则需要满足以
1、前言 工作中涉及到文件系统,有时候需要判断文件和目录是否存在。我结合apue第四章文件和目录,总结一下如何正确判断文件和目录是否存在,方便以后查询。 2、stat系列函数 stat函数用来
并查集(Union-Find Set): 一种用于管理分组的数据结构。它具备两个操作:(1)查询元素a和元素b是否为同一组 (2) 将元素a和b合并为同一组。 注意:并查集不能将在同一组的元素拆
当下,注解非常流行,以前很长篇的代码,现在基本上一个注解就能搞定。 那,在Mybatis中又有哪些注解呢? Mybatis中的注解基本上都在org.apache.ibatis.annotat
指针操作数组,方法一是p+index,方法二是p[index],第二种方法跟数组访问方法是一样的。 数组引用返回的是数组的第一个元素的指针地址。 可以将指针指向数组的任意元素,然后从那里开始访问
通常部署完php环境后会进行一些安全设置,除了熟悉各种php漏洞外,还可以通过配置php.ini来加固PHP的运行环境,PHP官方也曾经多次修改php.ini的默认设置。 下面对php.ini中一
在JavaScript中,使用typeof可以检测基本数据类型,使用instanceof可以检测引用数据类型。在PHP中,也有检测数据类型的方法,具体如下: 1、输出变量的数据类型(gettype
把图片缓存到本地,在很多场景都会用到,如果只是存储文件信息,那建一个plist文件,或者数据库就能很方便的解决问题,但是如果存储图片到沙盒就没那么方便了。这里简单介绍两种保存图片到沙盒的方法。
(1)需要安装docker容器,在docker容器内安装jenkins,gogs,tomcat。 新建maven项目,添加findbugs plugin。 使用docker
今天主题是实现并发服务器,实现方法有多种版本,先从简单的单进程代码实现到多进程,多线程的实现,最终引入一些高级模块来实现并发TCP服务器。 说到TCP,想起吐槽大会有个段子提到三次握手,也只有程序
如下所示: Ctrl+1或F2快速修复 Ctrl+D快捷删除行 Shift+Enter 快速切换到下一行,在本行的任何位置都可 Ctrl+F11快速运行代码 Alt+上下键 快速移动行(可
JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。 JSP编译后是”类servlet”。 Servlet和JSP最主要的不同点在于,Servlet的应用逻辑
Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键
读取Java文件到byte数组的三种方法(总结) ? 1
用java实现的数组创建二叉树以及递归先序遍历,递归中序遍历,递归后序遍历,非递归前序遍历,非递归中序遍历,非递归后序遍历,深度优先遍历,广度优先遍历8种遍历方式:
1、简明总结 ASCII(char) 返回字符的ASCII码值 BIT_LENGTH(str) 返回字符串的比特长度 CONCAT(s1,s2…,sn)
java应用服务器(web server),是指运行java程序的web应用服务器软件,不包括nginx、Apache等通用web服务器软件。 一、Tomcat Tomcat是Apache 软件基
事务作为抽象层,允许应用忽略DB 内部一些复杂并发问题和某些硬件、软件故障,简化应用层的处理逻辑:事务中止(transaction abort),而应用仅需重试。对复杂访问模式,事务可大大减少需要考虑
我们在本教程学习了如何描述 XML 文档的结构 我们学习到了如何使用 DTD 来定义一个 XML 文档的合法元素,以及如何在我们的 XML 内部或者作为一个外部引用来声明 DTD 我们学习了如何为
在这个XPath 基础教程中我们讲解了如何在 XML 文档中查找信息 我们可以使用 XPath 的元素和属性在 XML 文档中进行导航 我们也学习了如何使用 XPath 中内建的某些标准函数 如
我是一名优秀的程序员,十分优秀!