# MyBatis 动态 SQL

### 什么是 动态 SQL ？

动态 SQL 是指根据参数数据动态组织 SQL 语句的技术。比如一句 SELECT 语句里面可能会出现多个限定条件，比如 可能会出现多个 WHERE 条件判断，也可能不会出现。 举个实际的例子就是逛淘宝，搜索"手机"，下面就会有一个筛选框，勾选筛选框里面的条件(比如价格2000以下，内存4G以上)，界面就会重新刷新，筛选出符合条件的手机。&#x20;

### 在 MyBatis 中使用 动态 SQL

比如有这么一个需求，可能要根据商品ID或者商品价格筛选出特点的商品。MyBatis\src\main\resources\mappers\goods.xml 下的  \<mapper namespace="goods">这么写:

```xml
    <!-- 动态SQL -->
    <select id="dynamicSQL" parameterType="java.util.Map" resultType="indi.chester.mybatis.entity.Goods">
        SELECT  * FROM t_goods
        <where>
            <if test="categoryId!=null">
                AND category_id=#{categoryId}
            </if>
            <if test="currentPrice!=null">
                AND current_price &lt; #{currentPrice}
            </if>
        </where>
    </selectx
```

在 MyBatis\src\test\java\MyBatisTest.java 添加下面这个方法：

```java
    @Test
    public void testDynamicSQL() throws Exception{
        SqlSession sqlSession=null;
        try {
            sqlSession=MyBatisUtils.openSession();
            Map parm = new HashMap();
            parm.put("categoryId",44);
            parm.put("currentPrice",500);

            List<Goods> goodsList=sqlSession.selectList("goods.dynamicSQL",parm);
            for (Goods g:goodsList) {
                System.out.println(g.getTitle()+" : "+g.getCategoryId()+ " : "+
                        g.getCurrentPrice());
            }

        }catch (Exception e){
            throw e;
        }finally {
            MyBatisUtils.closeSession(sqlSession);
        }
    }
```

运行结果:

```xml
09:28:30:401 [main]  DEBUG goods.dynamicSQL -==>  Preparing: SELECT * FROM t_goods WHERE category_id=? AND current_price < ?  
09:28:30:438 [main]  DEBUG goods.dynamicSQL -==> Parameters: 44(Integer), 500(Integer) 
09:28:30:505 [main]  DEBUG goods.dynamicSQL -<==      Total: 29 
爱恩幼 孕妇护肤品润养颜睡眠面膜 100g : 44 : 49.0
【欧洲直邮】德国Hipp喜宝有机奶粉pre段 600g*2 : 44 : 208.0
小米 Yeelight床头灯 白色 : 44 : 249.0
雅滋美特 孕期护肤品玉米洗护三件套装（洗发+护发+沐浴露） : 44 : 49.0
优理氏 多效清洁补水套装（洗面奶+理肤水+保湿喷雾+原液） : 44 : 69.0
【德国】Aptamil爱他美奶粉2段 800g*2罐（6-10个月） : 44 : 399.0
袋鼠妈妈 轻透双色玫瑰腮红 持久自然彩妆 裸妆修容 孕妇化妆品 蜜桃红/蔷薇裸 8.5g : 44 : 68.0
兰多 铆钉时尚双肩背包小号妈咪包 紫色 : 44 : 79.0
【美囤自营】心开始 智能胎心跳聆听器 : 44 : 468.0
惠氏 启赋（Wyeth illuma）有机1段 900g （0-6月）婴儿配方奶粉（罐装） : 44 : 488.0
【直降】【日本】花王纸尿裤M42片*2包 : 44 : 152.0
（新）多美滋致粹新护婴儿1段配方乳粉 900g*2听 : 44 : 428.8
嘉宝蓝莓泡芙42克 : 44 : 38.0
CHBABY实木配摇篮多功能婴儿童床108 : 44 : 399.0
吕 【美囤包税】Ryoe吕洗发水护发素套装防脱发洗发水系列 黑吕两件套两洗400*2瓶装 : 44 : 149.0
贝乐乐 贝乐乐 亚麻草凉席+凉枕 100*56cm : 44 : 29.0
I.believe 爱贝丽 多功能可折叠便携式儿童餐椅婴儿餐桌椅宝宝餐桌椅 优雅玫 : 44 : 159.0
美国然雅 宝宝爬行垫儿童游戏垫婴幼儿游戏毯折叠户外野餐垫防潮隔热 F106 红色条纹 : 44 : 69.0
五羊 孕产妇经济实用护理待产包 12件套【经济型】 : 44 : 89.0
子初 孕妇护肤品海洋臻萃保湿补水4件套（洁面乳+精华水+舒护乳+水光水面膜25ml*27） : 44 : 388.0
笑巴喜 纯棉婴儿方巾洗脸方巾超柔6条装FJ6 : 44 : 59.0
【美囤包税】【日本】大王纸尿裤S106*1包（新老包装随机发） : 44 : 125.0
贝恩施 新生儿宝宝手抓棒抓握益智玩具BB棒 : 44 : 15.0
五羊bibi 智能棉柔婴儿纸尿裤 XL码84片*2箱 : 44 : 249.0
子初 孕妇清新护齿牙膏50g : 44 : 19.0
乐孕 产妇卫生柔湿巾5包装 : 44 : 29.0
飞利浦新安怡 经典宽口PES手动吸奶器花瓣按摩垫吸乳器SCF300/88 : 44 : 239.4
MeadJohnson 美赞臣 安儿健A+奶粉 4段 400克盒装 儿童配方奶粉 : 44 : 61.0
飞利浦新安怡 12安士儿童吸管杯魔术杯宝宝学饮杯水杯儿童水杯(颜色随机) SCF762/00 : 44 : 78.0
```
