1.参考官方文档
? if:字符判断
? choose (when, otherwise):分支选择
? trim (where, set):字符串截取;其中where标签封装查询条件,set标签封装修改条件
? foreach

2.if案例

1)在EmployeeMapper接口中添加一个方法:
//携带了哪个字段,查询条件就带上哪个字段的值
public List<Employee> getEmployeeByConditionIf(Employee employee);

2).如果要写下列的SQL语句,只要是不为空,就作为查询条件,如下所示,这样写实际上是有问题的,所以我们要写成动态SQL语句:
<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">
select *from tbl_employee where id = #{id} and user_name = #{userName} and email = #{email} and gender = #{gender}
</select>

3)用if标签改写为动态SQL,如下所示:

<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">
select *from tbl_employee
where
<!--
test:判断表达式(OGNL)
OGNL参照PPT或者官方文档。
c:if test
从参数中取值进行判断
遇见特殊符号,应该去写转义字符:参考W3CSchool>>HTML>>ISO8859 -->
<if test="id != null">
id = #{id}
</if>
<if test="userName != null && userName !=''">
and user_name = #{userName}
</if>
<if test="email != null and email.trim() != """>
and email = #{email}
</if>
<!-- ognl会进行字符串和数字的转换判断;"0"==0,"1"==1 -->
<if test="gender == 0 or gender == 1">
and gender = #{gender}
</if>
</select>

   4).测试代码:

@Test
public void testGetEmployee(){
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setId(1);
employee.setUserName("张三丰");
employee.setEmail("sunwukong@163.com");
employee.setGender(1);
List<Employee> list = mapper.getEmployeeByConditionIf(employee);
System.out.println(list);
}

  

但是仔细来说,上面的sql语句是有问题的,当我们不给动态sql语句传递id值的时候,sql语句的拼装就会有问题!
解决办法:
       1>.给where后面加上1=1,以后的条件都可以使用and xxx了
       2>.mybatis可以使用where标签来将所有的查询条件包括在内。mybatis就会将where标签中拼装的sql,
         多出来的and或者or去掉!//需要注意:where标签只会去掉第一个多出来的and或者or
      3.>也就是说使用where标签有时候还是不能解决问题的,那怎么办呢?我们这里可以使用trim标签!

2.trim标签:可以自定义字符串的截取规则

<select id="getEmployeeByConditionIf" resultType="com.neuedu.entity.Employee">
select *from tbl_employee
<!--
后面多出的and或者or where标签不能够解决
prefix="":前缀:trim标签体重是整个字符串拼串后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides="":
前缀覆盖:去掉整个字符串前面多余的字符
suffix="":后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides="":
后缀覆盖:去掉整个字符串后面多余的字符
-->
<trim prefix="where" suffixOverrides="and">
<if test="id != null">
id = #{id} and
</if>
<if test="userName != null && userName !=''">
user_name = #{userName} and
</if>
<if test="email != null and email.trim() != """>
email = #{email} and
</if>
<!-- ognl会进行字符串和数字的转换判断;"0"==0,"1"==1 -->
<if test="gender==0 or gender==1">
gender = #{gender}
</if>
</trim>
</select>

  3.choose标签:分支选择,类似于Java中的带了break的switch...case

choose (when, otherwise):如果带了id,就用id查,如果带了userName就用userName查,只会进入其中一个!

案例演示:
     1>.在EmployeeMapper接口中添加一个方法:
            public List<Employee> getEmployeeByConditionChoose(Employee employee);
        2>.sql映射文件

<!-- public List<Employee> getEmployeeByConditionChoose(Employee employee); -->
<select id="getEmployeeByConditionChoose" resultType="com.neuedu.entity.Employee">
select *from tbl_employee
<where>
<!-- 如果带了id,就用id查,如果带了userName就用userName查,只会进入其中一个! -->
<choose>
<when test="id != null">
id = #{id}
</when>
<when test="userName != null">
user_name like #{userName}
</when>
<when test="email != null">
email = #{email}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>

  

4.trim 中的set标签(where, set):字符串截取;其中where标签封装查询条件,set标签封装修改条件
set元素会动态前置set关键字,同时也会消除无关的逗号。

1).在EmployeeMapper中添加一个更新的方法,如下所示:
              public void updateEmp(Employee employee);
         2)在sql映射文件中,填写相应的sql语句,如下所示【set标签可以将字段后面的逗号去掉】:

<update id="updateEmp">
update tbl_employee
<set>
<if test="userName != null">
user_name = #{userName},
</if>
<if test="email != null">
email = #{email},
</if>
<if test="gender != null">
gender = #{gender},
</if>
</set>
where id = #{id}
</update>

  测试类代码为:

@Test
public void testGetEmployee(){
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee employee = new Employee();
employee.setId(1);
employee.setUserName("哈哈");
employee.setEmail("sunwukong@163.com");
employee.setGender(1);
mapper.updateEmp(employee);
} //当然上面的set标签我们也可以使用trim标签来代替,如下所示:
<update id="updateEmp">
update tbl_employee
<trim prefix="set" suffixOverrides=",">
<if test="userName != null">
user_name = #{userName},
</if>
<if test="email != null">
email = #{email},
</if>
<if test="gender != null">
gender = #{gender},
</if>
</trim>
where id = #{id}
</update>

  5.foreach:遍历元素

动态SQL的另一个常用的操作是需要对一个集合进行遍历,通常在构建in条件语句的时候!
foreach元素允许指定一个集合,声明集合项和索引变量,并可以指定开闭匹配的字符串以及在迭代之间放置分隔符。

案例演示:
         1>.在EmployeeMapper接口中加入一个方法,如下所示:
            public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);
         2>.在MyBatis的sql映射文件中写相应的代码:

<!-- public List<Employee> getEmpsByConditionForeach(List<Integer> ids); -->
<select id="getEmpsByConditionForeach" resultType="com.neuedu.entity.Employee">
select * from tbl_employee where id in
<!--
collection:指定要遍历的集合
item:将当前遍历出的元素赋值给指定的变量
separator:每个元素之间的分隔符
open:遍历出所有记过拼接一个开始的字符
close:遍历出所有结果拼接一个结束的字符
-->
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</select>

     3.>测试类代码为:

@Test
public void testGetEmployee(){
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
List<Integer> asList = Arrays.asList(1,2,3,4);
List<Employee> emps = mapper.getEmpsByConditionForeach(asList);
for (Employee employee : emps) {
System.out.println(employee);
}
}

  

foreach标签还可以用于批量保存数据,如下所示:

1.在EmployeeMapper接口类中添加批量插入的方法:
public void addEmps(@Param("emps") List<Employee> emps);

2.在EmployeeMapper.xml的sql映射文件中添加响应的语句:

<!-- public void addEmps(@Param("emps") List<Employee> emps); -->
<!-- MySQL下批量保存:可以foreach遍历,mysql支持values(),(),()语法 -->
<insert id="addEmps">
INSERT INTO tbl_employee(user_name,gender,email,d_id) VALUES
<foreach collection="emps" item="emp" separator=",">
(#{emp.userName},#{emp.gender},#{emp.email},#{emp.depart.id})
</foreach>
</insert>
3.测试代码:
@Test
public void testGetEmployee(){
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
List<Employee> emps = new ArrayList<Employee>();
emps.add(new Employee(0, 1, "allen", "allen@163.com", new Department(1)));
emps.add(new Employee(0, 0, "tom", "tom@163.com", new Department(2)));
emps.add(new Employee(0, 1, "mux", "mux@163.com", new Department(1)));
mapper.addEmps(emps);
}

动态拼接SQL语句的更多相关文章

  1. java动态拼接sql语句并且执行时给sql语句的参数赋值

    问题 在这里举一个例子,比如我要做一个多条件模糊查询,用户输入的时候有可能输入一个条件,也有可能输入两个条件,这时执行查询的sql语句就不确定了,但可以用动态拼接sql语句来解决这个问题. 解决方法 ...

  2. 动态拼接SQL 语句

    public T Get<T>(int id) { Type type = typeof(T); string columnStrings = string.Join(",&qu ...

  3. SQL 动态拼接SQL 语句

    USE [PMS_UnifiedDB_15] GO /****** Object: StoredProcedure [dbo].[SP_GetLogInfo] Script Date: 2/11/20 ...

  4. 查询拼接SQL语句,多条件模糊查询

    多条件查询,使用StringBuilder拼接SQL语句,效果如下: 当点击按钮时代码如下: private void button1_Click(object sender, EventArgs e ...

  5. sp_executesql动态执行sql语句并将结果赋值给一变量

    需求场景: 需动态拼接sql语句进行执行,并将执行的结果赋值给一指定变量. 样例代码如下: SELECT @tableName = TAB_NAME FROM dbo.NMR_BLYWBDY WHER ...

  6. 动态执行SQL语句

    在实际制作过程中,需要动态的拼接SQL语句然后执行.具体代码如下: declare @columnName varchar(20),@tempName varchar(20) select @temp ...

  7. 使用exec和sp_executesql动态执行SQL语句(转载)

    当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...

  8. 动态执行SQL语句,接收返回值

    一.exec和sp_executesql介绍 当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句.比如,一个比较通用的分页存储过程,可能需要传入表名,字段,过滤条件, ...

  9. mysql 存储过程动态执行sql语句

    之前经常在程序中拼接sql语句,其实我们也可以在存储过程中拼接sql 语句,动态的执行~~ 代码如下: DROP PROCEDURE IF EXISTS SearchByDoctor;CREATE P ...

随机推荐

  1. java多线程 synchronized关键字的一些用法

    看这篇文章啦: http://blog.csdn.net/xiao__gui/article/details/8188833

  2. HDU 5496——Beauty of Sequence——————【考虑局部】

    Beauty of Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  3. DNS安全浅议、域名A记录(ANAME),MX记录,CNAME记录 专题

    首先要做的就是配置域名的MX 记录啦: 先添加一条A记录: mail.abc.com 指向 你的服务器IP! 然后添加域名的MX 记录,指向mail.abc.com A 记录( 即域名MX 记录的值为 ...

  4. 最简实例演示asp.net5中用户认证和授权(1)

    asp.net5中,关于用户的认证和授权提供了非常丰富的功能,如果结合ef7的话,可以自动生成相关的数据库表,调用也很方便. 但是,要理解这么一大堆关于认证授权的类,或者想按照自己项目的特定要求对认证 ...

  5. 让zepto支持requirejs的方法

    window.Zepto = Zepto '$' in window || (window.$ = Zepto) if ( typeof define === "function" ...

  6. 《C#高效编程》读书笔记05-为类型提供ToString()方法

    System.Object.ToString()是.NET环境中最常用的方法之一.编写类型时,要提供一个合理的ToString版本,否则使用者就不得不自己构造一套可以阅读的表示. public cla ...

  7. C#数字图像处理算法学习笔记(一)--C#图像处理的3中方法

    C#数字图像处理算法学习笔记(一)--C#图像处理的3中方法 Bitmap类:此类封装了GDI+中的一个位图,次位图有图形图像及其属性的像素数据组成.因此此类是用于处理像素数据定义的图形的对象.该类的 ...

  8. iOS 收藏的笔记

    目录 UI 资料类 网络篇 图表 动画 菜单栏 数据存储和数据库 第三方库 社交分享 刷新 视频音频 其他 阅读 JS 导航 系统 支付 书籍 工具类 完整项目收集 DEMO UI http://ww ...

  9. Linux软件相关记录

    Pidgin+lw-web的聊天记录的文件对应的目录为.purple/logs/webqq/你的QQ号码/,进入之后有选择的删除. mkdir -p 递归创建目录:pwd 显示当前目录:cd .. 回 ...

  10. OAuth相关知识

    什么是OAuth认证 1.一种安全认证的协议;2.协议为用户资源的授权提供了一个安全的.开放又简易的标准;3.OAuth的授权不会使第三方触及到用户的账户信息(例如用户名和密码) 网址:www.oau ...