【MyBatis】-04- MyBatis最佳实践

本文详细介绍了MyBatis的动态SQL语句,包括if、choose、trim和foreach,以及批量操作、关联查询、分页和MBG与通用Mapper的使用。重点讲解了如何进行批处理和延迟加载,以及物理分页的实现。此外,还提到了MyBatis-Plus作为MyBatis的增强工具,提供了通用CRUD、条件构造器和代码生成器等功能。
摘要由CSDN通过智能技术生成

【MyBatis】-0- 系列汇总

1.动态SQL语句

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

1.1 if

需要判断的时候,条件写在test中
    <select id="selectListIf" parameterType="user" resultMap="BaseResultMap" >
        select
            <include refid="baseSQL"></include>
        from t_user
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="userName != null">
                and user_name = #{userName}
            </if>
        </where>
    </select>

1.2 choose

需要选择一个条件的时候
    <!-- choose 的使用 -->
    <select id="selectListChoose" parameterType="user" resultMap="BaseResultMap" >
        select
        <include refid="baseSQL"></include>
        from t_user
        <where>
            <choose>
                <when test="id != null">
                    id = #{id}
                </when>
                <when test="userName != null and userName != ''">
                    and user_name like CONCAT(CONCAT('%',#{userName,jdbcType=VARCHAR}),'%')
                </when>
                <otherwise>

                </otherwise>
            </choose>
        </where>
    </select>

1.3 trim

需要去掉where、and、逗号之类的符号的时候
    <!--
        trim 的使用
        替代where标签的使用
    -->
    <select id="selectListTrim" resultMap="BaseResultMap" 
            parameterType="user">
        select <include refid="baseSQL"></include>
        <!-- <where>
            <if test="username!=null">
                and name = #{username}
            </if>
        </where> -->
        <trim prefix="where" prefixOverrides="AND |OR ">
            <if test="userName!=null">
                and user_name = #{userName}
            </if>
            <if test="age != 0">
                and age = #{age}
            </if>
        </trim>
    </select>

    <!-- 替代set标签的使用 -->
    <update id="updateUser" parameterType="User">
        update t_user
        <trim prefix="set" suffixOverrides=",">
            <if test="userName!=null">
                user_name = #{userName},
            </if>
            <if test="age != 0">
                age = #{age}
            </if>
        </trim>
        where id=#{id}
    </update>

1.4 foreach

需要遍历集合的时候
    <delete id="deleteByList" parameterType="java.util.List">
         delete from t_user 
         where id in
        <foreach collection="list" item="item" open="(" separator="," close=")">
             #{item.id,jdbcType=INTEGER}
        </foreach>
    </delete>

动态SQL主要是用来解决SQL语句生成的问题。

2.批量操作

我们在项目中会有一些批量操作的场景,比如导入文件批量处理数据的情况(批量新增商户、批量修改商户信息),当数据量非常大,比如超过几万条的时候,在Java代码中循环发送SQL到数据库执行肯定是不现实的,因为这个意味着要跟数据库创建几万次会话。即使在同一个连接中,也有重复编译和执行SQL的开销。
例如循环插入10000条(大约耗时3秒钟):
public class Test03Batch {
   

    public SqlSession session;

    @Before
    public void init() throws IOException {
   
        // 1.获取配置文件
        InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
        // 2.加载解析配置文件并获取SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        // 3.根据SqlSessionFactory对象获取SqlSession对象
        session = factory.openSession();
    }

    /**
     * 循环插入10000
     */
    @Test
    public void test1(){
   
        long start = System.currentTimeMillis();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int count = 12000;
        for (int i=2000; i< count; i++) {
   
            User user = new User();
            user.setUserName("a"+i);
            mapper.insertUser(user);
         }
         session.commit();
         session.close();
         long end = System.currentTimeMillis();
         System.out.println("循环批量插入"+count+"条,耗时:" + (end -start )+"毫秒");
    }
}
在MyBatis里面是支持批量的操作的,包括批量的插入、更新、删除。我们可以直接传入一个List、Set、Map或者数组,配合动态SQL的标签,MyBatis会自动帮我们生成语法正确的SQL语句。

2.1 批量插入

批量插入的语法是这样的,只要在values后面增加插入的值就可以了。
insert into tbl_emp (emp_id, emp_name, gender,email, d_id) values ( ?,?,?,?,? ),( ?,?,?,?,? ),( ?,?,?,?,? )

在Mapper文件里面,我们使用foreach标签拼接 values部分的语句:

    <!-- 批量插入 -->
    <insert id="insertUserList" parameterType="java.util.List" >
        insert into t_user(user_name,real_name)
        values
        <foreach collection="list" item="user" separator=",">
            (#{user.userName},#{user.realName})
        </foreach>

    </insert>

Java代码里面,直接传入一个List类型的参数。

    /**
     * 批量插入
     */
    @Test
    public void test2(){
   
        long start = System.currentTimeMillis();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int count = 12000
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值