精华内容
下载资源
问答
  • Mybatis批量执行SQL语句

    万次阅读 2018-01-28 16:04:01
    之前做批量插入SQL时都是用的标签,但有时需要插入成千上万条语句,此时用标签...而mybatis本身设计了批量执行SQL的方法,让数据库一条一条的SQL语句执行,但不是每执行一条连接一次数据库,而是连接一次数据库,然后依

    之前做批量插入SQL时都是用的<foreach>标签,但有时需要插入成千上万条语句,此时用<foreach>标签拼接的SQL就会非常大,有时数据库识别不了。<foreach> 标签作用组成一个非常大的批量插入SQL语句,让不同数据库去支持执行非常大的SQL语句;而mybatis本身设计了批量执行SQL的方法,让数据库一条一条的SQL语句执行,但不是每执行一条连接一次数据库,而是连接一次数据库,然后依次执行每条数据库。

    一、批量插入SQL

    目前数据库中数据如下
    这里写图片描述

    执行批量插入数据如下

        public static void testGetUserMap(){
            String resource = "conf.xml";
            InputStream in = MybaitsTest.class.getClassLoader().getResourceAsStream(resource);
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);   
            /*获得session时,传入批量执行器ExecutorType.BATCH*/
            SqlSession session = factory.openSession(ExecutorType.BATCH);
            UserDao userDao = session.getMapper(UserDao.class);
            User user = new User(0, "wanger", 25);
            for(int i=0; i<10; i++){
                userDao.addUsers(user);
            }
            /*一定要执行commit,否则数据库中不会插入数据*/
            session.commit();
        }

    执行上述方法,数据库中批量插入语数据
    这里写图片描述
    其中id为自动增长的主键,7-14中缺失的部分数据,是因为之前出入数据时没有执行commit,所以没有插入到数据库中。

    注意:
    这里写图片描述
    如果在mybatis的配置位置xml文件中没有配置defaultExecutorType默认执行器的话,mybatis默认执行简单SQL语句,即一次数据库连接只发送一条SQL语句,此时要做批量执行需要用<foreach> 标签拼接成一个大SQL语句,然后一次执行完毕。或者用上述批量插入方法,在获得session时设置批量执行器。
    默认配置如下

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

    当然也可以在配置文件中设置批量执行,在执行SQL语句时就不需要再设置批量执行器了ExecutorType.BATCH,整个工程中的所有SQL语句都会使用批量执行的方式。

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

    此种方法不可取,还是采用上面的默认配置方式,然后在获取session时设置批量执行器。

    二、spring集成mybatis时批量执行

    需要在spring的配置xml文件中加入下面的配置

        <!--配置一个可以进行批量执行的sqlSession  -->
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
            <constructor-arg name="executorType" value="BATCH"></constructor-arg>
        </bean>

    然后在做批量执行的时候,获得这个session就可以

        @Autowired
        private SqlSession sqlSession;
    
        public List<User> getUsers(){
            UserDao userDao= sqlSession.getMapper(UserDao .class);
            return userDao.getUsers();
        }
    展开全文
  • Mybatis批量插入sql语句 + 返回id

    千次阅读 2019-07-17 16:11:23
    我们在保存数据操作时,可能会遇到批量插入的操作,有3中方法来操作该保存: 一、Mybatis插入数据,返回id 在sql语句上添加下面代码 useGeneratedKeys="true" keyProperty="id" 例如: <insert id="insert...

    我们在保存数据操作时,可能会遇到批量插入的操作,有3中方法来操作该保存:

    一、Mybatis插入数据,返回id

    在sql语句上添加下面代码

    useGeneratedKeys="true" keyProperty="id"

    例如:

    <insert id="insert" useGeneratedKeys="true" keyProperty="id">
            INSERT INTO t_user
           (userName,sex)
            values ("小明","男")
        </insert>

    二、批量插入

    1、在 for循环中批量调用单次保存操作,sql语句简单,操作方便,但是效率比较低,因为要调用多次,mysql要执行多次insert操作。

    2、利用Mybatis批量保存sql语句,service层只需要调用一次,就能完成多条数据插入操作,sql语句如下:

    <insert id="batchInsertSelective" parameterType="java.util.List">
    
    		INSERT INTO 表名 (reason,shop_id,create_user) values
    
    		<foreach collection="list" item="record" index="index" separator=",">
    
    			<trim prefix=" (" suffix=")" suffixOverrides="," >
    			
    				#{record.reason,jdbcType=VARCHAR},
    				#{record.shopId,jdbcType=BIGINT},
    				#{record.createUser,jdbcType=VARCHAR},
    			</trim>
    		</foreach>
    	</insert>

    3、如果是有条件的批量操作呢,只保存有值的字段呢,又该如何写,sql语句如下:

    <insert id="batchInsertSelective" parameterType="java.util.List">
    
    		INSERT INTO 表名
    		<foreach collection="list" item="record" index="index" separator=",">
    
    			<if test="index == 0">
    				<trim prefix="(" suffix=")" suffixOverrides="," >
    				<if test="record.reason != null"> reason,</if>
    				<if test="record.shopId != null"> shop_id,</if>
    				<if test="record.createUser != null"> create_user,</if>
    				</trim>
    				values
    			</if>
    			<trim prefix=" (" suffix=")" suffixOverrides="," >
    
    				<if test="record.reason!=null">#{record.reason,jdbcType=VARCHAR},</if>
    				<if test="record.shopId!=null">#{record.shopId,jdbcType=BIGINT},</if>
    				<if test="record.createUser!=null">#{record.createUser,jdbcType=VARCHAR},</if>
    			</trim>
    		</foreach>
    	</insert>

     

    展开全文
  • 为了提升性能,时常需要批量执行SQL语句。但是MyBATIS官方并没有给出很好的解决方案。俗话说,自己动手,丰衣足食。自己写一个呗   二、实现思路 Spring中的jdbcTemplate.batchUpdate()能够批量执行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的包

    展开全文
  • 一、直接执行SQL查询: 1、mappers文件节选、 <resultMap id="AcModelResultMap" type="com.izumi.InstanceModel"> <result column="instanceid" property="instanceID" jdbcType="VARCHAR" /> &...

    一、直接执行SQL查询:

     1、mappers文件节选、

     

    <resultMap id="AcModelResultMap" type="com.izumi.InstanceModel">
      <result column="instanceid" property="instanceID" jdbcType="VARCHAR" />
      <result column="instancename" property="instanceName" jdbcType="VARCHAR" />
    </resultMap>
    
    <select id="getInstanceModel" resultType="com.izumi.InstanceModel">
      ${paramSQL} 
    </select>

    2、DAO类节选

    public interface SomeDAO{
      List<InstanceModel> getInstanceModel(@Param("paramSQL")String sql);
    }

    3、注意事项 

    3.1:传入方法的参数sql必须遵循以下规范"select XXX as instanceid, XXX as instancename ....." ,否则MyBatis无法自动将查询结果变成Java对象。

    3.2: mappers文件中的#{}语法与${}语法的区别:

        默认情况下, #{}语法会促使MyBatis生成PreparedStatement属性并且使用PreparedStatement的参数(=?)来设置值。如果你想直接将未更改的字符串代入到sql中,可以使用${}。

        也就是说,MyBatis看到 #{}会认为你在给sql中的变量赋值,就像JDBC编程中给问号赋值一样(比如MyBatis会判断它的类型,并自动在前后加单引号)。而当MyBatis看到${}的时候会直接将之替换成变量的值而不做任何处理。

    所以在使用${}的时候,不需要像#{}一样写"jdbcType=VARCHAR"之类的属性。 

    3.3:resultType和resultMap

    按照1中的写法, < resultMap > 部分可以删除不用了,因为在接下来的<select >中没用使用定义的resultMap,而是使用了resultType。

    所以我们可以看出,关于<select >返回值的定义有两种写法,一种是定义一个resultMap然后引用这个resultMap,还有一种就是直接使用resultType指定一个类的路径。

    二、批量插入数据

    1、经验告诉我们,使用insert into XXX values(XX)(XXX)(XXX),比使用insert into XXX values(XX),insert into XXX values(XXX),insert into XXX values(XXX)效率要高。

    2、在MyBatis中的用法 

    2.1、mappers文件节选 

    <insert id="insertBatch" >
        insert into student ( <include refid="Base_Column_List" /> ) 
        values 
        <foreach collection="list" item="item" index="index" separator=",">
            (null,#{item.name},#{item.sex},#{item.address},#{item.telephone},#{item.tId})
        </foreach>
    </insert> 
    
     

    2.2、DAO类节选

    public interface SomeDAO{
    
    public void insertBatch(@Param("list")List<Student> students); 
    
     }
    
    

     

    参考:

    1、《MyBatis用户指南中文版》 译者:曾令祝 

    2、http://winhack.iteye.com/blog/1522181

    转载:MyBatis直接执行SQL查询及批量插入数据

     

     

    展开全文
  • Mybatis---- 批量操作sql语句
  • mybatis-plus Sqlsession批量执行sql语句

    千次阅读 2019-01-07 09:07:08
    正常使用mybaitis 在配置文件创建...获取Dao就可以直接用了 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 你会发现后台不会创建sqlsession了 而是用的同一个 &lt;bean class="org.mybati...
  • 批量修改时的错误信息: Caused by: java.sql.SQLException: sql injection ...由于开启了wall SQL监控 批量SQL不允许执行. 源码报错位置 multiStatementAllow为false抛出的异常 有两种解决办法: 1.关掉w...
  • 文章目录1、EmployeeMapper2、EmployeeMapper.xml(以逗号间隔执行一条语句)(推荐)3、Test4、以分号间隔执行每条语句(第二种方式)5、Oracle下的批量插入(方式一)6、Oracle下的批量插入(方式二) 1、...
  • 说到MyBatis的批量插入、修改相信很多人会说使用foreach遍历集合,然后去执行SQL语句;或者在XML中去使用foreach标签拼接SQL语句然后执行。其实这不是批量执行,而只能称之为是遍历执行。那么怎么才是批量执行呢?...
  • 如果你想在代码中获取Mybatis方法的sql,你可以使用本工具。 SqlHelper地址: SqlHelper.java 这个工具不需要你实际去执行Mybatis的查询方法就能得到sql。 程序提供的可以调用的方法如下: ...
  • batchExecutor.doUpdate(c.getMappedStatement(sql), entity); if (i++ > 0 && i % BATCH_SIZE == 0) { batchExecutor.doFlushStatements(); } } batchExecutor.doFlushStatements();
  • Mybatis 批量插入事物问题

    千次阅读 2020-01-03 09:06:52
    一、首先对于批量数据的插入有两种解决方案(下面内容只讨论和...参数,使用Mybatis批量插入 (foreach) 对于批量插入它的Mapper看起来向这样 <insert id="addUser" parameterType="java.util.List" > i...
  • MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。这篇文章主要介绍了Mybatis中动态SQL,if,where,foreach的使用教程,需要的朋友可以参考下
  • MySQL数据库 批量操作主要使用的是Mybatis的foreach,遍历参数列表执行相应的操作,所以批量插入/更新/删除的写法是类似的,只是SQL略有区别而已。MySql批量操作需要数据库连接配置allowMultiQueries=true才可以。...
  • MyBatis SQL是如何执行

    千次阅读 2020-02-03 13:54:41
    MyBatis 是第一个支持自定义 SQL、存储过程和高级映射的类持久框架。MyBatis 消除了大部分 JDBC 的样板代码、手动设置参数以及检索结果。MyBatis 能够支持简单的 XML 和注解配置规则。使 Map 接口和 POJO 类映射到...
  • mybatis-sqlserver批量新增返回id

    千次阅读 2020-06-28 16:12:50
    mybatis-SqlServer批量新增返回id遇到的问题解决思路步骤一功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、...
  • mybatis批量更新踩坑

    千次阅读 2019-06-26 23:57:36
    mybatis批量更新踩坑 说一下遇到的大坑,mybatis批量更新update语句,我们知道mysql是支持批量插入和批量删除的,因此它也是支持批量更新的,但是批量更新的方法跟批量插入删除略有不同,先简单说一下mybatis批量...
  • 这次代码框架很简单,通过spring定时任务,调用enum里的sql语句,通过c3p0连接oracle数据库,使用Mybatis运行,却产生了几个小bug ...3、多条sql批量执行时,抛出java.sql.BatchUpdateException,报“ORA-...
  • mybatis模板中的sql: 错误信息: The error occurred while setting parameters Caused by: org.springframework.jdbc.BadSqlGrammarException: 好好的sql没动过,就换了一个数据库连接,由mysql5升级到mysql...
  • 本文目录引用if 标签查询条件接口方法动态 SQL测试代码choose(when、otherwise) 标签动态 SQL测试代码where标签set 标签动态SQL...Mybatis提供了动态SQL,可以根据用户提供的参数,动态决定查询语句依赖的查询条件或
  • Mybatis批量提交

    千次阅读 2019-09-22 21:52:42
    有两种方式可以实现mybatis批量提交,第一种便是foreach标签,第二种便是开始mybatis批量模式。 一、通过foreach标签 foreach标签即是通过迭代传入的集合或者数组,进行拼接sql。 标签包含以下属性: ​ item:...
  • 如果你恰好使用 Mybatis-plus 框架,那么在开发环境就不能错过它提供的 PerformanceInterceptor 插件,该插件能打印 sql 执行时间以及完整的 sql 语句,非常方便复制出来分析 sql 使用 这里使用的 Mybatis-plus ...
  • mybatis批量update,返回行数为-1

    千次阅读 2020-07-03 10:38:48
    mybatis批量update,返回行数为-1  mybatis批量更新返回结果为-1...BATCH可以批量更新操作,缓存SQL以提高性能,缺陷就是无法获取update、delete返回的行数。 如果要拿到更新条数,修改如下: 在mybatis-config.xml配
  • 获取批量执行sql String sql = boundSql.getSql(); // 获取连接 Connection connection = null ; PreparedStatement ps = null ; List <Closeable> closeables = new LinkedList (); try { ...
  • MyBatis批量插入——常见错误

    千次阅读 2020-05-19 11:37:18
    因为test判断时都为空 ,下边语句也不会执行,因此也不可能获取到值,实际上在这里不需要做非空判断了,因为一旦有空值,就会导致前边插入列数与后边值数不匹配, insert into student(STU_NUMBER,STU_NAME,STU_SEX...
  • 说到MyBatis的批量插入、修改相信很多人会说使用foreach遍历集合,然后去执行SQL语句;或者在XML中去使用foreach标签拼接SQL语句然后执行。其实这不是批量执行,而只能称之为是遍历执行。那么怎么才是批量执行呢?...
  • mybatis批量操作的几种方式

    千次阅读 2019-04-18 19:40:52
    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java...
  • MyBatis动态SQL执行多条SQL

    千次阅读 2018-07-05 17:46:39
    有个常见的场景:删除用户...3、sql批量执行。今天我要说的是MyBatis中如何一次执行多条语句(使用mysql数据库)。1、修改数据库连接参数加上allowMultiQueries=true,如:xxoo.jdbc.url=jdbc:mysql://localhost:33...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 13,153
精华内容 5,261
关键字:

获取mybatis批量执行sql