MyBatis的动态SQL详解

合集下载

mybatis注解动态sql原理

mybatis注解动态sql原理

mybatis注解动态sql原理
MyBatis是一种基于Java语言的持久层框架,提供了一种使用
注解的方式来编写SQL语句,称为MyBatis注解。

动态SQL
是MyBatis中一个重要的特性,可以根据不同的条件生成不同的SQL语句。

MyBatis通过提供注解来实现动态SQL。

注解是一种元数据,
可以通过在方法或参数上添加注解来指定SQL语句的一些特性。

MyBatis注解提供了多种条件注解,用于动态生成SQL语句。

动态SQL的原理如下:
1. 在Java代码中,我们可以通过添加不同的注解来指定SQL
语句的不同条件,比如条件判断、循环等。

2. MyBatis会解析这些注解,并根据注解中的条件生成对应的SQL语句。

例如,如果有一个条件判断的注解,MyBatis会根
据条件判断的结果来生成对应的SQL语句。

3. 生成的SQL语句会被传递给数据库进行执行。

动态SQL的好处是可以根据不同的条件生成不同的SQL语句,从而实现更灵活的查询功能。

同时,使用注解编写SQL语句,可以减少编写XML配置文件的工作量,提高开发效率。

总结起来,动态SQL是通过使用注解来指定SQL语句的不同
条件,MyBatis会根据注解中的条件生成对应的SQL语句,从而实现灵活的查询功能。

mybatis 动态sql if用法

mybatis 动态sql if用法

电子合同存证服务合同甲方(以下简称“甲方”):公司名称:法定代表人姓名:注册地址:乙方(以下简称“乙方”):公司名称:法定代表人姓名:注册地址:鉴于甲方拥有一定的电子合同存证服务能力,乙方希望委托甲方为其提供电子合同存证服务,各方经友好协商,达成如下协议:第一条服务内容1.1甲方应根据乙方的需求,为其提供电子合同存证服务,具体服务内容如下:(1)检验、验证和签署电子合同的真实性和完整性;(2)为电子合同提供可追溯的时间戳;(3)提供电子合同存证的相关证明文件;(4)确保电子合同数据的安全性和保密性;(6)其他甲方与乙方约定的服务。

1.2甲方应按照服务内容及时、准确地向乙方提供相关服务。

乙方应根据甲方的要求提供相应的合同、协议等信息,以便甲方进行存证操作。

1.3乙方委托甲方存证的电子合同应符合国家法律法规规定的合法合同,甲方不对电子合同的内容、效力和合法性承担责任。

第二条服务费用及支付方式2.1乙方向甲方支付的服务费用为每份电子合同存证服务收费XXXX元。

2.2服务费用的支付方式为:(1)乙方应在甲方提供存证服务后的7个工作日内,将应付费用以现金/银行转账/电汇等方式支付至甲方指定的账户;(2)乙方应提供相应的付款凭证给予甲方,以便甲方核查。

2.3如乙方逾期未支付服务费用,甲方有权采取如下措施之一或多项:(1)中止电子合同存证服务;(2)要求乙方支付延迟履行的违约金;(3)要求乙方支付逾期履行的滞纳金;(4)追究乙方的违约责任。

第三条保密义务3.1甲方应对乙方委托存证的电子合同数据严格保密,不得泄露、篡改或非法使用。

3.2甲方不得将乙方的电子合同数据提供给任何第三方,除非取得乙方书面同意或法律法规另有规定。

3.3乙方如发现甲方存在泄露、篡改或非法使用电子合同数据等违法违规行为,有权要求甲方承担相应的法律责任,并取得相应的赔偿。

第四条风险责任4.1由于电子合同存证服务所涉及的信息传输和数据存储,可能面临各种风险,包括但不限于网络故障、黑客攻击、系统崩溃等。

mybatis之动态sql(超详细)

mybatis之动态sql(超详细)

mybatis之动态sql(超详细)动态SQL可以根据具体的参数条件,来对SQL语句进⾏动态拼接。

⽐如在以前的开发中,由于不确定查询参数是否存在,许多⼈会使⽤类似于where 1 = 1来作为前缀,然后后⾯⽤AND拼接要查询的参数,这样,就算要查询的参数为空,也能够正确执⾏查询,如果不加1 = 1,则如果查询参数为空,SQL语句就会变成SELECT * FROM student where,SQL不合法。

mybatis⾥的动态标签主要有if<!-- ⽰例 --><select id="find"resultType="student"parameterType="student">SELECT * FROM student WHERE age >= 18<if test="name != null and name != ''">AND name like '%${name}%'</if></select>当满⾜test条件时,才会将<if>标签内的SQL语句拼接上去。

choose<!-- choose 和 when , otherwise 是配套标签类似于java中的switch,只会选中满⾜条件的⼀个--><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 != null">AND author_name like #{}</when><otherwise>AND featured = 1</otherwise></choose></select>sql<!-- List<User> findByList(List<Integer> list); --><select id="findByList"resultType="er"parameterType="java.util.List"> SELECT * FROM user<include refid="rnm"></include></select><sql id="rnm"><where><if test="list != null and list.size() > 0">AND id in<foreach collection="list"item="id"open="("separator=","close=")">#{id}</foreach></if></where></sql>trimwhere<where>标签只会在⾄少有⼀个⼦元素返回了SQL语句时, 才会向SQL语句中添加WHERE,并且如果WHERE之后是以AND或OR开头,会⾃动将其删掉。

MyBatis执行动态SQL语句详解

MyBatis执行动态SQL语句详解

MyBatis执⾏动态SQL语句详解⼤家基本上都知道如何使⽤ MyBatis 执⾏任意 SQL,使⽤⽅法很简单,例如在⼀个 XXMapper.xml 中:<select id="executeSql" resultType="map">${_parameter}</select>你可以如下调⽤:sqlSession.selectList("executeSql", "select * from sysuser where enabled = 1");或者你可以在 XXMapper.java 接⼝中定义如下⽅法:List<Map> executeSql(String sql);然后使⽤接⼝调⽤⽅法:xxMapper.executeSql("select * from sysuser where enabled = 1");上⾯这些内容可能都会,下⾯在此基础上再复杂⼀点。

假如像上⾯SQL中的enabled = 1我想使⽤参数⽅式传值,也就是写成 enabled = #{enabled},如果你没有遇到过类似这种需求,可能不明⽩为什么要这么写,举个例⼦,要实现⼀种动态查询,可以在前台通过配置 SQL,提供⼀些查询条件就能实现⼀个查询的功能(为了安全,这些配置肯定是开发或者实施做的,不可能让⽤户直接操作数据库)。

针对这个功能,使⽤ MyBatis 实现起来相当容易。

配置 SQL 肯定要执⾏,⽤上⾯讲的这种⽅式肯定可以执⾏ SQL,如何提供参数呢?参数就是enabled = #{enabled}中的#{enabled}部分。

如果再多⼀些条件,⼀个配置好的 SQL 如下:select * from sysuserwhere enabled = #{enabled}and userName like concat('%',#{userName},'%')这种情况下,该怎么⽤ MyBatis 实现呢?⾸先 XML 中修改如下:<select id="executeSql" resultType="map">${sql}</select>接⼝中的⽅法修改为:List<Map> executeSql(Map map);然后调⽤⽅法:Map map = new HashMap();//这⾥的 sql 对应 XML 中的 ${sql}map.put("sql", "select * from sysuser "+ " where enabled = #{enabled} "+ " and userName like concat('%',#{userName},'%')");//#{enabled}map.put("enabled", 1);//#{userName}map.put("userName", "admin");//接⼝⽅式调⽤List<Map> list = xxMapper.executeSql(map);//sqlSession⽅式调⽤sqlSession.selectList("executeSql", map);有了这个SQL之后,就可以将 enabled 和 userName 作为条件提供给⽤户。

Mybatis中的动态SQL语句解析

Mybatis中的动态SQL语句解析

Mybatis中的动态SQL语句解析这篇⽂章主要介绍了Mybatis中的动态SQL语句解析,⽂中通过⽰例代码介绍的⾮常详细,对⼤家的学习或者⼯作具有⼀定的参考学习价值,需要的朋友可以参考下 Mybatis中配置SQL有两种⽅式,⼀种是利⽤xml ⽅式进⾏配置,⼀种是利⽤注解进⾏配置。

Mybatis使⽤注解配置SQL,但是由于配置功能受限,⽽且对于复杂的SQL⽽⾔可读性很差,所以很少使⽤。

Mybatis常⽤xml配置的⽅式,使⽤xml的⼏个简单的元素,便能完成动态SQL的功能,⼤量的判断都可以在mybaties的映射xml⾥⾯配置,以达到许多需要⼤量代码才能实现的功能,⼤⼤减少了代码量,体现了Mybatis的灵活、⾼度可配置性和维护性。

元素作⽤备注if判断语句单条件分⽀判断choose(when,otherwise)相当于Java中的switch和case语句多条件分⽀判断trim辅助元素,⽤于处理特定的SQL拼装问题⽤于处理SQL拼装的问题foreach循环语句在in语句等列表条件常⽤if元素 if元素是最常⽤的判断语句,相当于Java中国的 if 语句,它常常与test属性联合使⽤。

<select id="findRole1" parameterType="string" resultMap="roleResultMap">select role_no, role_name, note from t_role where 1=1<if test="roleName != null and roleName !=''">and role_name like concat('%', #{roleName}, '%')</if></select> 当参数roleName传递进映射器时,如果参数不为空,则采取构造对 roleName 的模糊查询,否则就不要去构造这个条件。

MyBatis动态SQL————MyBatis动态SQL标签的用法

MyBatis动态SQL————MyBatis动态SQL标签的用法

MyBatis动态SQL————MyBatis动态SQL标签的⽤法1.MyBatis动态SQLMyBatis 的强⼤特性之⼀便是它的动态 SQL,即拼接SQL字符串。

如果你有使⽤ JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。

拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。

利⽤动态 SQL 这⼀特性可以彻底摆脱这种痛苦。

通常使⽤动态 SQL 不可能是独⽴的⼀部分,MyBatis 当然使⽤⼀种强⼤的动态 SQL 语⾔来改进这种情形,这种语⾔可以被⽤在任意的 SQL 映射语句中。

动态 SQL 元素和使⽤ JSTL 或其他类似基于 XML 的⽂本处理器相似。

在 MyBatis 之前的版本中,有很多的元素需要来了解。

MyBatis 3 ⼤⼤提升了它们,现在⽤不到原先⼀半的元素就可以了。

MyBatis 采⽤功能强⼤的基于 OGNL 的表达式来消除其他元素。

2.动态SQL标签:if,choose (when, otherwise),trim (where, set),foreach2.1 if标签:直接上代码<select id="queryByIdAndTitle"resultType="Blog">SELECT * FROM BLOGWHERE 1=1<if test="id!= null and title!=null">AND id=#{id} and title=#{title}</if></select>注:if标签⼀般⽤于⾮空验证,如上例,若id为空,if标签⾥的代码,将不会执⾏,反之,则会执⾏。

2.2 choose(when,otherwise)标签:直接上代码<select id="queryBy"resultType="Blog">SELECT * FROM BLOG WHERE 1=1<choose><when test="title != null">AND title like #{title}</when><otherwise>AND id= 1</otherwise></choose></select>注:choose(when,otherwise)标签相当于switch(case,default) ,如上例,若title 为空,when标签⾥的代码,将不会执⾏,默认执⾏otherwise 标签⾥⾯的代码。

ibaties 动态sql 解析

ibaties 动态sql 解析

ibaties 动态sql 解析iBATIS (现在已经更名为MyBatis) 是一款流行的Java 持久化框架,具有强大的动态SQL 解析功能。

动态SQL 在开发过程中经常用到,它允许我们创建灵活的SQL 查询,根据不同的条件生成不同的SQL 语句。

本文将以"iBATIS 动态SQL 解析" 为主题,详细介绍如何使用iBATIS 动态SQL 解析功能进行动态SQL 查询。

第一步: 环境准备在开始使用iBATIS 的动态SQL 解析功能之前,首先需要准备开发环境。

我们需要安装Java JDK 和一个Java 开发环境,例如Eclipse 或者IntelliJ IDEA。

另外,还需要在项目中引入iBATIS 的相关依赖库。

第二步: 配置数据源和iBATIS在准备好开发环境后,接下来需要配置数据源和iBATIS。

首先,我们需要连接到数据库,可以选择MySQL、Oracle 或者其他主流的数据库。

在项目中,可以通过配置数据源的方式连接到数据库。

接下来,需要在项目中引入iBATIS 的配置文件,通常命名为"SqlMapConfig.xml"。

在该配置文件中,我们需要配置数据库连接信息、iBATIS 的相关设置以及动态SQL 查询语句的配置。

第三步: 创建实体类和映射文件在配置好数据源和iBATIS 后,接下来需要创建实体类和映射文件。

实体类是与数据库中的表对应的Java 类,我们需要定义实体类的属性和相应的getter 和setter 方法。

映射文件是iBATIS 中的核心组件,用于描述数据库表和实体类之间的映射关系。

在映射文件中,我们需要定义SQL 查询语句,包括静态SQL 和动态SQL。

其中,动态SQL 部分使用iBATIS 的"动态SQL 标签" 实现。

第四步: 使用动态SQL在准备好实体类和映射文件后,我们可以开始使用iBATIS 的动态SQL 功能。

MyBatis源码解析----MyBatis动态SQL底层原理分析

MyBatis源码解析----MyBatis动态SQL底层原理分析

MyBatis源码解析----MyBatis动态SQL底层原理分析前⾔废话不多说,直接进⼊⽂章。

我们在使⽤mybatis的时候,会在xml中编写sql语句。

⽐如这段动态sql代码:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<update id="update"parameterType="er"> UPDATE users<trim prefix="SET"prefixOverrides=","><if test="name != null and name != ''">name = #{name}</if><if test="age != null and age != ''">, age = #{age}</if><if test="birthday != null and birthday != ''">, birthday = #{birthday}</if></trim>where id = ${id}</update>mybatis底层是如何构造这段sql的?这⽅⾯的知识⽹上资料不多,于是就写了这么⼀篇⽂章。

下⾯带着这个疑问,我们⼀步⼀步分析。

介绍MyBatis中⼀些关于动态SQL的接⼝和类SqlNode接⼝,简单理解就是xml中的每个标签,⽐如上述sql的update,trim,if标签:1 2 3public interface SqlNode {boolean apply(DynamicContext context); }SqlSource Sql源接⼝,代表从xml⽂件或注解映射的sql内容,主要就是⽤于创建BoundSql,有实现类DynamicSqlSource(动态Sql 源),StaticSqlSource(静态Sql源)等:1 2 3public interface SqlSource {BoundSql getBoundSql(Object parameterObject); }BoundSql类,封装mybatis最终产⽣sql的类,包括sql语句,参数,参数源数据等参数:XNode,⼀个Dom API中的Node接⼝的扩展类。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

MyBatis的动态SQL详解MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。

MyBatis中用于实现动态SQL的元素主要有:∙if∙choose(when,otherwise)∙trim∙where∙set∙foreachif就是简单的条件判断,利用if语句我们可以实现某些简单的条件选择。

先来看如下一个例子:01<selectid="dynamicIfTest"parameterType="Blog"resultType="Blog">02 select * from t_blog where 1 = 103 <iftest="title != null">05 and title = #{title}06 </if>07 <iftest="content != null">08 and content = #{content}09 </if>10 <iftest="owner != null">11 and owner = #{owner}12 </if>14</select>这条语句的意思非常简单,如果你提供了title参数,那么就要满足title=#{title},同样如果你提供了Content和Owner的时候,它们也需要满足相应的条件,之后就是返回满足这些条件的所有Blog,这是非常有用的一个功能,以往我们使用其他类型框架或者直接使用JDBC的时候,如果我们要达到同样的选择效果的时候,我们就需要拼SQL语句,这是极其麻烦的,比起来,上述的动态SQL就要简单多了。

choose元素的作用就相当于JAVA中的switch语句,基本上跟JSTL中的choose的作用和用法是一样的,通常都是与when和otherwise搭配的。

看如下一个例子:0 1<selectid="dynamicChooseTest"parameterType="Blog"resultType="Blog" >2select * from t_blog where 1 = 103 <choose>05 <whentest="title != null">06 and title = #{title}07 </when>08 <whentest="content != null">09 and content = #{content}10 </when>11 <otherwise>13 and owner = "owner1"14 </otherwise>15 </choose>16</select>when元素表示当when中的条件满足的时候就输出其中的内容,跟JAVA中的switch效果差不多的是按照条件的顺序,当when中有条件满足的时候,就会跳出choose,即所有的when和otherwise条件中,只有一个会输出,当所有的我很条件都不满足的时候就输出otherwise中的内容。

所以上述语句的意思非常简单,当title!=null的时候就输出and titlte = #{title},不再往下判断条件,当title为空且content!=null的时候就输出and content =#{content},当所有条件都不满足的时候就输出otherwise中的内容。

where语句的作用主要是简化SQL语句中where中的条件判断的,先看一个例子,再解释一下where的好处。

01<selectid="dynamicWhereTest"parameterType="Blog"resultType="Blog">02 select * from t_blog03 <where>04 <iftest="title != null">05 title = #{title}06 </if>07 <iftest="content != null">09 and content = #{content}10 </if>11 <iftest="owner != null">12 and owner = #{owner}13 </if>14 </where>15</select>where元素的作用是会在写入where元素的地方输出一个where,另外一个好处是你不需要考虑where元素里面的条件输出是什么样子的,MyBatis会智能的帮你处理,如果所有的条件都不满足那么MyBatis就会查出所有的记录,如果输出后是and 开头的,MyBatis会把第一个and忽略,当然如果是or开头的,MyBatis也会把它忽略;此外,在where元素中你不需要考虑空格的问题,MyBatis会智能的帮你加上。

像上述例子中,如果title=null,而content != null,那么输出的整个语句会是select * from t_blog where content = #{content},而不是select * from t_blog where and content = #{content},因为MyBatis会智能的把首个and 或or 给忽略。

trim元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是prefix和suffix;可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是prefixOverrides和suffixOverrides;正因为trim有这样的功能,所以我们也可以非常简单的利用trim来代替where元素的功能,示例代码如下:01<selectid="dynamicTrimTest"parameterType="Blog"resultType="Blog">02 select * from t_blog03 <trimprefix="where"prefixOverrides="and |or">05 <iftest="title != null">06 title = #{title}07 </if>08 <iftest="content != null">09 and content = #{content}10 </if>11 <iftest="owner != null">13 or owner = #{owner}14 </if>15 </trim>16</select>set元素主要是用在更新操作的时候,它的主要功能和where元素其实是差不多的,主要是在包含的语句前输出一个set,然后如果包含的语句是以逗号结束的话将会把该逗号忽略,如果set包含的内容为空的话则会出错。

有了set元素我们就可以动态的更新那些修改了的字段。

下面是一段示例代码:01<updateid="dynamicSetTest"parameterType="Blog">02 update t_blog03 <set>04 <iftest="title != null">05 title = #{title},06 </if>07 <iftest="content != null">0809 content = #{content},10 </if>11 <iftest="owner != null">12 owner = #{owner}14 </set>15 where id = #{id}16</update>上述示例代码中,如果set中一个条件都不满足,即set中包含的内容为空的时候就会报错。

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。

foreach元素的属性主要有item,index,collection,open,separator,close。

item表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection 属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key下面分别来看看上述三种情况的示例代码:1.单参数List的类型:1<selectid="dynamicForeachTest"resultType="Blog">2 select * from t_blog where id in3 <foreachcollection="list"index="index"item="item"open="("separa tor=","close=")">5 </foreach>67</select>上述collection的值为list,对应的Mapper是这样的1publicList<Blog>dynamicForeachTest(List<Integer> ids);测试代码:01@Test02publicvoiddynamicForeachTest() {03 SqlSession session = Util.getSqlSessionFactory().openSession();04 BlogMapperblogMapper = session.getMapper(BlogMapper.class);05 List<Integer> ids = newArrayList<Integer>();06 ids.add(1);07 ids.add(3);08 ids.add(6);09 List<Blog> blogs = blogMapper.dynamicForeachTest(ids);10 for(Blog blog : blogs)11 System.out.println(blog);12 session.close();13}2.单参数array数组的类型:1<selectid="dynamicForeach2Test"resultType="Blog">2 select * from t_blog where id in3 <foreachcollection="array"index="index"item="item"open="("separ ator=","close=")">4 #{item}5 </foreach>6</select>上述collection为array,对应的Mapper代码:1publicList<Blog> dynamicForeach2Test(int[] ids);对应的测试代码:01@Test02publicvoiddynamicForeach2Test() {03 SqlSession session = Util.getSqlSessionFactory().openSession();04 BlogMapperblogMapper = session.getMapper(BlogMapper.class);05 int[] ids = newint[] {1,3,6,9};06 List<Blog> blogs = blogMapper.dynamicForeach2Test(ids);07 for(Blog blog : blogs)08 System.out.println(blog);09 session.close();10}3.自己把参数封装成Map的类型1<selectid="dynamicForeach3Test"resultType="Blog">2 select * from t_blog where title like "%"#{title}"%" and id in3 <foreachcollection="ids"index="index"item="item"open="("separat or=","close=")">4 #{item}5 </foreach>67</select>上述collection的值为ids,是传入的参数Map的key,对应的Mapper代码:1publicList<Blog> dynamicForeach3Test(Map<String, Object>params);对应测试代码:01@Test02publicvoiddynamicForeach3Test() {03 SqlSession session = Util.getSqlSessionFactory().openSession();04 BlogMapperblogMapper = session.getMapper(BlogMapper.class);05 finalList<Integer> ids = newArrayList<Integer>();06 ids.add(1);07 ids.add(2);08 ids.add(3);09 ids.add(6);10 ids.add(7);11 ids.add(9);12 Map<String, Object>params = newHashMap<String, Object>();13 params.put("ids", ids);14 params.put("title", "中国");15 List<Blog> blogs = blogMapper.dynamicForeach3Test(params);16 for(Blog blog : blogs)17 System.out.println(blog);18 session.close();19}。

相关文档
最新文档