美文网首页
04动态sql

04动态sql

作者: RobertLiu123 | 来源:发表于2019-07-18 16:27 被阅读0次

    学习以下动态sql语句

    if(多条件动态拼接)
    2)where(解决where and/or情况)
    3)set(解决update语句多逗号情况 与update一起用)
    4)trim(**可以前后追加,同时还能用指定字符分隔语句,还可以去除语句前后的指定字符)
    5)foreach(拼装in语句)
    6)sql片段(提取出公用的sql)
    7)choose(选择很多情况下的一种,和 Java 中的 switch语句相似

    if(多条件动态拼接)
    1)页面让用户输入查询条件
    用户名 身份证号 邮箱
    后台动态判断他输入了什么
    如果输入了用户名我就把用户名做为选择条件
    如果输入了身份证号我就把身份证号做为选择条件
    如果输入了邮箱我就把邮箱做为选择条件
    select * from t_user
    where (如果输入用户名 username=#{username})
    (如果输入身份证号 and/or idcard=#{useridcard})
    (如果输入邮箱 and/or email=#{useremail})
    样例代码
    接口

    public interface UserSqlMapper {
      public User getUser(User user);
    }
    
    xml
    <?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="com.neuedu.day02.mapper.UserSqlMapper">
    <select id="getUser" parameterType="User" resultType="user">
    select * from t_user where 
    <if test="user_name!=null and user_name!=''">
     user_name=#{user_name}
    </if>
    <if test="user_email!=null and user_email!=''">
     and user_email=#{user_email}
    </if>
    <if test="user_idCard!=null and user_idCard!=''">
     and user_idCard=#{user_idCard}
    </if>
    </select>
    </mapper>
    

    测试类以下方法调用usersqlmapper下的

       @Test
       public void testFind() throws IOException{
           IUserDao userDao=new UserDaoImpl(factory);
           User user=new User();
           user.setUser_name("chenhao");
           user.setUser_email("chenhao.newedu.com");
           user.setUser_idCard("210101200006061234");
           User dbuser=userDao.getUser(user);
           System.out.println(dbuser.getUser_name());
       }
    

    如果上述查询不输入用户名,会出现where直接加and/or的情况,导致查询不到结果
    where(解决if多条件拼装时,如果第一个条件不存在,where+and/or的问题。)
    把上面的statement稍微改写一个。改写成用where子句把if包起来。即下面这样:

    <select id="getUser" parameterType="User" resultType="user">
    select * from t_user 
    <where> 
    <if test="user_name!=null and user_name!=''">
     user_name=#{user_name}
    </if>
    <if test="user_email!=null and user_email!=''">
     and user_email=#{user_email}
    </if>
    <if test="user_idCard!=null and user_idCard!=''">
     and user_idCard=#{user_idCard}
    </if>
    </where>
    </select>
    

    set(解决update语句多逗号情况 与update一起用)
    关键代码
    UserSqlMapper.xml

    <update id="updateUser" parameterType="user">
    update t_user set
    <if test="user_name!=null and user_name!=''">
    user_name=#{user_name},
    </if>
    <if test="user_email!=null and user_email!=''">
    user_email=#{user_email},
    </if>
    <if test="user_idCard!=null and user_idCard!=''">
    user_idcard=#{user_idCard},
    </if>
    <if test="user_pwd!=null and user_pwd!=''">
    user_pwd=#{user_pwd}
    </if>
    where  user_id=#{user_id}
    </update>
    

    测试类:

    @Test
       public void testUpdate() throws IOException{
           IUserDao userDao=new UserDaoImpl(factory);
           User user=new User();
           //主键必须带
           user.setUser_id(8);
           //user.setUser_name("chenhao");
           user.setUser_pwd("654321");
           user.setUser_email("chenhao@newedu.com");
           user.setUser_idCard("210101200006061233");
           int count=userDao.updateUserSql(user);
           System.out.println(count);
       }
    

    上面的语句如果最后一个条件没有输入,会有多余的逗号,导致语句出错,把set写成动态的,也就是用<set> </set>把IF语句把起来,能够解决上述问题。
    上面的语句改造成下面的形式

    <update id="updateUser" parameterType="user">
    update t_user 
    <set>
    <if test="user_name!=null and user_name!=''">
    user_name=#{user_name},
    </if>
    <if test="user_email!=null and user_email!=''">
    user_email=#{user_email},
    </if>
    <if test="user_idCard!=null and user_idCard!=''">
    user_idcard=#{user_idCard},
    </if>
    <if test="user_pwd!=null and user_pwd!=''">
    user_pwd=#{user_pwd}
    </if>
    </set>
    where  user_id=#{user_id}
    </update>
    

    第二节
    trim(可以前后追加,同时还能用指定字符分隔语句,还可以去除语句前后的指定字符)
    格式:

    <trim prefix="" suffix="" prefixOverrides="" suffixOverrides=""></trim>
    

    其中:prefix:前面加上什么
    suffix:后面加上什么
    prefixOverrides:前面去掉什么
    suffixOverrides:后面去掉什么
    他可以替代前面的set where
    举例如果想动态拼装inset语句:

    insert into t_user (key1,key2)
    values (value1,value2)
    

    我们可以通过更改上下两个括号的部分来实现
    来试一下
    *注意如果字段是int类型,user_power=0时,user_power!=''为true
    所以,
    关键代码:
    动态的insert的xml为

    <insert id="insertUserSql" parameterType="User">
    insert into t_user 
    <trim prefix="(" suffix=")" suffixOverrides=",">
    user_id,
    <if test="user_name!=null and user_name!=''">
    user_name,
    </if>
    <if test="user_pwd!=null and user_pwd!=''">
    user_pwd,
    </if>
    <if test="user_email!=null and user_email!=''">
    user_email,
    </if>
    <if test="user_idcard!=null and user_idcard!=''">
    user_idcard,
    </if>
    <if test="user_power!=null">
    user_power,
    </if>
    </trim>
     values 
    <trim prefix="(" suffix=")" suffixOverrides=",">
    null,
    <if test="user_name!=null and user_name!=''">
    #{user_name},
    </if>
    <if test="user_pwd!=null and user_pwd!=''">
    #{user_pwd},
    </if>
    <if test="user_email!=null and user_email!=''">
    #{user_email},
    </if>
    <if test="user_idcard!=null and user_idcard!=''">
    #{user_idcard},
    </if>
    <if test="user_power!=null">
    #{user_power},
    </if>
    </trim>
    

    对应的测试类为:

     @Test
       public void testInsert() {
           IUserDao userDao=new UserDaoImpl(factory);
           User user=new User();
           user.setUser_name("gujunn");
           user.setUser_pwd("123456");
           user.setUser_power(0);
           //user.setUser_email("chenhao.newedu.com");
           //user.setUser_idCard("210101200006061234");
           int count=userDao.insertUserSql(user);
           System.out.println(count);
       }
    

    第三节
    foreach(拼装in语句)
    注意:你可以传递一个 List 实例或者数组作为参数对象传给 MyBatis。当你这么做的时
    候,MyBatis 会自动将它包装在一个 Map 中,用名称在作为键。List 实例将会以“list”
    作为键,而数组实例将会以“array”作为键。
    语法:

    <foreach item="item" index="index" collection="list"
    open="(" separator="," close=")">
    #{item}
    </foreach>
    

    代码示例:用户批量删除功能
    UserSqlMapper.xml

    <delete id="delUserList">
    <!-- 分析批量删除语句delete from t_user where user_id in (1,2,3,4,5) 
    上述语句需要动态拼(1,2,3,4,5)
    foreach可以实现循环拼接
    如果传递参数为list,collection="list"(固定写法)
    前面加(  open="("
    后面加)  close=")"
    中间加,  separator=","
    -->
    delete from t_user where user_id in 
    <foreach collection="list" item="item" open="(" close=")" separator=",">
    #{item}
    </foreach>
    

    接口里对应方法UserSqlMapper.java

    public int delUserList(List ids);
    

    测试用例:UserSqlServiceTest.java

    @Test
       public void testDeleteBatch() throws IOException{
           SqlSession session=factory.openSession();
           //执行查询
           UserSqlMapper mapper=session.getMapper(UserSqlMapper.class);
           List<Integer> ids=new ArrayList();
           ids.add(10);
           ids.add(8);
           int count=mapper.delUserList(ids);
           System.out.println(count);
           //关闭连接
           session.close();
       }
    

    学生练习:
    批量删除传入参数为Array
    关键代码UserSqlMapper.xml

    <delete id="delUserArray">
    <!-- 分析批量删除语句delete from t_user where user_id in (1,2,3,4,5) 
    上述语句需要动态拼(1,2,3,4,5)
    foreach可以实现循环拼接
    如果传递参数为数组,collection="array"(固定写法)
    前面加(  open="("
    后面加)  close=")"
    中间加,  separator=","
    -->
    delete from t_user where user_id in 
    <foreach collection="array" item="item" open="(" close=")" separator=",">
    #{item}
    </foreach>
    </delete>
    

    问题:前面两个方法的sql语句中有重复的部分 delete from t_user where user_id in 为了减少代码冗余,我们引入sql片段
    sql片段(提取出公用的sql)

    <sql id="delusersql">
    delete from t_user where user_id in 
    </sql>
    

    再将上面的statement改造成如下形式

    <delete id="delUserArray">
    <!--refid与sql的id对应-->
    <include refid="delusersql"/>
    <foreach collection="array" item="item" open="(" close=")" separator=",">
    #{item}
    </foreach>
    </delete>
    

    choose(选择很多情况下的一种,和 Java 中的 switch语句相似) (手册41页)##
    作业:
    练习上面的代码,完成用户动态添加、修改、批量删除、动态拼接查询语句

    相关文章

      网友评论

          本文标题:04动态sql

          本文链接:https://www.haomeiwen.com/subject/mknllctx.html