MyBatis——MyBatis的动态SQL

MyBatis的动态SQL

创建工程:

1.什么是动态SQL?

MyBatis的映射文件中支持在基础SQL上添加一些逻辑操作,并动态拼接成完整的SQL之后再执行,以达到SQL复用、简化编程的效果。

2.if标签

我们根据实体类的不同取值,使用不同的SQL语句来进行查询。比如在id如果不为空时可以根据 id查询,如果username不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

  • mapper接口

    java 复制代码
    public interface UserDao {
    
        //复杂条件查询
        public List<User> findByUser(User user);
    }
  • mapper映射文件

    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.wt.dao.UserDao">
        <!--使用别名-->
        <select id="findByUser" resultType="User">
        	<!-- 1=1是为了永真,使得之后所有条件都不成立时where关键字后面有内容,防止报错-->
            select * from user where 1=1
            <if test="username!=null and username != ''">
                and username=#{username}
            </if>
            <if test="birthday!=null">
                and birthday=#{birthday}
            </if>
            <if test="sex!=null and sex != ''">
                and sex=#{sex}
            </if>
            <if test="address!=null and address != ''">
                and address=#{address}
            </if>
        </select>
    </mapper>
  • 测试

    java 复制代码
        @Test
        public void testFindAll(){
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            User user = new User();
            user.setSex("男");
            user.setAddress("香港");
            List<User> userList = userDao.findByUser(user);
            for(User u : userList){
                System.out.println(u);
            }
        }

3.where标签

为了简化上面where 1=1的条件拼装,我们可以使用where标签将if标签代码块包起来,将1=1条件去掉。

若查询条件的开头为 "AND" 或 "OR",where 标签会将它们去除。

  • mapper映射文件

    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.by.dao.UserDao">
        <select id="findByUser" resultType="User">
            select * from user
            <!--where标签将if标签代码块包起来去掉开头 "AND" 或 "OR"-->
            <where>
                <if test="username!=null and username != ''">
                    and username=#{username}
                </if>
                <if test="birthday!=null">
                    and birthday=#{birthday}
                </if>
                <if test="sex!=null and sex != ''">
                    and sex=#{sex}
                </if>
                <if test="address!=null and address != ''">
                    and address=#{address}
                </if>
            </where>
        </select>
    </mapper>

4.set标签

set标签用于动态包含需要更新的列,并会删掉额外的逗号

  • mapper

    java 复制代码
    public void updateByUser(User user);
    xml 复制代码
        <update id="updateByUser" parameterType="user">
            update user
            <set>
                <if test="username!=null and username != '' ">
                    username=#{username},
                </if>
                <if test="birthday!=null">
                    birthday=#{birthday},
                </if>
                <if test="sex!=null and sex != '' ">
                    sex=#{sex},
                </if>
                <if test="address!=null and address != '' ">
                    address=#{address},
                </if>
            </set>
            where id=#{id}
        </update>
  • 测试

    java 复制代码
        @Test
        public void testUpdateByUser(){
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            User user = new User();
            user.setId(50);
            user.setBirthday(new Date());
            user.setAddress("加拿大");
            userDao.updateByUser(user);
        }

5.trim标签

trim标签可以代替where标签、set标签

  • mapper

    java 复制代码
        //修改
        public void updateByUser2(User user);
    xml 复制代码
    <update id="updateByUser2" parameterType="User">
            update user
            <!-- 增加SET前缀,忽略,后缀 -->
            <!--
              trim标签一定要包括if标签,作用:
                  prefix:加上前缀,"("
                  suffix:加上后缀,")"
                  prefixOverrides:去除多余的前缀内容
                  suffixOverrides:去除多余的后缀内容,","
          -->
            <trim prefix="SET" suffixOverrides=",">
                <if test="birthday!=null">
                    birthday=#{birthday},
                </if>
                <if test="sex!=null and username != '' ">
                    sex=#{sex},
                </if>
                <if test="address!=null and username != '' ">
                    address=#{address},
                </if>
            </trim>
            where id=#{id}
        </update>

6.foreach标签

foreach标签的常见使用场景是集合进行遍历

  • mapper

    java 复制代码
        //批量删除
        public void deleteUserByIds(@Param("ids") List<Integer> ids);
    	//批量添加
        public void insertUsers(@Param("userList") List<User> userList);
    xml 复制代码
        <delete id="deleteUserByIds" parameterType="list">
            delete from user where id in
            <!--
                collection:取值list、array、map、@Param("keyName")、对象的属性名
                item:循环取出的具体对象
                open:起始符
                separator:分隔符
                close:结束符
            -->
            <foreach collection="ids" item="id" open="(" close=")" separator=",">
                #{id}
            </foreach>
        </delete>
    
    	<insert id="insertUsers" parameterType="list">
            INSERT INTO user(username,password,birthday,sex,address)
            VALUES
            <foreach collection ="userList" item="user" separator =",">
                (#{user.username},#{user.password},#{user.birthday},
                							#{user.sex},#{user.address})
            </foreach>
        </insert>
  • 测试

    java 复制代码
        @Test
        public void testDeleteUserByIds(){
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            List<Integer> ids = new ArrayList();
            ids.add(50);
            ids.add(64);
            ids.add(67);
            userDao.deleteUserByIds(ids);
        }
    
    //通过将数据放入集合中使用forEach标签来执行sql语句,要比执行多次sql语句要更加省时
    	@Test
        public void testInsertUsers(){
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            long start = System.currentTimeMillis();
            List<User> userList = new ArrayList<>();
            for(int i = 0 ;i < 10000; i++) {
                User user = new User();
                user.setUsername("刘德华");
                user.setPassword("111");
                user.setBirthday(new Date());
                user.setSex("男");
                user.setAddress("香港");
                //userDao.insertUser(user);
                userList.add(user);
            }
            userDao.insertUsers(userList);
            long end = System.currentTimeMillis();
            System.out.println("一万条数据总耗时:" + (end-start) + "ms" );
            sqlSession.commit();
        }

7.sql标签

sql元素标签用来定义可重复使用的SQL代码片段,使用时只需要用include元素标签引用即可

  • mapper

    java 复制代码
        //复杂条件查询
        public List<User> findByUser3(User user);
    xml 复制代码
        <!-- 定义SQL片段 -->
        <sql id="query_user_where">
            <if test="username!=null and username != ''">
                and username=#{username}
            </if>
            <if test="birthday!=null">
                and birthday=#{birthday}
            </if>
            <if test="sex!=null and sex != ''">
                and sex=#{sex}
            </if>
            <if test="address!=null and address != ''">
                and address=#{address}
            </if>
        </sql>
        <select id="findByUser3" resultType="User">
            select * from user
            <where>
                <include refid="query_user_where"></include>
            </where>
        </select>
  • 测试

    java 复制代码
        @Test
        public void testFindAll3(){
            UserDao userDao = sqlSession.getMapper(UserDao.class);
            User user = new User();
            user.setAddress("香港");
            user.setUsername("刘德华");
            List<User> userList = userDao.findByUser3(user);
            for(User u : userList){
                System.out.println(u);
            }
        }
相关推荐
MadPrinter1 天前
SpringBoot学习日记 Day11:博客系统核心功能深度开发
java·spring boot·后端·学习·spring·mybatis
奔跑吧邓邓子1 天前
【Java实战㉟】Spring Boot与MyBatis:数据库交互的进阶之旅
java·spring boot·实战·mybatis·数据库交互
lunzi_fly1 天前
【源码解读之 Mybatis】【基础篇】-- 第1篇:MyBatis 整体架构设计
java·mybatis
摸鱼仙人~1 天前
深入理解 MyBatis-Plus 的 `BaseMapper`
java·开发语言·mybatis
隔壁阿布都1 天前
spring boot + mybatis 使用线程池异步修改数据库数据
数据库·spring boot·mybatis
Mcband2 天前
MyBatis 拦截器让搞定监控、脱敏和权限控制
mybatis
╭╰4022 天前
苍穹外卖优化-续
java·spring·mybatis
weixin_456904272 天前
基于Spring Boot + MyBatis的用户管理系统配置
spring boot·后端·mybatis
码熔burning2 天前
Redis 的三种高效缓存读写策略!
redis·缓存·mybatis
stein_java3 天前
Mybatis-7 XML映射器
数据库·sql·mybatis