一、背景
为了提升性能,时常需要批量执行SQL语句。但是MyBATIS官方并没有给出很好的解决方案。俗话说,自己动手,丰衣足食。自己写一个呗
二、实现思路
Spring中的jdbcTemplate.batchUpdate()能够批量执行SQL语句。所以,只要想办法拿到Mybatis中的SQL语句(以?作为占位符),然后结合jdbcTemplate.batchUpdate()就能够批量执行了
但是,要注意的是此处没有事务控制,事务控制在业务外层需要自己控制
三、代码实现
/** * 批处理的最大执行次数 */ protected static final int MAX_BATCH_COUNT = 1000; @Resource private JdbcTemplate jdbcTemplate; /** * <p> * 批量处理update或insert, 使用jdbcTemplate做批处理 * </p> * <p> * List中的对象需要和sqlMapper中的parameterType属性一致 * </p> * * @param sqlId sqlMap中的ID * @param objList 需要增加或更新的obj对象 * @return */ public <T> int executeBatch(@Nullable final String sqlId, @Nullable final List<T> objList) { if (StringUtils.isEmpty(sqlId) || CollectionUtils.isEmpty(objList)) { throw new IllegalArgumentException("请求参数不能为空!"); } SqlSessionDaoSupport daoSupport = (SqlSessionDaoSupport) updateDAO; // 从mybatis配置文件中获取动态sql BoundSql bound = daoSupport.getSqlSession().getConfiguration().getMappedStatement(sqlId).getSqlSource() .getBoundSql(objList.get(0)); String preparedSql = bound.getSql(); final List<ParameterMapping> parameterMappingList = bound.getParameterMappings(); int[][] result = jdbcTemplate.batchUpdate(preparedSql, objList, MAX_BATCH_COUNT, new ParameterizedPreparedStatementSetter<T>() { @Override public void setValues(PreparedStatement ps, T obj) throws SQLException { Map map = convertParamToMap(obj); if (map.size() == 0) { throw new IllegalArgumentException("参数类型错误!"); } for (int index = 0; index < parameterMappingList.size(); index++) { ParameterMapping parameter = parameterMappingList.get(index); Object o = map.get(parameter.getProperty()); if (o == null) { if (parameter.getJavaType() == Boolean.class) { if (parameter.getProperty().startsWith("is")) { String booleanPropertyName = StringUtils.uncapitalize(StringUtils.substring( parameter.getProperty(), 2)); o = map.get(booleanPropertyName); } if (o == null) { logger.error("请求参数属性名称不合法, 找不到批处理请求数据的属性值[" + parameter.getProperty() + "]"); } } } else { // 如果是枚举类型,则转换成name if (o.getClass().isEnum()) { o = o.toString(); } } ps.setObject(index + 1, o); } } }); int succ = 0; for (int i = 0; i < result.length; i++) { for (int j = 0; j < result[i].length; j++) { succ += result[i][j] > 0 ? 1 : 0; } } return succ; } private Map convertParamToMap(Object param) { if (param == null) { return Maps.newHashMap(); } if (param instanceof Map) { return (Map) param; } else { return BeanMappingUtil.describe(param); } }
其中:BeanMappingUtil是guava的包
相关推荐
主要介绍了MyBatis直接执行SQL查询及数据批量插入的相关知识,需要的朋友一起学习吧
最近在项目中有这么一段代码:下载服务器基础业务数据进行本地批量插入操作,因项目中使用mybatis进行持久化操作,故直接考虑使用mybatis的批量插入功能。 1.以下是Mapper接口的部分代码 public interface ...
主要介绍了Mybatis批量更新三种方式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
在操作数据库时,经常会碰到批量插入、批量删除的情况,直接执行SQL语句还好做一点,当使用Mybatis进行批量插入、批量删除时会有一些问题。下面对使用Mybatis批量插入,批量删除进行介绍
Sql语句中,当删除条件并不唯一的时候,我们有两种删除的sql语句,一种使用or拼接where中的条件,例如delete from 表名where 条件1 or 条件2,另一种是使用in 例如delete from 表名where 元素in( ) 利用第一种删除...
在操作数据库时,经常会碰到批量插入、批量删除的情况,直接执行SQL语句还好做一点,当使用Mybatis进行批量插入、批量删除时会有一些问题。下面对使用Mybatis批量插入,批量删除进行介绍。 1. 批量插入 Java代码...
本篇仅记录批量update操作的sql语句,懂得SQL语句,那么MyBatis部分的操作简单了。 注意:下列批量更新语句都是作为一个事务整体执行,要不全部成功,要不全部回滚。 二、MSSQL的SQL语句 WITH R AS( ...
11、Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式? 12、如何执行批量插入? 13、如何获取自动生成的(主)键值? 14、在 mapper 中如何传递多个参数? 15、Mybatis 动态 sql 有什么用?...
春天数据bean Spring数据的Ebean实现。... 使用JDBC简单语句(不是PreparedStatement)执行查询 根据主键删除单个实体 为什么选择 我选择考虑的框架条件: 该框架应包含(而不是隐藏)我们正在使用SQ
│ Java面试题74:sql语句优化小技巧.mp4 │ Java面试题75:批量插入几百万条数据.mp4 │ Java面试题76:有没有使用过redis.mp4 │ Java面试题77:redis的使用场景.mp4 │ Java面试题78:redis存储对象的方式.mp4 │...