zoukankan      html  css  js  c++  java
  • 笔记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>
  • 相关阅读:
    EXTJS 动态改变Gird 列值
    EXTJS动态改变store的proxy的params
    获取Spring容器Bean
    EXTJS 6 必填项加星号*
    Maven打包附加配置文件
    MyEclipse 优化
    Android-SurfaceView生命周期
    Android-PopupWindow
    Android-Sqlite3的使用
    Android-adb的使用
  • 原文地址:https://www.cnblogs.com/lyj-gyq/p/9235033.html
Copyright © 2011-2022 走看看