天天看点

mybatis 批量update_MyBatis通透理解

mybatis 批量update_MyBatis通透理解
MyBatis编程步骤

​ 1.创建SqlSessionFactory对象

​ 2.通过SqlSessionFactory获取SqiSession对象

​ 3.通过SQLSession对象获得Mapper代理对象

​ 4.通过Mapper代理对象,执行数据库操作

​ 5.执行成功,则使用SqlSession提交事务

​ 6.执行失败,则使用SQLSession回滚事务

​ 7.关闭会话

Mybatis动态SQL,动态SQL的执行原理

​ Mybatis的动态SQL,可以让我们在XML映射文件中,以XML标签的形式编写动态SQL,完成逻辑判断和动态拼接SQL的功能。

​ 执行原理为:使用OGNL的表达式,从SQL参数对象中计算表达式的值,根据表达式的值动态拼接SQL,以此来完成动态SQL的功能。

​ 可以参考官网文档:https://mybatis.org/mybatis-3/zh/dynamic-sql.html

通常一个XML映射文件都会写一个Mapper接口对应,这个Mapper接口的工作原理,Mapper接口里的方法,参数不同,可以重载吗

​ Mapper接口,对应关系:

​ 1.接口的全限名,就是映射文件中的"namespace"的值

​ 2.接口的方法名,就是映射文件中MapperedStatement的"id"值

<resultMap id="BaseResultMap" type="com.my.blog.website.modal.Vo.AttachVo">
           

​ 3.接口方法内的参数,就是传递给SQL的参数

​ Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定为一个对应的MapperedStatement

​ 总结来说,在 Mybatis 中,每一个

<select />

<insert />

<update />

<delete />

标签,都会被解析为一个 MappedStatement 对象。

​ 另外,Mapper 接口的实现类,通过 MyBatis 使用

JDK Proxy

自动生成其代理对象 Proxy ,而代理对象 Proxy 会拦截接口方法,从而“调用”对应的 MappedStatement 方法,最终执行 SQL ,返回执行结果

Mapper接口绑定的实现方式

​ 1.通过XML Mapper里面写SQL来绑定,在这种情况下,要指定XML映射文件里面的"namespace"必须为接口的全路径名。

​ 2.通过注解绑定,就是在接口的方法上加上@select,@Update,@Insert,@Delete注解,这里面包含SQL语句绑定。

@Select("select g.*,mg.stock_count,mg.start_date,mg.end_date from miaosha_goods mg left join goods g on mg.goods_id = g.id ")
public List<GoodsVo> getGoodsVoList();
           

​ 3.是第二种的特例,也是通过

注解

绑定,在接口的方法上面加上

@SelectProvider

@UpdateProvider

@InsertProvider

@DeleteProvider

注解,通过 Java 代码,生成对应的动态 SQL 。

MyBatis的XML Mapper文件中,不同的XML映射文件,id是否可以重复

​ 不同的XML Mapper文件,如果配置了namespace,那么id可以重复,如果没有配置namespace,那么id就不能重复。

​ 因为

namespace + id

是作为

Map<String, MappedStatement>

的 key 使用的

如何获取自动生成的主键值
// 方式一,使用 useGeneratedKeys + keyProperty 属性
<insert id="insert" parameterType="Person" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO person(name, pswd)
    VALUE (#{name}, #{pswd})
</insert>

// 方式二,使用 `<selectKey />` 标签
<insert id="insert" parameterType="Person">
    <selectKey keyProperty="id" resultType="long" order="AFTER">
        SELECT LAST_INSERT_ID()
    </selectKey>

    INSERT INTO person(name, pswd)
    VALUE (#{name}, #{pswd})
</insert>
           
在Mapper中如何传递多个参数

​ 1.使用Map集合,装载多个参数进行传递

​ 2.保持传递多个参数,使用@Param注解

​ 3.直接传递多个参数,不同@Param注解,这种方法就是按照参数在方法中的位置,从1开始,逐个不断向下

Mybatis都有哪些Executor执行器,之间的区别是什么

​ 1.SimpleExecutor:每执行一次update或者select,就创建一个Statement对象,用完立刻关闭Statement对象

​ 2.ReuseExecutor:执行update或者select,以SQL作为key查询缓存中的statement对象,存在就使用,不存在就创建,用完不关闭Statement对象,而是放置于缓存Map内,用于下一次使用

​ 3.BatchStatement:执行 update 操作(没有 select 操作,因为 JDBC 批处理不支持 select 操作),将所有 SQL 都添加到批处理中(通过 addBatch 方法),等待统一执行(使用 executeBatch 方法)。它缓存了多个 Statement 对象,每个 Statement 对象都是调用

​ 4.CachingExecutor :在上述的三个执行器之上,增加

二级缓存

的功能。

​ 通过设置

<setting name="defaultExecutorType" value="">

"value"

属性,可传入 SIMPLE、REUSE、BATCH 三个值,分别使用 SimpleExecutor、ReuseExecutor、BatchExecutor 执行器。

​ 通过设置

<setting name="cacheEnabled" value=""

"value"

属性为

true

时,创建 CachingExecutor 执行器。

Mybatis如何实现批量操作

​ 1.使用批处理

private static SqlSessionFactory sqlSessionFactory;

@Test
public void testBatch() {
    // 创建要插入的用户的名字的数组
    List<String> names = new ArrayList<>();
    names.add("占小狼");
    names.add("朱小厮");
    names.add("徐妈");
    names.add("飞哥");

    // 获得执行器类型为 Batch 的 SqlSession 对象,并且 autoCommit = false ,禁止事务自动提交
    try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH, false)) {
        // 获得 Mapper 对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        // 循环插入
        for (String name : names) {
            mapper.insertUser(name);
        }
        // 提交批量操作
        session.commit();
    }
}
           

​ 2.在xml文件中用foreach循环,就相当于insert into table(1,1) values((value,value),(value,value)),但是这种有大小限制,单条SQL不能超过语句的最大限制,默认1M.

mybatis支持一对一,一对多的关联查询.

具体可参考https://blog.csdn.net/xzm_rainbow/article/details/15336959

Mybatis 是如何进行分页的?分页插件的原理是什么?

Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的

内存分页

,而非

数据库分页

所以,实际场景下,不适合直接使用 MyBatis 原有的 RowBounds 对象进行分页。而是使用如下两种方案:

  • 在 SQL 内直接书写带有数据库分页的参数来完成数据库分页功能
  • 也可以使用分页插件来完成数据库分页。

这两者都是基于数据库分页,差别在于前者是工程师

手动

编写分页条件,后者是插件

自动

添加分页条件。

可以查看脑图:https://github.com/zy-yz/Xmind/tree/master/src/Xmind/mybatis

继续阅读