mybatis之动态SQL
来源:互联网 发布:单片机系统电路原理图 编辑:程序博客网 时间:2024/05/22 04:25
动态SQL
mybatis最强大的特点就是有动态SQL。如果你曾经使用过JDBC或者类似的框架,你可以明白把有条件的SQL字符串放在一起是多么痛苦,确定在列表的最后没有忘掉空格或者遗漏逗号。动态SQL可以完美的解决这一切。
然而使用动态SQL并不是永远很完美,mybatis在某种程度上使用强有力的动态SQL改善了那种环境,可以在任何映射的SQL语句中使用动态SQL。
动态SQL元素应该对于任何人来说都很熟悉,它采用了基于JSTL或者类似于XML的文本。在mybatis以前的版本中,这里有许多元素需要去了解和理解。mybatis3在这点改善了很多,现在这里只有大概不到一半的元素。mybatis使用了强大的OGNL表达式来排除其他的元素。
if
choose (when, otherwise)
trim (where, set)
foreach
if
动态SQL中最常见的是就是有条件的包含where子句的一部分,如下:
<select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{title} </if></select>
这个语句提供了一个功能性的可供选择的文本搜索类型。如果没有传title,所有激活的Blogs将会返回。但是如果你传递了一个title,它将会寻找与其相似的。
如果我们想通过title和author来进行选择会发生什么?首先,必须改变语句的名字来使其有意义。紧接着添加另一个条件
<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
有时候我们不想所有的条件都被应用,相反我们想选择一些来进行应用。类似于JAVA中的switch语句。mybatis也提供了一个choose元素。
让我们使用上面的例子,但是现在让我们搜索仅仅被提供title的情况,接着搜索提供author的情况,如果两个都没有被提供,它就会返回有特征的blog(管理员或许在一个战略列表进行选择,而不是返回一个很大却没有意义的列表)。
<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作为一个动态条件。
<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>
如果没有条件被发现会有什么结果?类似于下面的例子代码:
SELECT * FROM BLOGWHERE
将会失败。如果只有第二个条件出现,会发生什么?类似于下面这样结束你的SQL:
SELECT * FROM BLOGWHEREAND title like ‘someTitle’
这个也会失败。这个问题不是很容易被用条件来解决的。如果你曾经写过这样的,你将永远不会再这样做一次了。
mybatis有一个简单的答案可能在90%的例子中都会起作用。在这个例子中,你可以定制它让它起作用。
<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元素知道仅仅在包含标签有内容返回的地方插入。此外,如果内容以and或者or开头,它知道去除掉and或者or。
如果where子句并没有做出和你所想的那样的操作,你可以通过使用trim元素来定义,使它可以起作用。例如,trim等价于where元素,如下:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ...</trim>
属性prefixOverrides 采用了管道文本的列表进行重写限制那些和空格有关的。结果是在属性prefixOverrides 任何具体的被移除。在属性prefix 中任何的插入。
对于动态SQL,这里也有一个相似的解决方案被叫做set。set元素可以被使用来动态包含列来更新,忽略其它。例如:
<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关键字,而且排除额外的逗号,追踪在条件被应用后任务的值。
如果你对trim元素的等价形式很好奇,你可以看下面的:
<trim prefix="SET" suffixOverrides=","> ...</trim>
注意:在这个例子中我们重写了一个suffix,然而我们仍然添加了一个prefix
foreach
动态SQL中另一个共通必要的就是需要遍历集合,经常需要建立in条件,例如:
<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元素是很强大的,它允许你指定一个collection,声明item和index变量,可以在元素的body内部使用。它也允许你指定一个opening和closing字符串,并且添加一个separator 放在迭代之间。它不会偶然的增加额外的separator。
注意你可以传递Iterable变量(例如:list,set等),当然也有map或者数组对象来遍历当做collection的参数。当使用一个Iterable 或者数组,下标将会是当前迭代的数字,值将会是在迭代过程中取回的元素的值。当使用map,index将会是key对象,item将会是value对象。
这将讨论有关xml配置文件和xml映射文件.下个章节将会详细的讨论JAVA API,这样你就可以从你创建的映射中得到最多的
bind
bind元素可以让你从一个OGNL表达式创建一个变量,并且与上下文绑定,例如:
<select id="selectBlogsLike" resultType="Blog"> <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern}</select>
多个数据库供应商的支持
如果一个提供的数据库被配置了一个_databaseId变量,这个变量是一个可利用的动态代码,你可以依赖数据库供应商建立不同的语句,看一下下面这个例子:
<insert id="insert"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> <if test="_databaseId == 'oracle'"> select seq_users.nextval from dual </if> <if test="_databaseId == 'db2'"> select nextval for seq_users from sysibm.sysdummy1" </if> </selectKey> insert into users values (#{id}, #{name})</insert>
对于动态SQL来说Pluggable Scripting语言是从mybatis3.2开始的支持Pluggable Scripting语言,所以你可以添加一个语言驱动并且使用它来写你的动态SQL查询。
你可以通过实现下面的接口来添加一个语言:
public interface LanguageDriver { ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql); SqlSource createSqlSource(Configuration configuration, XNode script, Class<?> parameterType); SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType);}
一旦你有自己的原因驱动你可以在mybatis-config.xml文件中设置为默认的语言。
<typeAliases> <typeAlias type="org.sample.MyLanguageDriver" alias="myLanguage"/></typeAliases><settings> <setting name="defaultScriptingLanguage" value="myLanguage"/></settings>
而不是改变默认的,你可以通过添加lang元素为某个具体的语句来指定语言,如下所示:
<select id="selectBlog" lang="myLanguage"> SELECT * FROM BLOG</select>
或者,在这种情况下使用映射类,使用@Lang注解
public interface Mapper { @Lang(MyLanguageDriver.class) @Select("SELECT * FROM BLOG") List<Blog> selectBlog();}
注意:你可以使用Apache Velocity作为你的动态语言,看一下MyBatis-Velocity可以得到更多详情。
All the xml tags you have seen in the previous sections are provided by the default MyBatis language that is provided by the driver org.apache.ibatis.scripting.xmltags.XmlLanguageDriver which is aliased as xml.
- mybatis之动态SQL
- MyBatis之动态SQL
- Mybatis之动态sql
- mybatis之动态SQL
- MyBatis之动态sql
- Mybatis之动态 SQL
- Mybatis之动态sql
- MyBatis之动态SQL语句
- mybatis之动态sql总结
- Mybatis小结之动态sql
- mybatis学习之动态SQL
- mybatis之动态sql(八)
- Mybatis系列之动态SQL
- mybatis 动态sql之foreach
- mybatis之动态sql语句
- MyBatis学习 之 三、动态SQL语句
- MyBatis学习 之 三、动态SQL语句
- MyBatis学习 之 三、动态SQL语句
- mybatis之XML映射文件
- ubuntu下andriod-webrtc编译步骤
- Swift 之UISegmentedControl
- Python获取股票历史数据和收盘数据的代码实现
- Java中处理异常throw和throws
- mybatis之动态SQL
- mybatis之JAVA API
- Spring配置文件中读取Properties文件的配置
- List<T>的各种排序方法
- 软件工程 基本概念
- mybatis创建SQL的类
- 【强烈推荐】开源C#工具类MSCL系列(一)配置帮助类
- mybatis日志
- MFC运行时窗口总是最小化,不直接弹出