12.动态sql

动态sql:根据不同的条件生成不同的sql语句,其本质是在sql层面,加入一些逻辑代码
1.if标签的使用:(重点:会执行所有的fi标签,并进行条件判断,满足的部分进行sql拼接)
    1.1接口中的定义:
           public interface UserMapper {
               List<User> getUserByListtIf(Map map);
           } 
     1.2xml文件中的写法
         <select id="getUserByListtIf" resultType="user">
            select * from public."user" where 1=1
            重点1:如果传入的id参数不为null,会在上述的sql上拼接上改条件:select * FROM public.user WHERE 1=1 and id=1;
            <if test="id !=null">
                and id=#{id}
            </if>
            <if test="name !=null">
                and name=#{name}
            </if>
        </select>
    1.3测试类的写法:
        @org.junit.Test
        public void testGetUserByListif(){
            SqlSession sqlSession = MybatisTools.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            重点1:创建map放入sql所需参数
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("id",1);
            map.put("name","刘丹");
            List<User> userByListtIf = mapper.getUserByListtIf(map);
            for (User user : userByListtIf) {
                System.out.println(user);
            }
            sqlSession.close();
        }
        
2.where标签的使用:动态拼接where(并且会智能的去掉第一个语句的and或者or)
    上述sql写成:
        select * from public."user" where 1=1再拼接下面的if标签内容,显得很不专业
        可以使用<where>标签
        用法如下:
        xml文件中的写法:
                <select id="getUserByListtIf" resultType="user">
                    select * from public."user"
                    重点1:使用where标签,下面跟条件,如果条件不满足,则不会拼接where语句
                    并且第一个子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
                    <where>
                        <if test="id !=null">
                           id=#{id}
                        </if>
                        重点2:第一个if标签的不满足,第二个语句前有and,在拼接sql时会将and去除!
                        <if test="name !=null">
                            and name=#{name}
                        </if>
                    </where>
                </select>
  
3.choose、when、otherwise标签 (重点:不会执行所有的when语句,遇到满足的条件,后面的when语句不会执行)
    3.1xml中的写法如下:
        <select id="getUserByListtIf" resultType="user" >
            select * from public."user"
            重点1:配合where标签使用
            <where>
               <choose>
                   重点2:如果1一条件满足,不会执行剩余的语句,直接跳出
                   <when test="id !=null">
                       and id=#{id}
                   </when>
                    <when test="name !=null">
                        and name=#{name}
                    </when>
                    重点3:otherwise可以不写,即不拼接该语句,会查询出所有的记录
                    <otherwise>
        
                    </otherwise>
               </choose>
            </where>
        </select>

 4.set标签,用于更新操作(并且会智能的去掉最后一个语句后面的逗号)
     更新语句:update 表名 set ... where ...
      xml文件中的写法:
          <update id="updatePwd">
                update public."user"
                重点1:使用set标签,相当于update语句中的set字段
                <set>
                    重点2:使用if标签进行字段判断,注意每个判断后面的逗号,因为多字段更新时,字段以逗号隔开
                    (update 表明 SET name='无法', pwd='五天' where 语句),逗号必须有
                    但是mybatis在进行拼接时,会自动将最后一个set字段的逗号去掉,所以每个set语句都要加逗号
                    <if test="name !=null">name=#{name},</if>
                    <if test="pwd !=null">pwd=#{pwd},</if>
                </set>
                重点3:条件语句的拼接
                <where>
                    <choose>
                        <when test="id!=null">id=#{id}</when>
                        <when test="name!=null">name=#{name}</when>
                    </choose>
                </where>
            </update>
sql片段
在mapper.xml中有些sql片段,在多个sql语句中都有用,每个都写的话显得代码冗余,可以用到代码片段,将公共部分抽取出来
注意点:
    1.最好基于单表定义sql片段
    2.sql片段中不要存在where标签,因为where标签会自动优化sql中的and和or
    3.尽量存放是简单的if标签
样例:
        重点1:使用sql标签,定义自定义id,将工共sql片段抽取出来
        <sql id="choose-when-id-name">
            <choose>
                <when test="id!=null">id=#{id}</when>
                <when test="name!=null">name=#{name}</when>
            </choose>
        </sql>
        <update id="updatePwd">
            update public."user"
            <set>
                <if test="name !=null">name=#{name},</if>
                <if test="pwd !=null">pwd=#{pwd},</if>
            </set>
            <where>
                重点2:使用include标签和refid标签来进行sql片段的引入
               <include refid="choose-when-id-name"></include>
            </where>
        </update>

 foreach的使用

示例1:如果想执行这么一个语句呢:select * FROM public."user" WHERE ( id=1 or id=2 or id=3 or id=4 );
    如何动态拼接呢:
    1.1xml中的写法
        <select id="seletUserForEarch" resultType="cn.com.wmd.pojo.User">
            select * from public."user"
            <where>
                重点1:使用foreach标签,
                        collection=map中list集合的key名称,
                        item=每个的id值,
                       open=前面的拼接,因为在where标签中,会自动去除第一个子句的and
                       close=结尾的拼接
                       separator=每个元素间的分割符
                <foreach collection="ids" item="id" open="and (" close=")" separator="or">
                    id=#{id}
                </foreach>
            </where>
        </select>
    1.2测试类代码:
        @org.junit.Test
        public void testSelectUserForEarch(){
            SqlSession sqlSession = MybatisTools.getSqlSession();
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            Map<String, Object> map=new HashMap<String, Object>();
            List<Integer> ids = new ArrayList<Integer>();
            ids.add(1);
            ids.add(2);
            ids.add(3);
            ids.add(4);
            map.put("ids",ids);
            List<User> userList = mapper.seletUserForEarch(map);
            for (User user : userList) {
                System.out.println(user);
            }
            sqlSession.close();
        }


示例2:如果想要执行sql:select * FROM public."user" WHERE id in(1,2,3,4)
    <select id="seletUserForEarch" resultType="cn.com.wmd.pojo.User">
        select * from public."user"
        <where>
            重点1:open=此处是id in (  分割符是,
            <foreach collection="ids" item="id" open="id in (" close=")" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

 

posted @ 2022-05-13 20:01  努力的达子  阅读(616)  评论(0编辑  收藏  举报