MyBatis第二次练习——动态sql

本文介绍了MyBatis中几个关键的动态SQL标签的使用,包括if标签实现有条件查询,where标签处理多条件查询避免语法错误,set标签在更新语句中的应用,choose(when/otherwise)实现类似if...else的逻辑,以及foreach标签用于处理IN操作。这些标签提高了SQL语句的灵活性和可维护性。

一、MyBatis if

(一)创建数据表product_

 (二)准备数据

得到数据表product_

 (三)对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="com.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_         
        </select>
        <select id="listProductByName" resultType="Product">
            select * from product_  where name like concat('%',#{name},'%')        
        </select>
         
    </mapper>

TestMybatis.java

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

运行结果为:

 (四)if标签

如果Product的字段比较多的话,为了应付各个字段的查询,那么就需要写多条sql语句,这样就变得难以维护。

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

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="com.how2java.pojo">
        <select id="listProduct" resultType="Product">
            select * from product_
            <if test="name!=null">
                where name like concat('%',#{name},'%')
            </if>        
        </select>
         
    </mapper>

TestMybatis.java

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

运行结果如下:

二、MyBatis where

进行多条件判断时,以Product为例,通常会写成这样:

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

但是在这种情况下,当没有name参数,却有price参数的时候,执行的sql语句就会是:

select * from product_ and price > 10,从而报错。

(一)where标签

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

关键代码:

Map<String,Object> params = new HashMap<>(); 
        //params.put("name","a");
        params.put("price","10");

这个参数map,无论是否提供值否都可以正常执行,就可以解决之前的问题。

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="com.how2java.pojo">
    <select id="listProduct" 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>
         
    </mapper>

TestMybatis.java

package com.how2java;
  
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Product;
  
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
  
        System.out.println("多条件查询");
        Map<String,Object> params = new HashMap<>();
//        params.put("name","y");
        params.put("price","10");
        List<Product> ps2 = session.selectList("listProduct",params);
        for (Product p : ps2) {
            System.out.println(p);
        }      
         
        session.commit();
        session.close();
  
    }
}

(二)set标签

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

关键代码:

 <set>
     	<if test="name != null">name=#{name},</if>
     	<if test="price != null">price=#{price}</if>
    </set>

其效果与where标签类似,有数据的时候才进行设置。

(三)trim标签

trim 用来定制想要的功能,例如where标签可用下述代码替换:

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

set标签可用下述代码替换:

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

三、MyBatis choose

(一)if else

Mybatis里面没有else标签,但是可以使用when otherwise标签来达到这样的效果。其作用是: 提供了任何条件,就进行条件查询,否则就使用id>1这个条件。

关键代码:

<select id="listProduct" 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>

四、MyBatis foreach

foreach标签通常用于in 这样的语法里。

关键代码:

SELECT * FROM product_ 
 	WHERE ID in
			<foreach item="item" index="index" collection="list"
    			open="(" separator="," close=")">
      		             #{item}
			</foreach>

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="com.how2java.pojo">
    <select id="listProduct" resultType="Product">
          SELECT * FROM product_
            WHERE ID in
                <foreach item="item" index="index" collection="list"
                    open="(" separator="," close=")">
                    #{item}
                </foreach>
    </select>
    </mapper>

TestMybatis.java

package com.how2java;
  
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
 
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 
import com.how2java.pojo.Product;
  
public class TestMybatis {
  
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
 
        List<Integer> ids = new ArrayList();
        ids.add(2);
        ids.add(4);
        ids.add(6);
         
      List<Product> ps = session.selectList("listProduct",ids);
      for (Product p : ps) {
          System.out.println(p);
      }
 
        session.commit();
        session.close();
  
    }
}

即选择出id要么等于2要么等于4要么等于6的Product。

实现效果如下:

五、MyBatis bind

bind标签就像是再做一次字符串拼接,方便后续使用。

例如在练习中,在模糊查询的基础上,把模糊查询改为bind标签。

原代码:

<select id="listProduct" resultType="Product">
select * from   product_  where name like concat('%',#{0},'%') 
</select>

改成: 

<select id="listProduct" resultType="Product">
            <bind name="likename" value="'%' + name + '%'" />
            select * from   product_  where name like #{likename}
        </select>

总结:在这一次的练习中,学习了很多用法不同的标签,没有什么很难的部分,做起来也是比较顺手的,但是这次学习了很多种类的标签。还是需要多加练习加固学习的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值