笔记53 Mybatis快速入门(四)

动态SQL

1.if

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

Product.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper
 3     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 
 6 <mapper namespace="mybatis.pojo">
 7 
 8     <select id="listProduct1" resultType="Product">
 9         select * from product
10     </select>
11     <select id="listProductByName" resultType="Product">
12         select *
13         from product where name like concat('%',#{name},'%')
14     </select>
15 </mapper>

Test.java

 1 package mybatis.test;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.util.HashMap;
 6 import java.util.List;
 7 import java.util.Map;
 8 
 9 import org.apache.ibatis.session.SqlSession;
10 import org.apache.ibatis.session.SqlSessionFactory;
11 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
12 
13 import mybatis.pojo.Product;
14 
15 public class testIf {
16     public static void main(String[] args) throws IOException {
17         String resource = "mybatis-config.xml";
18         InputStream inputStream = org.apache.ibatis.io.Resources.getResourceAsStream(resource);
19         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
20         SqlSession session = sqlSessionFactory.openSession();
21 
22          System.out.println("查询所有的");
23          List<Product> products = session.selectList("listProduct1");
24          for (Product product : products) {
25          System.out.println(product);
26          }
27         
28          System.out.println("模糊查询");
29          Map<String, Object> params = new HashMap<String, Object>();
30          params.put("name", "a");
31          List<Product> products2 = session.selectList("listProductByName",
32          params);
33          for (Product product : products2) {
34          System.out.println(product);
35          }
36 
37         session.commit();
38         session.close();
39     }
40 }

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

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

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

 1         System.out.println("查询所有的");
 2         List<Product> products = session.selectList("listProduct2");
 3         for (Product product : products) {
 4             System.out.println(product);
 5         }
 6 
 7         System.out.println("模糊查询");
 8         Map<String, Object> params = new HashMap<String, Object>();
 9         params.put("name", "a");
10         List<Product> products2 = session.selectList("listProduct2", params);
11         for (Product product : products2) {
12             System.out.println(product);
13         }

2.where

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

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

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

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

 1     <select id="listProduct4" resultType="Product">
 2         select * from product
 3         <where>
 4             <if test="name!=null">
 5                 and name like concat('%',#{name},'%')
 6             </if>
 7             <if test="price!=null and price!=0">
 8                 and price>#{price}
 9             </if>
10         </where>
11     </select>

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

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

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

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

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

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

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

1 <trim prefix="SET" suffixOverrides=",">
2   ...
3 </trim>

示例:

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

3.choose

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

 1     <select id="listProduct6" resultType="Product">
 2         select * from product
 3         <where>
 4             <choose>
 5                 <when test="name!=null">
 6                     and name like concat('%',#{name},'%')
 7                 </when>
 8                 <when test="price!=null and price!=0">
 9                     and price>#{price}
10                 </when>
11                 <otherwise>
12                     and id>1
13                 </otherwise>
14             </choose>
15         </where>
16     </select>

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

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

查询结果:

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

4.foreach

适用情况如下所示:

1     <select id="listProduct7" resultType="Product">
2         select * from product
3         where id in
4         <foreach item="item" index="index" collection="list" open="("
5             separator="," close=")">
6             #{item}
7         </foreach>
8     </select>

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

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

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

open :前缀     

close :后缀     

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

测试:

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

结果:

5.bind

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

1     <select id="listProductByName" resultType="Product">
2         select *
3         from product
4         where name like concat('%',#{name},'%')
5     </select>
1     <select id="listProductByName2" resultType="Product">
2         <bind name="likename" value="'%'+name+'%'"/>
3         select *
4         from product
5         where name like #{likename}
6     </select>
posted @ 2018-06-27 17:22  雨落忧伤-  阅读(196)  评论(0编辑  收藏  举报