zoukankan      html  css  js  c++  java
  • java-mybaits-00402-Mapper-动态sql-if、where、foreach、sql片段

    1、动态sql(重点)

    通过mybatis提供的各种标签方法实现动态拼接sql。
    什么是动态sql
    mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。
      需求
     用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
      对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。

    1.1、If

      <!-- 传递pojo综合查询用户信息 -->
        <select id="findUserList" parameterType="user" resultType="user">
           select * from user
           where 1=1
           <if test="id!=null and id!=''">
           and id=#{id}
           </if>
           <if test="username!=null and username!=''">
           and username like '%${username}%'
           </if>
        </select>
    注意要做不等于空字符串校验。
     注意直接是属性,不用类名.属性

    1.2、Where

    上边的sql也可以改为:
       <select id="findUserList" parameterType="user" resultType="user">
           select * from user
           <where>
           <if test="id!=null and id!=''">
           and id=#{id}
           </if>
           <if test="username!=null and username!=''">
           and username like '%${username}%'
           </if>
           </where>
        </select>
    <where />可以自动处理第一个and。

    1.3、foreach 

    向sql传递数组或List,mybatis使用foreach解析,

    collection:表示传入过来的参数的数据类型。该参数为必选。要做 foreach 的对象,作为入参时,List 对象默认用 list 代替作为键,数组对象有 array 代替作为键,Map 对象没有默认的键。当然在作为入参时可以使用 @Param(“keyName”) 来设置键,设置 keyName 后,list,array 将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
    如果 User 有属性 List ids。入参是 User 对象,那么这个 collection = “ids” 如果 User 有属性 Ids ids;其中 Ids 是个对象,Ids 有个属性 List id;入参是 User 对象,那么 collection = “ids.id”
    如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list
    如果传入的是单参数且参数类型是一个 array 数组的时候,collection 的属性值为 array
    如果传入的参数是多个的时候,我们就需要把它们封装成一个 Map 了,当然单参数也可以封装成 map。
    item: 循环体中的具体对象。支持属性的点路径访问,如 item.age,item.info.details。具体说明:在 list 和数组中是其中的对象,在 map 中是 value,该参数为必选。(它是每一个元素进行迭代时的别名)
    index:在 list 和数组中,index 是元素的序号;在 map 中,index 是元素的 key。
    open:表示该语句以什么开始
    close:表示该语句以什么结束
    separator:表示在每次进行迭代之间以什么符号作为分隔符

    如下:

     1.3.1、通过pojo传递list 

    • 需求
    传入多个id查询用户信息,用下边两个sql实现:
     
    SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
    SELECT * FROM USERS WHERE username LIKE '%张%'  id IN (10,89,16) 
    • 在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法
      

      mapper.xml

    <if test="ids!=null and ids.size>0">
      <foreach collection="ids" open=" and id in(" close=")" item="id" separator="," >
        #{id}
      </foreach>
    </if>

      测试代码:

    List<Integer> ids = new ArrayList<Integer>();
    ids.add(1);//查询id为1的用户
    ids.add(10); //查询id为10的用户
    queryVo.setIds(ids);
    List<User> list = userMapper.findUserList(queryVo);

     1.3.2、传递单个List

     传递List类型在编写mapper.xml没有区别,唯一不同的是只有一个List参数时它的参数名为list。
     如下:mapper.xml
    <select id="selectUserByList" parameterType="java.util.List"
            resultType="com.lhx.mybatis.po.User">
            select * from user
            <where>
                <!-- 传递List,List中是pojo -->
                <if test="list!=null">
                    <foreach collection="list" item="item" open="and id in("
                        separator="," close=")">
                        #{item.id}
                    </foreach>
                </if>
            </where>
        </select>

    mapper接口

    public List<User> selectUserByList(List<User> userlist) throws Exception;

    测试类

        public void testselectUserByList() throws Exception {
            // 获取session
            SqlSession session = sqlSessionFactory.openSession();
            // 获限mapper接口实例
            UserMapper userMapper = session.getMapper(UserMapper.class);
            // 构造查询条件List
            List<User> userlist = new ArrayList<User>();
            User user = new User();
            user.setId(1);
            userlist.add(user);
            user = new User();
            user.setId(2);
            userlist.add(user);
            // 传递userlist列表查询用户列表
            List<User> list = userMapper.selectUserByList(userlist);
            System.out.println(list.size()+"");
            // 关闭session
            session.close();
        }

    1.3.3、传递单个数组(数组中是pojo):

    mapper.xml
        <!-- 传递数组综合查询用户信息 -->
        <select id="selectUserByArrayPojo" parameterType="Object[]"
            resultType="com.lhx.mybatis.po.User">
            select * from user
            <where>
                <!-- 传递数组 -->
                <if test="array!=null">
                    <foreach collection="array" index="index" item="item" open="and id in("
                        separator="," close=")">
                        #{item.id}
                    </foreach>
                </if>
            </where>
        </select>

    mapper接口

        public List<User> selectUserByArrayPojo(Object[] userlist) throws Exception;

    测试代码

        public void testselectUserByArray() throws Exception {
            // 获取session
            SqlSession session = sqlSessionFactory.openSession();
            // 获限mapper接口实例
            UserMapper userMapper = session.getMapper(UserMapper.class);
            // 构造查询条件List
            Object[] userlist = new Object[2];
            User user = new User();
            user.setId(1);
            userlist[0] = user;
            user = new User();
            user.setId(2);
            userlist[1] = user;
            // 传递user对象查询用户列表
            List<User> list = userMapper.selectUserByArrayPojo(userlist);
            // 关闭session
            session.close();
        }

    1.3.4、传递单个数组(数组中是字符串类型):

    mapper.xml
        <!-- 传递数组综合查询用户信息 -->
        <select id="selectUserByArray" parameterType="Object[]"
            resultType="com.lhx.mybatis.po.User">
            select * from user
            <where>
                <!-- 传递数组 -->
                <if test="array!=null">
                    <foreach collection="array" index="index" item="item" open="and id in("
                        separator="," close=")">
                        #{item}
                    </foreach>
                </if>
            </where>
        </select>

    mapper接口

    public List<User> selectUserByArray(Object[] userlist) throws Exception;

    测试代码

        public void testselectUserByArray() throws Exception {
            // 获取session
            SqlSession session = sqlSessionFactory.openSession();
            // 获限mapper接口实例
            UserMapper userMapper = session.getMapper(UserMapper.class);
            // 构造查询条件List
            Object[] userlist = new Object[2];
            userlist[0] = "1";
            userlist[1] = "2";
            // 传递user对象查询用户列表
            List<User> list = userMapper.selectUserByArray(userlist);
            // 关闭session
            session.close();
        }

    1.4、Sql片段

    Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的,方便程序员进行开发如下:
     
    <!-- 传递pojo综合查询用户信息 -->
        <select id="findUserList" parameterType="user" resultType="user">
           select * from user
           <where>
           <if test="id!=null and id!=''">
           and id=#{id}
           </if>
           <if test="username!=null and username!=''">
           and username like '%${username}%'
           </if>
           </where>
        </select>
    将where条件抽取出来
    <sql id="query_user_where">
        <if test="id!=null and id!=''">
           and id=#{id}
        </if>
        <if test="username!=null and username!=''">
           and username like '%${username}%'
        </if>
    </sql>
    使用include引用
    <select id="findUserList" parameterType="user" resultType="user">
           select * from user
           <where>
           <include refid="query_user_where"/>
           </where>
        </select>
    注意:
    1.如果引用其它mapper.xml的sql片段,则在引用时需要加上namespace,如下:
    <include refid="namespace.sql片段”/>
    2.经验,是基于单表定有的sql片段,这样sql可重用性高
    3.一般不添加where,方便引用多个片段 
     
     
     
     
     
  • 相关阅读:
    网页制作--标签,表格,表单,框架
    sql数据库框架
    数据库的触发器
    数据库的复制与附加
    sql数据库随笔
    sql常用函数
    sql数据类型、约束
    sql数据库查询
    数据库增删改查
    数据库基本概念
  • 原文地址:https://www.cnblogs.com/bjlhx/p/6838294.html
Copyright © 2011-2022 走看看