9.2 批量更新
在数据库中使用批量更新有助于提高性能。在 MyBatis 中,我们可以修改配置文件中 settings 的 defaultExecutorType 来制定其执行器为批量执行器,如代码清单 9-5 所示。
代码清单 9-5:配置批量执行器
<settings> ...... <setting name="defaultExecutorType" value="BATCH"/> ...... </settings>
当然我们也可以用 Java 代码来实现批量执行器的使用,如代码清单 9-6 所示。
代码清单 9-6:打开批量 SqlSession
sqlSessionFactory.openSession(ExecutorType.BATCH);
如果你是在 Spring 环境中使用批量执行器,也可以这样定义 Spring 的 Bean,如代码清单 9-7 所示。
代码清单 9-7:Spring 环境下的批量执行器
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> <!--更新采用批量模式 --> <constructor-arg index="1" value="BATCH"/> </bean>
批量执行需要注意的问题是,一旦使用了批量执行器,那么在默认的情况下,它在 commit 后才发送 SQL 到数据库,此时我们需要注意代码清单 9-8 所示的问题。
代码清单 9-8:批量执行器问题代码
SqlSession session = SqlSessionFactoryUtil.openSqlSession(); try { RoleMapper rmapper = session.getMapper(RoleMapper.class); Role role = new Role(); role.setRoleNo("role_no_xxx"); role.setRoleName("role_name_xxx"); role.setRoleNo("role_note_xxx"); rmapper.insertRole(role); Role role2 = rmapper.getRole("role_no_xxx"); System.err.println(role2.getRoleName()); session.commit(); } catch(Exception ex) { session.rollback(); ex.printStackTrace(); } finally { if (session != null) { session.close(); } }
我们运行上面的代码后,出现了下面这行代码:
System.err.println(role2.getRoleName());
抛出空异常,然后事务回滚。
从代码上看,我们先插入了 role 到数据库,它运行了代码 role2 依旧为空,所以打印其名称的时候将抛出异常,为什么会这样呢?由于我们采用了批量的执行器,则更新数据 SQL 的执行操作是要到 session.commit() 中才会被 MyBatis 发送到数据库执行的,所以在我们执行下面的操作之前,insert 在数据库中根本没有被执行,于是便出现了这句话获取一个空对象的情况。这是我们需要注意的。
Role role2 = rmapper.getRole("role_no_xxx");
而我们在 getRole 方法调用前并不想提交事务,因为后面可能还有其他更新的数据库语句要执行,这个时候我们只要执行 SqlSession 的 flushStatements 方法便可以了,它的含义是将当前缓存的 SQL 发送给数据库执行。于是我们按照代码清单 9-9 的方法修改代码。
代码清单 9-9:在获取数据前发送 SQL
RoleMapper rmapper = session.getMapper(RoleMapper.class); Role role = new Role(); role.setRoleNo("role_no_xxx"); role.setRoleName("role_name_xxx"); role.setNote("role_note_xxx"); rmapper.insertRole(role); session.flushStatements(); Role role2 = rmapper.getRole("role_no_xxx"); System.err.println(role2.getRoleName()); session.commit();
这样就避免了在一个事务里面插入了数据,而 select 查不出来的情况,代码就能运行成功了,我们在使用批量更新的时候要特别注意这个问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论