• MyBatis框架(6)动态sql


    本次全部学习内容MyBatisLearning

     
    什么是动态sql:
        mybatis的核心,对sql进行灵活的操作,通过对表达式的判断,对sql灵活的拼接

     在之前小案例的基础上我们先进行简单的实现一下:

     if:

     在UserMapper.xml文件中找到:

    <!-- 动态sql -->
         <!-- 综合查询 -->
         <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" >
               select * from user
               <where>
                    <if test="userCustomer!=null">
                          <if test="userCustomer.sex!=null and userCustomer.sex!='' ">
                               and user.sex=#{userCustomer.sex}
                          </if>
                        <if test="userCustomer.username!=null and userCustomer.username!=''">
                               and user.username like '%${userCustomer.username}%'
                          </if>
                    </if>
               </where>
         </select>

     注意:where标签可以自动去掉条件中的第一个  and

    测试类:
    //此时值传入username这一个值
         //动态sql
         //高级查询
         @Test
         public void testfindBySelect() throws Exception{
               SqlSession sqlSession = getSqlSessionFactory().openSession();
               
               UserMapper mapper = sqlSession.getMapper(UserMapper.class);
               
               UserView userView = new UserView();
               
               UserCustomer userCustomer = new UserCustomer();
               //userCustomer.setSex(1);
               userCustomer.setUsername("小明");
               
               userView.setUserCustomer(userCustomer);
               
               List<User> user = mapper.findBySelect(userView);
               for(User u : user){
                    System.out.println(u);
               }
               sqlSession.close();
         }

     结果:

    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@545997b1]
    DEBUG [main] - ==>  Preparing: select * from user WHERE user.username like '%小明%'
    DEBUG [main] - ==> Parameters:
    DEBUG [main] - <==      Total: 3
    User [id=16, username=张小明, birthday=null, sex=1, address=河南郑州]
    User [id=22, username=陈小明, birthday=null, sex=1, address=河南郑州]
    User [id=25, username=陈小明, birthday=null, sex=1, address=河南郑州]
    在if中判断此时,之传入了一个username进行查询。

    SQL片段:

    把实现动态sql判断的代码块抽取出来,组成一个sql片段,在需要的时候可以直接引用,重用性高
     
    定义一个sql片段,基于上面的代码进行测试和实践:
    在UserMapper.xml文件中:
    定义sql片段:
    <!-- sql片段 -->
         <!-- id唯一,是sql片段的唯一标识 -->
         <!-- 基于单表定义sql片段,这样的话sql片段的可重用性才高,在sql片段中不要包括where -->
         <sql id="selectBySql">
                    <if test="userCustomer!=null">
                          <if test="userCustomer.sex!=null and userCustomer.sex!='' ">
                               and user.sex=#{userCustomer.sex}
                          </if>
                          <if test="userCustomer.username!=null and userCustomer.username!=''">
                               and user.username like '%${userCustomer.username}%'
                          </if>
                    </if>
         </sql>

    引用sql片段:

    <!-- 动态sql -->
         <!-- 综合查询 -->
         <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" >
               select * from user
               
               <where>
                    <!-- 引用sql片段 -->
                    <include refid="selectBySql"></include>
               </where>
         </select>

     测试代码同上次测试代码!

     foreach标签:

     假设我们同时查询多个id

    select from user where id = 1 or id = 10 or id = 12
    在UserMapper.xml文件中,对之前的代码进行加工修改:
    此时,在测试的时候,我只是测试foreach里面的内容,所以,对代码进行了修改
         <!-- sql片段 -->
         <!-- id唯一,是sql片段的唯一标识 -->
         <!-- 基于单表定义sql片段,这样的话sql片段的可重用性才高,在sql片段中不要包括where -->
         <sql id="selectBySql">
                    <if test="userCustomer!=null">
                          <if test="userCustomer.sex!=null and userCustomer.sex!='' ">
                               and user.sex=#{userCustomer.sex}
                          </if>
                          <if test="userCustomer.username!=null and userCustomer.username!=''">
                               and user.username like '%${userCustomer.username}%'
                          </if>
                    </if>
    
                    <!-- foreach -->
                    <!-- 测试 -->
                    <!-- select from user where id = 1 or id = 10 or id = 12 -->
                    
                    <!-- collection:指定输入对象的集合 -->
                    <!-- item:每个遍历生成成的对象 -->
                    <!-- open:开始遍历时 拼接的串 -->
                    <!-- close:结束遍历时 拼接的串 -->
                    <!-- separator:遍历时两个对象中需要拼接的串 -->
                    <foreach collection="ids" close=")"  item="userId" open="1=1 and (" separator="or">
                         id=#{userId}
                    </foreach>
         </sql>
         
         <!-- 动态sql -->
         <!-- 综合查询 -->
         <select id="findBySelect" parameterType="com.MrChengs.po.UserView" resultType="com.MrChengs.po.UserCustomer" >
               select * from user
               
               <where>
                    <!-- 引用sql片段 -->
                    <include refid="selectBySql"></include>
               </where>
         
         </select>

     测试代码:

       //foreach
         //动态sql
         //高级查询
         @Test
         public void testfindBySelect() throws Exception{
               SqlSession sqlSession = getSqlSessionFactory().openSession();
               
               UserMapper mapper = sqlSession.getMapper(UserMapper.class);
               
               UserView userView = new UserView();
               //foreach
               List<Integer> ids = new ArrayList<>();
               ids.add(1);
               ids.add(2);
               ids.add(30);
               
               userView.setIds(ids);
               
               List<User> users = mapper.findBySelect(userView);
               for(User user : users){
                    System.out.println(user);
               }
               sqlSession.close();
         }

     结果:

    DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@545997b1]
    DEBUG [main] - ==>  Preparing: select * from user WHERE 1=1 and ( id=? or id=? or id=? )
    DEBUG [main] - ==> Parameters: 1(Integer), 2(Integer), 30(Integer)
    DEBUG [main] - <==      Total: 2
    User [id=1, username=王五, birthday=null, sex=2, address=null]
    User [id=30, username=Ma, birthday=null, sex=1, address=安徽]
    对于
    SELECT * FROM USER WHERE id IN(1,2,30)来说
    只需要修改下面的测试代码,其余的测试代码均不变
    <foreach collection="ids" close=")"  item="userId" open="1=1 and id in(" separator=",">
                   id=#{userId}
    </foreach>
    sql只接收一个数组参数,这时sql解析参数的名称mybatis固定为array,如果数组是通过一个pojo传递到sql则参数的名称为pojo中的属性名。
    index:为数组的下标。
    item:为数组每个元素的名称,名称随意定义
    open:循环开始
    close:循环结束
    separator:中间分隔输出
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    全面分析C#方法中的ref和out
    SQL注入漏洞全接触入门篇
    如何使用四个语句来提高 SQL Server 的伸缩性
    5种提高SQL性能的方法
    SQL注入漏洞全接触高级篇
    网络游戏程序员须知 收包与发包
    SQL注入攻击的原理及其防范措施
    SQL注入漏洞全接触进阶篇
    C#委托的故事
    转眼又快一年了,最近没赚钱,在学习FLASH as3编程
  • 原文地址:https://www.cnblogs.com/Mrchengs/p/9763632.html
Copyright © 2020-2023  润新知