本次全部学习内容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:中间分隔输出
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10-09 22:44