zoukankan      html  css  js  c++  java
  • MyBatis06_动态SQL语句

    本教程源码请访问:tutorial_demo
    之前在MyBatis持久层接口映射配置文件中,我们使用的SQL语句都是比较简单的,有时候业务逻辑复杂,SQL语句是动态变化的,前面学习的SQL语句就不能满足要求了。

    一、if标签

    我们根据实体类的不同取值,使用不同的SQL语句来进行查询。比如,username不为空时,根据username进行查询,address不为空时,根据address进行查询。这种多条件组合查询经常会碰到。

    1.1、 持久层接口IUserDao

    List<User> findByUser(User user);
    

    1.2 持久层映射配置文件IUserDao.xml

    <select id="findByUser" resultType="org.codeaction.domain.User">
        select * from user where 1=1
        <if test="username != null and username != ''">
            and username like #{username}
        </if>
        <if test="address != null and address != ''">
            and address like #{address}
        </if>
    </select>
    

    if标签中test属性中写的是对象的属性名,如果是封装的对象,这里要使用OGNL表达式的写法。注意这里的where 1=1。

    1.3 测试方法

    @Test
    public void testFindByUser() {
        IUserDao userDao = session.getMapper(IUserDao.class);
        User user = new User();
        user.setUsername("%王%");
        user.setAddress("北京");
    
        List<User> users = userDao.findByUser(user);
        users.forEach(System.out::println);
    }
    

    运行测试方法,控制台输出如下:

    User{id=41, username='王一', birthday=Tue Dec 27 17:47:08 CST 2011, sex='男', address='北京'}
    

    二、where标签

    上面的案例使用的where 1=1,我们可以使用where标签来进行简化。

    <select id="findByUser" resultType="org.codeaction.domain.User">
        select * from user
        <where>
            <if test="username != null and username != ''">
                and username like #{username}
            </if>
            <if test="address != null and address != ''">
                and address like #{address}
            </if>
        </where>
    </select>
    

    三、foreach标签

    查询地址的北京或拉萨的用户,SQL如下:

    select * from user where address in ('北京', '拉萨');
    select * from user where address = '北京' or  address = '拉萨';
    

    如果我们需要对一个范围进行查询,就需要将集合中的值作为参数添加进来。

    3.1、 持久层接口IUserDao

    List<User> findByAddress(List<String> list);
    

    3.2、持久层映射配置文件IUserDao.xml

    <select id="findByAddress" resultType="org.codeaction.domain.User" parameterType="list">
        select * from user
        <where>
            <if test="list != null and list.size() >= 0">
    			<!--
    				foreach标签用于遍历集合。
    				collection:代表要遍历的集合元素,注意编写时不要写#{};
    				open:代表语句的开始部分;
    				close:代表结束部分;
    				item:代表遍历集合的每个元素,生成的变量名;
    				sperator:代表分隔符。
    			-->
                <foreach collection="list" item="addr" open="address in (" close=")" separator=",">
                    #{addr}
                </foreach>
            </if>
        </where>
    </select>
    

    3.3、测试方法

    @Test
    public void testFindByAddress() {
        IUserDao userDao = session.getMapper(IUserDao.class);
        List<String> list = new ArrayList<String>();
        list.add("北京");
        list.add("拉萨");
    
        List<User> users = userDao.findByAddress(list);
        users.forEach(System.out::println);
    }
    

    运行测试方法,控制台输出如下:

    User{id=41, username='王一', birthday=Tue Dec 27 17:47:08 CST 2011, sex='男', address='北京'}
    User{id=46, username='老王', birthday=Sat Aug 07 17:37:26 CST 1999, sex='女', address='拉萨'}
    

    四、SQL片段

    我们在前面的学习中发现持久层映射配置文件有一些重复的SQL语句,我们可以通过定义SQL片段的方式把重复的SQL语句抽取出来,通过引用的方式在其他地方引用SQL片段。

    <?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="org.codeaction.dao.IUserDao">
        <!-- 定义SQL片段 -->
        <sql id="defaultSQL">
            select * from user
        </sql>
        <!-- 配置查询所有 -->
        <select id="findAll" resultType="org.codeaction.domain.User">
            <!-- 引用SQL片段 -->
            <include refid="defaultSQL"></include>
        </select>
        <select id="findByUser" resultType="org.codeaction.domain.User">
            <!-- 引用SQL片段 -->
            <include refid="defaultSQL"></include>
            <where>
                <if test="username != null and username != ''">
                    and username like #{username}
                </if>
                <if test="address != null and address != ''">
                    and address like #{address}
                </if>
            </where>
        </select>
    
        <select id="findByAddress" resultType="org.codeaction.domain.User" parameterType="list">
            <!-- 引用SQL片段 -->
            <include refid="defaultSQL"></include>
            <where>
                <if test="list != null and list.size() >= 0">
                    <foreach collection="list" item="addr" open="address in (" close=")" separator=",">
                        #{addr}
                    </foreach>
                </if>
            </where>
        </select>
    </mapper>
    
  • 相关阅读:
    ref与out的区别(C#)
    用MS SQL Server 2008修改数据库表时提示“不允许保存更改”的解决方法
    测试的职责
    性能测试新手误区(三):用户数与压力
    JAVA + LR实现apache流媒体的性能测试(LR部分)
    性能测试新手误区(二):为什么我模拟的百万测试数据是无效的
    JAVA + LR实现apache流媒体的性能测试(JAVA部分)
    性能测试新手误区(六):性能监控
    性能测试新手误区(五):这是性能问题么
    性能测试新手误区(四):一切来自录制
  • 原文地址:https://www.cnblogs.com/codeaction/p/12915670.html
Copyright © 2011-2022 走看看