`

MyBatis的SQL语句批量执行

 
阅读更多

一、背景

为了提升性能,时常需要批量执行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直接执行sql语句后续之一”可能探讨了如何在MyBatis中高效且有效地执行SQL操作。下面我们将深入探讨MyBatis的SQL执行机制及相关知识点。 首先,MyBatis的核心组件是SqlSessionFactory,它是创建...

    SpringBoot整合Mybatis连接SQL Server 跨库批量插入

    配置完成后,创建Mybatis的Mapper接口和XML文件,用于定义SQL语句。这里我们将关注跨库批量插入,所以需要两个数据库(假设为database1和database2)以及相应的表结构。例如,我们有两个表`table1`和`table2`,分别...

    详解MyBatis直接执行SQL查询及数据批量插入

    MyBatis是一个强大的持久层框架,它允许开发者直接编写SQL语句,简化了数据库操作。在本文中,我们将深入探讨如何使用MyBatis直接执行SQL查询以及如何进行数据的批量插入。 **一、直接执行SQL查询** 在MyBatis中,...

    mybatis自动sql生成插件源码

    在MyBatis中,拦截器用于在特定的执行点插入自定义行为,比如在SQL语句执行前或后。`AutoMapperInterceptor`实现了`org.apache.ibatis.plugin.Interceptor`接口,具备拦截执行方法的能力。它会检测到对Mapper接口的...

    Mybatis中SQL语句的编写.pdf

    ### MyBatis中SQL语句的编写 #### 一、概述 在MyBatis框架中,SQL语句的编写是一项核心任务。MyBatis作为一款优秀的持久层框架,支持多种方式来定义SQL语句,包括XML配置文件和注解等方式。本文档主要介绍在XML配置...

    mybatis之动态SQL

    动态 SQL 是 MyBatis 的一大特色,它允许我们在运行时根据条件构建 SQL 语句,极大地提高了代码的可维护性和灵活性。 动态 SQL 在 MyBatis 中主要通过 XML 映射文件或者注解来实现。在 XML 映射文件中,我们可以...

    Mybatis Plus 自定义批量插入或批量更新(根据唯一索引)

    最后,关于提供的 `injector` 文件,这可能是 Mybatis Plus 的一个插件或者工具类,用于注入 SQL 语句或者定制特定的操作。不过,由于具体文件内容未知,这里无法给出详细说明。如果你需要关于 `injector` 的具体...

    Mybatis与JDBC批量插入MySQL数据库性能测试

    首先,JDBC(Java Database Connectivity)是Java平台中用于与数据库交互的一种规范,它允许程序员使用SQL语句直接操作数据库。在批量插入场景下,JDBC提供了Statement对象的addBatch()和executeBatch()方法,可以将...

    MyBatis防止批量更新1

    MyBatis 是一个流行的持久层框架,它提供了插件机制来拦截 SQL 操作,以便于开发者可以在执行 SQL 语句前进行预处理或后续处理。本文将详细介绍 MyBatis 插件机制的实现原理和应用场景。 MyBatis 插件机制的实现...

    深入剖析MyBatis SQL执行流程:从配置到查询结果的全程追踪

    MyBatis是一个流行的Java持久层框架,它简化了数据库操作,允许开发者将SQL语句直接映射到Java方法。本文将深入探讨MyBatis的SQL执行流程,从配置解析到查询结果的返回,以及Spring如何整合MyBatis,特别是如何管理...

    mybatis plus 5种批量操作性能测试

    MyBatis Plus 支持自定义 SQL,可以通过 `executeBatch()` 执行批量 SQL 语句,如 `INSERT INTO table (column1, column2) VALUES (?, ?), (?, ?), ...` 这种形式,适用于需要定制 SQL 的场景。 5. **分批次插入...

    MyBatis语句规范化拦截器1

    MyBatis提供了插件(Plugins)机制,允许我们在执行SQL语句之前或之后插入自定义的处理逻辑。通过实现`org.apache.ibatis.plugin.Interceptor`接口并覆写`intercept`方法,我们可以创建一个拦截器。在`intercept`...

    mybatis执行自定义sql工具包

    而`mybatis-helper`工具包引入了动态SQL的概念,你可以将SQL语句写在一个单独的资源文件(如.properties或.xml)中,然后在运行时根据需要加载和执行。 使用`mybatis-helper`,你可以实现以下功能: 1. 动态SQL:...

    MyBatis动态SQL是一种强大的特性,它允许我们在SQL语句中根据条件动态地添加或删除某些部分,从而实现更加灵活和高效的数据

    而MyBatis的动态SQL特性正是为了解决这些问题而设计的,它允许开发者在XML映射文件中编写带有条件的SQL语句,从而简化了代码并增强了安全性。 ### 动态SQL的实现方式 MyBatis提供了一系列标签来实现动态SQL,主要...

    基于mybatis batch实现批量提交大量数据

    "基于MyBatis批量提交大量数据的实现" MyBatis批量提交大量数据是...需要注意在xml文件中配置多条参数同时插入,使用SqlSessionFactory和SqlSession来执行批量提交操作,并分段处理长sql语句,以免超出数据库的限制。

    如何批量测试Mybatis项目中的Sql是否正确详解

    总结来说,批量测试Mybatis项目中的SQL语句需要理解Mybatis的运行机制,利用反射技术动态执行Mapper接口中的方法,并记录执行结果。通过这种方法,开发者可以在数据库环境变化或SQL调整时快速定位和解决问题,确保...

    MyBatis通过BATCH批量提交的方法

    在MyBatis中,BATCH模式是指当执行多个SQL语句时,MyBatis会将这些语句缓存在内存中,然后在一个数据库会话中执行这些语句。这可以大大提高批量操作的性能。 使用BATCH模式可以减少数据库连接的次数,从而提高性能...

    ### MyBatis动态SQL介绍说明、使用技巧和优缺点

    MyBatis作为一款出色的持久层框架,通过XML或注解的方式配置SQL语句,有效地实现了Java方法与SQL语句之间的映射。动态SQL是MyBatis的一项重要特性,它允许开发人员根据条件动态地生成SQL片段,从而实现灵活的数据库...

    Mybatis 中的sql批量修改方法实现

    Mybatis的批量修改主要依赖于`&lt;foreach&gt;`标签,这个标签允许我们遍历集合并在SQL语句中生成动态的条件。以下是一个简单的例子: 首先,在DAO层接口定义一个方法,该方法接收一个List类型的参数,例如`List&lt;Demo&gt;`,...

Global site tag (gtag.js) - Google Analytics