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. 【密码学】SHA1算法实现及详解

    1 SHA1算法简介 安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digit ...

  2. 5 - 参考函数-API

    5.1 鼠标管理 a). MouseClick 点击鼠标 MouseClick ( "button" [, x, y [, clicks = 1 [, speed = 10]]] ...

  3. idea没有绑远程地址,如何提交到github的空项目

    一 有同事问我怎么提交到github的空项目....这么简单.... 二 1.创建本地的git仓库 选择自己的项目 创建成功 2.添加代码,选中左边的文件,add 3.提交 5.定义远程仓库,不定义的 ...

  4. ElasticSearch最新版本下载地址

    直接访问官方很慢,打不开,找到这个下载方法: ElasticSearch下载地址: https://download.elastic.co/elasticsearch/elasticsearch/el ...

  5. jquery jquery选择器总结 转自(永远的麦子)

    jQuery选择器总结 阅读目录 1, 基本选择器? 2, 层次选择器? 3, 过滤选择器? 4, 表单选择器? jQuery选择器共有四大类,分别为基本选择器,层次选择器,过滤选择器和表单选择器.下 ...

  6. 关于IE的一些hack

    TIPS:对于完全放弃IE的幸福开发者,以下内容全是废话,建议跳转到 博客园 着页,寻找更优质的文章. 对于前端开发来说IE一直是心里的痛,不管你觉得做的多好的网页,放到它上面总会有一些意想不到的问题 ...

  7. Canny边缘检测学习

    Canny边缘检测学习:http://www.open-open.com/lib/view/open1453460512558.html 高斯滤波学习:http://www.cnblogs.com/q ...

  8. Today is the first day of the rest of your life.

    Today is the first day of the rest of your life. 今天是你余下人生的第一天.

  9. angularjs嵌套路由

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  10. mui的ajax例子3

    mui.get() 前端页面: <!DOCTYPE html><html><head> <meta charset="utf-8"> ...