zoukankan      html  css  js  c++  java
  • MyBatis的动态SQL语句这么厉害的!

    MyBatis动态SQL语句,非常实用

    MyBatis 的强大特性之一便是它的动态 SQL。简直厉害啦~

    if

    if 语句比较常用,查询、删除、修改的时候都是可以用到!

    其中的 where 1 = 1 仅仅只是为了满足多条件查询页面中不确定的各种因素而采用的一种构造一条正确能运行的动态SQL语句的一种方法。

    where 1 = 0 这个条件始终为false,结果不会返回任何数据,只有表结构,可用于快速建表

    <!-- 
    	测试 if 语句
     	id 与之查询方法相对应
    	resultType 表示User对象
    	test 属性中可以写判断User对象属性的语句
    -->
    
    <select id="queryUser1" resultType="User">
        select * from t_user
        where 1=1
        <if test="name != null">
            and name = #{name}
        </if>
        <if test="info != null">
            and info = #{info}
        </if>
    </select>
    

    当传入过来的 name 不为空时,则拼接语句 and name = #{name}

    当传入过来的 info 不为空时,则拼接语句 and info = #{info}

    这样的话 mybatis 就能灵活的帮助我们~

    例如:

    /**
     *	这里只是部分代码,可以执行查询操作
     */
    @Test	
    	public void queryUser1() {
    		SqlSessionFactory factory = DbUtils.getInstance();
    		SqlSession session = factory.openSession();
    		IUserDao mapper = session.getMapper(IUserDao.class);
    		User user = new User();
    		user.setName("张三");
    //		user.setInfo("程序员");
    		List<User> list = mapper.queryUser1(user);
    		list.forEach(e -> System.out.println(e));
    	}
    

    输出结果为:User [id=1, name=张三, info=测试员, games=null] (这样mybatis就把我们想要查询的 name = "张三" 的信息给查询出来了)

    user.setName("张三"); 这条代码注释,

    然后将 user.setInfo("程序员"); 的注释取消, 效果如下:

    输出结果: User [id=3, name=李四, info=程序员, games=null]

    [QC] DEBUG [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(159) | ==>  Preparing: select * from t_user where 1=1 and info = ? 
    [QC] DEBUG [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(159) | ==> Parameters: 程序员(String)
    [QC] DEBUG [main] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(159) | <==      Total: 1
    User [id=3, name=李四, info=程序员, games=null]
    

    where

    if 可以通过搭配 where 来升级

    <select id="queryUser1" resultType="User">
    	select * from t_user
    	<where>
    		<if test="name != null">
    			and name = #{name}
    		</if>
    		<if test="info != null">
    			and info = #{info}
    		</if>
    	</where>
    </select>
    

    这样写的话就 mybatis 遇到AND或者OR这些,就能自己处理了

    我们传入一个空的 User 对象来测试

    public void queryUser1() {
        SqlSessionFactory factory = DbUtils.getInstance();
        SqlSession session = factory.openSession();
        IUserDao mapper = session.getMapper(IUserDao.class);
        User user = new User();
    //		user.setName("张三");
    //		user.setInfo("程序员");
        List<User> list = mapper.queryUser1(user);
        list.forEach(e -> System.out.println(e));
    }
    

    输出:

    User [id=1, name=张三, info=测试员, games=null]
    User [id=3, name=李四, info=程序员, games=null]
    User [id=4, name=王五, info=打酱油, games=null]
    User [id=7, name=鲁班, info=射手, games=[王者荣耀, QQ飞车, 刺激战场]]
    User [id=8, name=孙悟空, info=刺客, games=[王者荣耀, QQ飞车, 刺激战场]]
    

    choose, when, otherwise

    这个见名知意了, 和 Java 中的 switch 差不多的功能

    <!-- 
        1.name 不为空,则根据 name 查询
        2.info 不为空,则根据 info 查询
        3.否则根据id降序排列
    -->
    
    <select id="queryUser2" parameterType="user" resultType="User">
        select * from t_user where 1=1
            <choose>
                <when test="name != null">
                    and name = #{name}
                </when>
                <when test="info != null">
                    and info = #{info}
                </when>
                <otherwise>
                    order by id desc
                </otherwise>
            </choose>
    </select>
    

    set

    set 重要是用于更新数据

    修改传入的 id 的信息,如果 name不为空,就修改 name

    <update id="updateUser">
        update t_user
        <set>
            <if test="name != null">
                name = #{name}
            </if>
            <if test="info != null">
                info = #{info}
            </if>
        </set>
        where id = #{id}
    </update>
    

    测试

    @Test
    public void updateUser() {
        SqlSession session = DbUtils.getInstance().openSession();
        IUserDao mapper = session.getMapper(IUserDao.class);
        User user = new User();
        user.setId(1);
        user.setInfo("set修改了");
        int updateUser = mapper.updateUser(user);
        System.out.println(updateUser);
        session.commit();
    }
    

    日志记录

     ==>  Preparing: update t_user SET info = ? where id = ? 
     ==> Parameters: set修改了(String), 1(Integer)
     <==    Updates: 1
    

    trim

    trim标记是一个格式化的标记,可以完成set或者是where标记的功能

    trim 的属性

    属性 说明
    prefix 当 trim 中有内容时, 增加 prefix 所指定的前缀
    prefixOverrides 当 trim 中有内容时, 去除 prefixOverrides 指定的前缀
    suffix 当 trim 中有内容时, 增加 suffix 所指定的后缀
    suffixOverrides 当 trim 中有内容时, 去除 suffixOverrides 指定的后缀
    <select id="queryUser3" resultType="User">
        select * from t_user
        <trim prefix="where" prefixOverrides="AND|OR">
            <!-- trim可以代替这里的 where 功能			
                <where>
                    <if test="name != null">
                        and name = #{name}
                    </if>
                    <if test="info != null">
                        and info = #{info}
                    </if>
                </where> 
            -->
            <if test="name != null">
                and name = #{name}
            </if>
            <if test="info != null">
                and info = #{info}
            </if>
        </trim>
    </select>
    

    foreach

    foreach用来遍历,遍历的对象可以是数组,也可以是集合。

    先测试这条语句

    select * from t_user where 1=1 and id in(1,3,4,7)

    结果:

    1 张三 set修改了
    3 李四 程序员
    4 王五 打酱油
    7 鲁班 射手 王者荣耀;QQ飞车;刺激战场;

    //先处理一下接口
    public List queryUser5(@Param("ids") List<Integer> ids);
    

    配置文件内的sql

    <select id="queryUser5" resultType="User">
        select * from t_user where 1=1
        <if test="ids != null">
        and id in
            <foreach collection="ids" open="(" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </if>
    </select>
    

    foreach 属性

    属性 说明
    collection collection属性的值有三个分别是list、array、map三种
    open 前缀
    close 后缀
    separator 分隔符,表示迭代时每个元素之间以什么分隔
    item 表示在迭代过程中每一个元素的别名
    index 用一个变量名表示当前循环的索引位置

    日志记录

    | ==>  Preparing: select * from t_user where 1=1 and id in ( ? , ? , | ==> Parameters: 1(Integer), 3(Integer), 4(Integer), 7(Integer)
    | <==      Total: 4
    

    输出

    User(id=1, name=张三, info=set修改了, games=null)
    User(id=3, name=李四, info=程序员, games=null)
    User(id=4, name=王五, info=打酱油, games=null)
    User(id=7, name=鲁班, info=射手, games=[王者荣耀, QQ飞车, 刺激战场])
    
  • 相关阅读:
    织梦精准搜索自定义字段搜索证书查询
    织梦一个标签获取当前链接url(首页/列表页/列表分页/内容页/内容页分页)
    织梦dede:arclist按最新修改排序orderby=pubdate无效的解决方法
    织梦likearticle让mytypeid支持多个栏目和子栏目
    织梦站内选择和文件管理器中文乱码的解决方法(utf8编码程序包才会)
    WPFDispatcher示例
    WPF 核心体系结构
    WPF扩展标记
    WPF 路由事件
    WPF 自定义路由事件
  • 原文地址:https://www.cnblogs.com/zhiwenxi/p/11774853.html
Copyright © 2011-2022 走看看