动态SQL

1.if

  假设需要对Product执行两条sql语句,一个是查询所有,一个是根据名称模糊查询。那么按照现在的方式,必须提供两条sql语句:listProduct和listProductByName然后在调用的时候,分别调用它们来执行。如下所示:

Product.xml

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="mybatis.pojo"> <select id="listProduct1" resultType="Product">
select * from product
</select>
<select id="listProductByName" resultType="Product">
select *
from product where name like concat('%',#{name},'%')
</select>
</mapper>

Test.java

 package mybatis.test;

 import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import mybatis.pojo.Product; public class testIf {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession(); System.out.println("查询所有的");
List<Product> products = session.selectList("listProduct1");
for (Product product : products) {
System.out.println(product);
} System.out.println("模糊查询");
Map<String, Object> params = new HashMap<String, Object>();
params.put("name", "a");
List<Product> products2 = session.selectList("listProductByName",
params);
for (Product product : products2) {
System.out.println(product);
} session.commit();
session.close();
}
}

  如果Product的字段比较多的话,为了应付各个字段的查询,那么就需要写多条sql语句,这样就变得难以维护。这个时候,就可以使用Mybatis 动态SQL里的if标签

 <select id="listProduct2" resultType="Product">
select * from product
<if test="name!=null">
where name like concat('%',#{name},'%')
</if>
</select>

  如果没有传参数name,那么就查询所有,如果有name参数,那么就进行模糊查询。这样只需要定义一条sql语句即可应付多种情况了,在测试的时候,也只需要调用这么一条sql语句listProduct 即可。

         System.out.println("查询所有的");
List<Product> products = session.selectList("listProduct2");
for (Product product : products) {
System.out.println(product);
} System.out.println("模糊查询");
Map<String, Object> params = new HashMap<String, Object>();
params.put("name", "a");
List<Product> products2 = session.selectList("listProduct2", params);
for (Product product : products2) {
System.out.println(product);
}

2.where

<1>如果要进行多条件判断,如下所示:

     <select id="listProduct2" resultType="Product">
select * from product
<if test="name!=null">
where name like concat('%',#{name},'%')
</if>
<if test="price!=0">
and price>=#{price}
</if>
</select>
         System.out.println("多条件查询");
Map<String, Object> params = new HashMap<String, Object>();
params.put("name", "a");
params.put("price", "10");
List<Product> products2 = session.selectList("listProduct4", params);
for (Product product : products2) {
System.out.println(product);
}

这么写的问题是:当没有name参数,却有price参数的时候,执行的sql语句就会是:select * from product_ and price > 10。这样就会报错。

这个问题可以通过<where>标签来解决,如代码所示:

     <select id="listProduct4" resultType="Product">
select * from product
<where>
<if test="name!=null">
and name like concat('%',#{name},'%')
</if>
<if test="price!=null and price!=0">
and price>#{price}
</if>
</where>
</select>

<where>标签会进行自动判断:
如果任何条件都不成立,那么就在sql语句里就不会出现where关键字
如果有任何条件成立,会自动去掉多出来的 and 或者 or。

所以map里面两个参数无论是否提供值都可以正常执行。

<2>与where标签类似的,在update语句里也会碰到多个字段相关的问题。 在这种情况下,就可以使用set标签:

     <update id="updateProduct" parameterType="Product">
update product
<set>
<if test="name!=null">name=#{name},</if>
<if test="price!=null">price=#{price}</if>
</set>
where id=#{id}
</update>
         Product product = new Product();
product.setId(6);
product.setName("product xzz");
product.setPrice(6.99f);
session.update("updateProduct", product);

<3>trim 用来定制想要的功能,比如where标签就可以用以下代码替换:

 <trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>

set标签可以用以下代码来替换:

 <trim prefix="SET" suffixOverrides=",">
...
</trim>

示例:

     <select id="listProduct5" resultType="Product">
select * from product
<trim prefix="WHERE" prefixOverrides="AND|OR">
<if test="name!=null">
and name like concat('%',#{name},'%')
</if>
<if test="price!=null and price!=0">
and price>#{price}
</if>
</trim>
</select>
     <update id="updateProduct2" parameterType="Product">
update product
<trim prefix="SET" suffixOverrides=",">
<if test="name!=null">name=#{name},</if>
<if test="price!=null">price=#{price}</if>
</trim>
where id=#{id}
</update>

3.choose

Mybatis里面没有else标签,但是可以使用when otherwise标签来达到这样的效果。

     <select id="listProduct6" resultType="Product">
select * from product
<where>
<choose>
<when test="name!=null">
and name like concat('%',#{name},'%')
</when>
<when test="price!=null and price!=0">
and price>#{price}
</when>
<otherwise>
and id>1
</otherwise>
</choose>
</where>
</select>

作用: 提供了任何条件,就进行条件查询,否则就使用id>1这个条件。

         System.out.println("多条件查询");
Map<String, Object> params = new HashMap<String, Object>();
// params.put("name", "a");
// params.put("price", "10");
List<Product> products2 = session.selectList("listProduct6", params);
for (Product products : products2) {
System.out.println(products);
}

查询结果:

如果去掉注释,提供查询条件,则结果如下:

4.foreach

适用情况如下所示:

     <select id="listProduct7" resultType="Product">
select * from product
where id in
<foreach item="item" index="index" collection="list" open="("
separator="," close=")">
#{item}
</foreach>
</select>

collection :collection属性的值有三个分别是list、array、map三种,分别对应的参数类型为:List、数组、map集合

item : 表示在迭代过程中每一个元素的别名     

index :表示在迭代过程中每次迭代到的位置(下标)     

open :前缀     

close :后缀     

separator :分隔符,表示迭代时每个元素之间以什么分隔

测试:

         List<Integer> idsIntegers = new ArrayList<Integer>();
idsIntegers.add(1);
idsIntegers.add(3);
idsIntegers.add(5); List<Product> products = session.selectList("listProduct7", idsIntegers); for (Product product : products) {
System.out.println(product);
}

结果:

5.bind

bind标签就像是再做一次字符串拼接,方便后续使用。如下所示,在模糊查询的基础上,把模糊查询改为bind标签。

     <select id="listProductByName" resultType="Product">
select *
from product
where name like concat('%',#{name},'%')
</select>
     <select id="listProductByName2" resultType="Product">
<bind name="likename" value="'%'+name+'%'"/>
select *
from product
where name like #{likename}
</select>

最新文章

  1. 【数据库】_由2000W多条开房数据引发的思考、实践----给在校生的一个真实【练耙场】,同学们,来开始一次伟大的尝试吧。
  2. js实现由分隔栏决定两侧div的大小—js动态分割div
  3. td在relative模式下,IE9不显示border
  4. PHP类和对象函数实例详解
  5. javascript 创建对象
  6. 2016年最好的15个Web设计和开发工具
  7. 感知机学习算法 python实现
  8. IOS平台设计规范
  9. 配置Android开发环境
  10. poj1330Nearest Common Ancestors(LCA小结)
  11. 学习json-rpc
  12. Web.config中设置启用webservice远程调试访问
  13. 只有一百行的xss扫描工具——DSXS源码分析
  14. Generator自动生成DAO和POJO代码
  15. 如何保证Redis的高并发
  16. tomcat-会话绑定
  17. codeforces 797B
  18. Task 和 ThreadPool
  19. 创建template模板
  20. C++ Primer 中文版 5th Edition 练习15.8和练习15.9的解答

热门文章

  1. SpringBoot开发详解(五)--Controller接收参数以及参数校验
  2. IIS 承载的服务失败
  3. nginx proxy_pass设置
  4. 【LeetCode】拓扑排序
  5. 【Luogu】【关卡2-15】动态规划的背包问题(2017年10月)【还差一道题】
  6. hdu 5792 线段树+离散化+思维
  7. oracle查询重复数据出现次数
  8. 关系型数据库---MYSQL---系统学习
  9. 【JavaWeb项目】一个众筹网站的开发(六)后台用户权限控制
  10. vue简单的input校验手机号