精华内容
下载资源
问答
  • mybatis-plus Sqlsession批量执行sql语句

    千次阅读 2018-06-15 16:12:29
    正常使用mybaitis 在配置文件...获取Dao就可以直接用了 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 你会发现后台不会创建sqlsession了 而是用的同一个 <bean class="org.mybatis....

    正常使用mybaitis 在配置文件创建bean  就可以在使用时

    @Autowired
    SqlSession sqlSession;
    获取Dao就可以直接用了
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
    你会发现后台不会创建sqlsession了 而是用的同一个
    

    <bean class="org.mybatis.spring.SqlSessionTemplate" id="sqlSession">

        <constructor-arg index="0" ref="sqlSessionFactory"/>
        <constructor-arg index="1" value="BATCH"/>
    </bean>


    而mybatis-plus 必须配置其封装后的 MybatisSqlSessionTemplate

    <bean class="com.baomidou.mybatisplus.MybatisSqlSessionTemplate" id="sqlSession">
        <constructor-arg index="0" ref="sqlSessionFactory"/>
        <constructor-arg index="1" value="BATCH"/>
    </bean>
    完毕
    展开全文
  • Configuration c = this... batchExecutor.doUpdate(c.getMappedStatement(sql), entity); if (i++ > 0 && i % BATCH_SIZE == 0) { batchExecutor.doFlushStatements(); } } batchExecutor.doFlushStatements();
    Configuration c = this.getSqlSession().getConfiguration();
    ManagedTransactionFactory managedTransactionFactory = new ManagedTransactionFactory();
    BatchExecutor batchExecutor = 
    new BatchExecutor(c,managedTransactionFactory.newTransaction(this.getSqlSession().getConnection(), false));
    int i = 0;
    for (T entity : collection) {
    	batchExecutor.doUpdate(c.getMappedStatement(sql), entity);
    	if (i++ > 0 && i % BATCH_SIZE == 0) {
    		batchExecutor.doFlushStatements();
    	}
    }
    batchExecutor.doFlushStatements();

    展开全文
  • Mybatis 的三种执行器❝在企业开发中, 对数据库的批量操作, 是一个非常常见的操作, Mybatis提供了批量执行器, 来支持批量操作.❞Mybatis sql执行器Mybatis 支持全局修改执行器, 参数名为: defaultExecutorType. 但是...

    Mybatis 的三种执行器

    在企业开发中, 对数据库的批量操作, 是一个非常常见的操作, Mybatis提供了批量执行器, 来支持批量操作.

    Mybatis sql执行器

    Mybatis 支持全局修改执行器, 参数名为: defaultExecutorType. 但是笔者并不推荐这种方式,笔者建议在获取sqlSession对象时设置. Mybatis 共有三种执行器:

    • SIMPLE: 默认的执行器, 对每条sql进行预编译->设置参数->执行等操作
    • BATCH: 批量执行器, 对相同sql进行一次预编译, 然后设置参数, 最后统一执行操作
    • REUSE: REUSE执行器会重用预处理语句prepared statements

    如何设置执行器

    1.局部设置

    在获取sqlSession时设置, 需要注意的时, 如果选择的是批量执行器时, 需要手工提交事务。

    // 获取指定执行器的sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)

    // 获取批量执行器时, 需要手动提交事务
    sqlSession.commit();

    2.全局设置

    可在全局配置文件中配置。

    <settings>
    <setting name="defaultExecutorType" value="BATCH" />
    settings>

    三种执行器效率测试

    xml代码:

    <mapper namespace="com.ywh.demo.mapper.StudentMapper">


    <insert id="save" useGeneratedKeys="true" keyProperty="id">
    insert into t_student values (null , #{name}, #{age}, #{sex}, #{birth})
    insert>

    mapper>

    测试代码:

    对于一条sql语句的执行不同的执行器没有太大的差异,所以这边采用插入10000条数据的方式。

    public class TestStudentMapper {

    // 批量保存方法
    private void batchSave(StudentMapper mapper) {
    // 初始化10000个对象
    List list = new ArrayList<>();for (int i = 0; i < 10000; i++) {
    list.add(new StudentPO("zhangsan_" + i, "M",20 + i % 10, LocalDate.now()));
    }// 批量执行long start = System.currentTimeMillis();for (StudentPO studentPO : list) {
    mapper.save(studentPO);
    }long end = System.currentTimeMillis();// 输出执行耗时
    System.out.println("耗时:" + (end - start) + " ms!");
    }// 默认执行器@Testpublic void test_SIMPLE(){// 获取自动提交事务的Maper
    StudentMapper mapper = SqlSessionUtil.getMapperAutoTx(StudentMapper.class);// 执行批量保存
    batchSave(mapper);
    }// 重用预编译执行器@Testpublic void test_REUSE(){// 获取批量保存sqlSession
    SqlSession sqlSession = SqlSessionUtil.openSession(ExecutorType.REUSE, true);// 获取Mapper 对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 执行批量保存
    batchSave(mapper);
    }// 批量执行器@Testpublic void test_BATCH(){// 获取批量保存sqlSession
    SqlSession sqlSession = SqlSessionUtil.openSession(ExecutorType.BATCH, true);// 获取Mapper 对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 执行批量保存
    batchSave(mapper);
    sqlSession.commit();
    }
    }

    测试结果:

    1. simple方式:从执行日志可以看出, 每次插入操作, 都会执行编译, 设置参数, 执行sql操作.
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==>  Preparing: insert into t_student values (null , ?, ?, ?, ?) 
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_0(String), 20(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Preparing: insert into t_student values (null , ?, ?, ?, ?)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_1(String), 21(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Preparing: insert into t_student values (null , ?, ?, ?, ?)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_2(String), 22(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1
    ...
    耗时:21575 ms!
    1. reuse方式:从执行日志可以看出, 只有第一次插入操作, 执行了sql编译步骤, 对其它插入操作执行了设置参数, 执行sql的操作.
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==>  Preparing: insert into t_student values (null , ?, ?, ?, ?) 
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_0(String), 20(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_1(String), 21(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_2(String), 22(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1
    ...
    耗时:19322 ms!
    1. batch方式:从执行日志可以看出, 只对第一次插入操作执行了sql编译操作, 对其它插入操作仅执行了设置参数操作, 最后统一执行.
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==>  Preparing: insert into t_student values (null , ?, ?, ?, ?) 
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_0(String), 20(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_1(String), 21(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_2(String), 22(Integer), M(String), 2020-07-24(Date)
    ...
    耗时:835 ms!

    「结论:」 在做批量操作时, 使用批量执行器, 性能会有很大的提升.

    点击关注不迷路09adf834094acc6c347197a10d918fb5.png09adf834094acc6c347197a10d918fb5.png09adf834094acc6c347197a10d918fb5.png更多技术分享、优质文章尽在作者的公众号:「程序员的小黑屋」,长按下图订阅,第一时间获取更新。↓↓↓

    98ef19bb95a0e6541382f4d305979991.png

    展开全文
  • Mybatis 的三种执行器❝在企业开发中, 对数据库的批量操作, 是一个非常常见的操作, Mybatis提供了批量执行器, 来支持批量操作.❞Mybatis sql执行器Mybatis 支持全局修改执行器, 参数名为: defaultExecutorType. 但是...

    Mybatis 的三种执行器

    在企业开发中, 对数据库的批量操作, 是一个非常常见的操作, Mybatis提供了批量执行器, 来支持批量操作.

    Mybatis sql执行器

    Mybatis 支持全局修改执行器, 参数名为: defaultExecutorType. 但是笔者并不推荐这种方式,笔者建议在获取sqlSession对象时设置. Mybatis 共有三种执行器:

    • SIMPLE: 默认的执行器, 对每条sql进行预编译->设置参数->执行等操作
    • BATCH: 批量执行器, 对相同sql进行一次预编译, 然后设置参数, 最后统一执行操作
    • REUSE: REUSE执行器会重用预处理语句prepared statements

    如何设置执行器

    1.局部设置

    在获取sqlSession时设置, 需要注意的时, 如果选择的是批量执行器时, 需要手工提交事务。

    // 获取指定执行器的sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)

    // 获取批量执行器时, 需要手动提交事务
    sqlSession.commit();

    2.全局设置

    可在全局配置文件中配置。

    <settings>
    <setting name="defaultExecutorType" value="BATCH" />
    settings>

    三种执行器效率测试

    xml代码:

    <mapper namespace="com.ywh.demo.mapper.StudentMapper">


    <insert id="save" useGeneratedKeys="true" keyProperty="id">
    insert into t_student values (null , #{name}, #{age}, #{sex}, #{birth})
    insert>

    mapper>

    测试代码:

    对于一条sql语句的执行不同的执行器没有太大的差异,所以这边采用插入10000条数据的方式。

    public class TestStudentMapper {

    // 批量保存方法
    private void batchSave(StudentMapper mapper) {
    // 初始化10000个对象
    List list = new ArrayList<>();for (int i = 0; i < 10000; i++) {
    list.add(new StudentPO("zhangsan_" + i, "M",20 + i % 10, LocalDate.now()));
    }// 批量执行long start = System.currentTimeMillis();for (StudentPO studentPO : list) {
    mapper.save(studentPO);
    }long end = System.currentTimeMillis();// 输出执行耗时
    System.out.println("耗时:" + (end - start) + " ms!");
    }// 默认执行器@Testpublic void test_SIMPLE(){// 获取自动提交事务的Maper
    StudentMapper mapper = SqlSessionUtil.getMapperAutoTx(StudentMapper.class);// 执行批量保存
    batchSave(mapper);
    }// 重用预编译执行器@Testpublic void test_REUSE(){// 获取批量保存sqlSession
    SqlSession sqlSession = SqlSessionUtil.openSession(ExecutorType.REUSE, true);// 获取Mapper 对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 执行批量保存
    batchSave(mapper);
    }// 批量执行器@Testpublic void test_BATCH(){// 获取批量保存sqlSession
    SqlSession sqlSession = SqlSessionUtil.openSession(ExecutorType.BATCH, true);// 获取Mapper 对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);// 执行批量保存
    batchSave(mapper);
    sqlSession.commit();
    }
    }

    测试结果:

    1. simple方式:从执行日志可以看出, 每次插入操作, 都会执行编译, 设置参数, 执行sql操作.
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==>  Preparing: insert into t_student values (null , ?, ?, ?, ?) 
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_0(String), 20(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Preparing: insert into t_student values (null , ?, ?, ?, ?)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_1(String), 21(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Preparing: insert into t_student values (null , ?, ?, ?, ?)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_2(String), 22(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1
    ...
    耗时:21575 ms!
    1. reuse方式:从执行日志可以看出, 只有第一次插入操作, 执行了sql编译步骤, 对其它插入操作执行了设置参数, 执行sql的操作.
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==>  Preparing: insert into t_student values (null , ?, ?, ?, ?) 
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_0(String), 20(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_1(String), 21(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1

    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_2(String), 22(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- <== Updates: 1
    ...
    耗时:19322 ms!
    1. batch方式:从执行日志可以看出, 只对第一次插入操作执行了sql编译操作, 对其它插入操作仅执行了设置参数操作, 最后统一执行.
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==>  Preparing: insert into t_student values (null , ?, ?, ?, ?) 
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]-
    ==> Parameters: zhangsan_0(String), 20(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_1(String), 21(Integer), M(String), 2020-07-24(Date)
    [main][DEBUG][o.z.l.m.l.mapper.StudentMapper.save]- ==> Parameters: zhangsan_2(String), 22(Integer), M(String), 2020-07-24(Date)
    ...
    耗时:835 ms!

    「结论:」 在做批量操作时, 使用批量执行器, 性能会有很大的提升.

    点击关注不迷路403299493b850e46ad8d8d4d3b0c1d23.png403299493b850e46ad8d8d4d3b0c1d23.png403299493b850e46ad8d8d4d3b0c1d23.png更多技术分享、优质文章尽在作者的公众号:「程序员的小黑屋」,长按下图订阅,第一时间获取更新。↓↓↓

    5980cd98a754e67e501fc66ad20e786d.png

    展开全文
  • mybatis批量update,返回行数为-1  mybatis批量更新返回结果为-1...BATCH可以批量更新操作,缓存SQL以提高性能,缺陷就是无法获取update、delete返回的行数。 如果要拿到更新条数,修改如下: 在mybatis-config.xml配
  • 然后编写批量更新语句时候,发现老是更新失败,但是从控制台获取sql语句又能够在数据库中正常执行,这个小坑让我花了些时间,为了避免以后再犯错,在此这里来记录下解决办法。 二、报错信息 注:在使用本方案解决...
  • mybatis的一级缓存mybatis的一级缓存是基于sqlsession为生命周期的,如果多次执行同一个sql语句时,只需第一次连接数据库查询,剩下几次均可通过mybatis缓存获取。生命周期:当你这个sqlsession没有了,会...
  • 21. Mybatis 的三种执行

    千次阅读 多人点赞 2019-08-27 17:05:52
    在企业开发中, 对数据库的批量操作, 是一个非常常见的操作, Mybatis提供了批量执行器, 来支持批量操作. 1. Mybatis sql执行器 Mybatis 支持全局修改执行器, 参数名为: defaultExecutorType. 但是笔者并不推荐这种...
  • Mybatis执行Update返回行数为负数

    千次阅读 2019-04-17 14:22:52
    获取mybatis的update行数,总是返回负数。后来在官网上找到原因,是由于defaultExecutorType的引起的,defaultExecutorType有三个执行器SIMPLE、REUSE和BATCH。其中BATCH可以批量更新操作缓存SQL以提高性能,但是有...
  • 3)执行SQL 4)读取结果 1.2、预编译的三种执行器 三种执行器都支持批处理 1)Mysql不支持(setFetchSize)设置一次性读取多少行。 2)addBatch批量操作,将多个SQL合并在一起,最后调executeBatch一起发送至数据库...
  • mybatis的一级缓存mybatis的一级缓存是基于sqlsession为生命周期的,如果多次执行同一个sql语句时,只需第一次连接数据库查询,剩下几次均可通过mybatis缓存获取。生命周期:当你这个sqlsession没有了,会...
  • mybatis之StatementHandler

    2020-06-14 21:05:46
    StatementHandler接口中的功能很多,例如创建Statement对象,为SQL语句绑定实参,执行select、insert、update、delete等多种类型的SQL语句,批量执行SQL语句,将结果集映射成结果对象。 StatementHandler接口的定义...
  • mybatis面试题

    2020-05-23 15:41:58
    为了应付面试,搞了一些面试题。 什么是Mybatis? Mybaits的优点:MyBatis框架的缺点: ...Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式? 如何执行批量插入? 如何获取自.
  • (2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。 (3)通过xml 文件或注解的方式将要执行的各
  • Mybatis的基本使用

    2021-01-03 12:10:48
    文章目录Mybatis基本使用使用的一般流程驼峰映射成下划线JDBCTYPE模糊查询插入数据,以及获取当前插入数据的主键执行流程如下批量插入数据 利用foreachupdate语句 以及使用 \Mybatis基本使用 通过简单的xml或注解来...
  • MyBatis之核心类

    千次阅读 2019-06-03 10:20:21
    核心类 参数处理器ParameterHandler(默认参数处理器DefaultParameterHandler) 参数解析:参数映射配置、参数映射解析、参数类型解析 ...简单执行器SimpleExecutor、批量执行器BatchExecuto...
  • Mybatis foreach遍历

    2019-06-14 16:53:48
    获取的要删除的用户的id,在dao层进行遍历这些id,每次都执行一次 delete from user where id=?;语句 这样的效率很低; >思路二 获取的要删除的用户的id,在dao层使用 'in' 或者 'or' 将这些id拼接到一个SQL...
  • 将defaultExecutorType配置为BATCH,可以批量更新操作缓存SQL以提高性能,但是有个缺陷就是无法获取update、delete返回的行数。 MyBatis配置文件中defaultExecutorType有三个参数 SIMPLE:执行执行其它语句 REUSE...
  • 而batch模式重复使用已经预处理的语句,并且批量执行所有更新语句,显然batch性能将更优; 但batch模式也有自己的问题,比如在Insert操作时,在事务没有提交之前,是没有办法获取到自增的id,这在某型情形下是不符合...
  • #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值 --> <!-- 将插入数据的主键返回,返回到user对象中 SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值...
  • Java对数据库的操作主要以下几步1)加载驱动,获取数据库连接2)开启事务3)创建语句4)批量执行操作或执行查询获取结果集,处理结果5)提交事务6)关闭连接第一步:加载驱动类,获取数据库连接,条件是要有对应的第三...
  • 批量插入相同类型的多个实体并返回生成的密钥 更新单个现有实体-一次更新实体的所有字段 获取多对一关系(部门公司) 获取一对多关系(公司部门) 更新实体一对多关系(公司部门)-添加两项,更新两项并删除一项-...
  • 在同一个事物内,同一条sql默认只执行一次,并将结果存入缓存中,因此多次查询会返回同样的值 因此在一个事物中,批量保存数据时,根据序列函数获取唯一id就会出错 解决方法: 序列函数加注解 @Options(flushCache...

空空如也

空空如也

1 2
收藏数 38
精华内容 15
关键字:

获取mybatis批量执行sql