精华内容
下载资源
问答
  • Mybatis 批处理

    2016-10-27 10:53:12
    Mybatis 批处理 有的时候,我们需要一次性插入很多的数据或者一次性更新、删除很多的数据,那么为了提高效率,我们需要使用批处理来完成。以下将讨论Mybatis+Spring如何使用批处理。 首先应该知道...

    Mybatis 批处理


    有的时候,我们需要一次性插入很多的数据或者一次性更新、删除很多的数据,那么为了提高效率,我们需要使用批处理来完成。以下将讨论Mybatis+Spring如何使用批处理。

    首先应该知道Mybatis是Ibatis的升级版,比Ibatis性能更好,这是我采用Mybatis的原因。

    Ibatis是支持批处理的:

    1. public void batchAddExamlog(List examlogList) throws SQLException{                   
    2.     SqlMapClient smc=this.getSqlMapClient();                                           
    3.     try {                                                                              
    4.         smc.startTransaction();                                                          
    5.         smc.startBatch();                                                                                                                                                                                      
    6.         for (Iterator iter = examlogList.iterator(); iter.hasNext();) {  
    7.             Examlog log = (Examlog) iter.next();  
    8.             smc.update("insertExamlog", log);  
    9.         }                                                                              
    10.         smc.executeBatch();                                                              
    11.     }finally{                                                                          
    12.         smc.commitTransaction();                                                         
    13.         smc.endTransaction();                                                            
    14.     }                                                                                  
    15. }   


    Mybatis接口实现批处理:

    sessionFactory.openSession(ExecutorType.BATCH,true);//得到session,用于批量update


    以上两种,他们都可以实现批处理。
    但是当 Mybatis + Spring集成,且由Spring控制事务时,Mybatis这种批处理是不能使用的。
    因为sessionFactory.openSession(ExecutorTypetype);方法会创建一个新的数据库连接,该连接不受Spring控制,将导致Spring的事务控制失效,它无法利用与当前线程绑定的session。

    再看其他方式:

    1、Mybatis主配置文件中,加入下面代码:
    <configuration>
    <settings>
    <setting name="defaultExecutorType" value="BATCH"/>
    </settings>
    </configuration>
     -- 这是个总配置,所有操作都会生效,在任何一个事务中做的更改,在事务结束时提交,该事务内无法读取自己的操作结果。
     -- 它会导致所有方法 insert 无法返回id,update/delete 无法得到影响行数,所以、这个全局设置并不好。

    2、配合(1)使用SqlSessionUtils.getSqlSession(sessionFactory).commit();

     -- 虽然数据在事务内提交了,但是依然无法获得自增id

    3、mapper文件中使用foreach标签拼装语句

     -- 但是sql语句有长度限制,小数据量可以(当然也可以从数据库设置sql最长限制)。

    4、获得当前连接,使用jdbc进行批处理操作。

     -- 这也不好,sql需要写在其他地方,不能写在Mapper文件中。

    5、从Spring上下文中,实例化两个SqlSessionTemplate,一个使用批处理方式,一个不使用批处理,程序中适时而用。

     -- 无法获得自增id,且一个事务中不能同时使用两个SqlSessionTemplate。

    6、从源代码,扩展自己的批处理实现。
    1、BatchExecutor类的public List<BatchResult> doFlushStatements() throws SQLException方法最终执行批量操作,它将返回影响信息。
    2、BatchExecutor.doFlushStatements() 方法在 Executor.commit() 方法中被调用。
    3、Executor.commit() 在 SqlSession 中调用。
    4、SqlSessionFactory 负责创建 SqlSession。

    扩展SqlSessionFactory 创建我们定义的 MySqlSession,MySqlSession 最终可以调用到BatchExecutor.doFlushStatements() 获得影响结果

     -- 这种方式需要扩展源码。


    总结了几种方式,大家在项目中看情况使用吧。
    展开全文
  • MyBatis批处理

    2021-03-29 14:15:43
    所以针对于批量数据新增、删除、修改、查找的操作,mybatis提供了批处理方案 批量插入 除了可以向SQL语句中传入单一的数据类型,还可以传输一个list集合,利用foreach标签就可以循环遍历集合中的内容实现批处理,...

    批处理即批量处理。如果需要往数据库中插入大量数据时,再使用单条插入即插入一次调一次insert语句就会很浪费资源。所以针对于批量数据新增、删除、修改、查找的操作,mybatis提供了批处理方案

    批量插入

    除了可以向SQL语句中传入单一的数据类型,还可以传输一个list集合,利用foreach标签就可以循环遍历集合中的内容实现批处理,例如:

    Mapper XML:

    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO t_goods (title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
        VALUES
        <foreach collection="list" item="item" separator=",">
            (#{item.title}, #{item.subTitle}, #{item.originalCost}, #{item.currentPrice}, #{item.discount}, #{item.isFreeDelivery}, #{item.categoryId})
        </foreach>
    </insert>
    

    foreach标签的属性如下:

    • collection:传入的集合
    • item:实体
    • separator:分隔符
    • open:开始标识符
    • close:结束标识符
    • index:序号

    当批量插入数据时,可以在打印日志中看到集合中的每个实体类的数据组成一部分SQL,再由,连接,拼接为一个完整的SQL语句

    测试类:

    @Test
    public void testBatchSQL() {
        SqlSession sqlSession = null;
    
        try {
            sqlSession = MyBatisUtils.getSqlSession();
    
            // 制作一个集合
            List<Good> list = new ArrayList<>();
            for (int i = 0; i < 10; i++) {
                Good good = new Good();
    
                good.setTitle("测试数据");
                good.setSubTitle("测试数据");
                good.setOriginalCost(2000f);
                good.setCurrentPrice(3000f);
                good.setDiscount(6.66f);
                good.setIsFreeDelivery(1);
                good.setCategoryId(1);
    
                list.add(good);
            }
    
            int insert = sqlSession.insert("good.batchInsert", list);
    
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MyBatisUtils.close(sqlSession);
        }
    }
    

    在这里插入图片描述

    通过foreach标签即可将list集合中的数据组装成一条SQL提高了SQL的执行效率

    批量查询

    Mapper XML:

    <select id="batchSelect" parameterType="java.util.List" resultType="com.mybatis.entity.Good">
        SELECT * FROM t_goods WHERE category_id IN
        <foreach collection="list" item="item" open="(" close=")" separator=",">
            #{item}
        </foreach>
    </select>
    

    测试类:

    @Test
    public void testBatchSelect() {
        SqlSession sqlSession = null;
    
        try {
            sqlSession = MyBatisUtils.getSqlSession();
    
            List<Integer> list = new ArrayList<>();
            list.add(16);
            list.add(17);
            list.add(18);
    
            List<Good> result = sqlSession.selectList("good.batchSelect", list);
    
            for (Good good : result)
                System.out.println(result);
    
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            MyBatisUtils.close(sqlSession);
        }
    }
    
    

    使用open和close属性可以设置开始的字符和结束字符,最后拼接的语句为:
    在这里插入图片描述

    批量更新与删除类似

    展开全文
  • mybatis批处理

    2020-02-20 18:47:35
    批量查询 方法一、(推介) dao接口: List<UBaseMenu> findMenuName(List<String> valueList); ...select id="findMenuName" resultType="java.lang.String" parameterType="java.util.List">...

    批量查询

    方法一、(推介)

    dao接口:

    	List<UBaseMenu> findMenuName(List<String> valueList);
    

    xml:

    <select id="findMenuName" resultType="java.lang.String" parameterType="java.util.List">
    	select menu_name
    	from menu
    	where menu_id in
    	<foreach collection="list" item="valueList" open="(" close=")" separator=",">
    		#{valueList}
    	</foreach>
    </select>
    

    方法二、

    dao接口:

    	List<ReturnCodeEntity> selectByIds(@Param("ids") List<Long> ids);
    

    xml:

    <select id="selectByIds" parameterType="java.util.List"
                resultType="com.paic.ocss.gateway.model.entity.ReturnCodeEntity">
            SELECT  id,  code,  message,   recommendation,status
            FROM openapi_return_code
            WHERE id in
            <trim prefix="(" suffix=")">
                <foreach collection="ids" index="index" item="id" separator=",">
                    #{id}
                </foreach>
            </trim>
        </select> 
    

    方法三、

    dao接口:

    	public List<User> findUserListByIdList(List<Long> idList); 
    

    xml:

    <select id="findUserListByIdList" parameterType="java.util.ArrayList" resultType="User">    
        select * from user user    
        <where>    
            user.ID in (    
              <foreach collection="list"  item="id" index="index" separator=",">   
                 #{id}   
              </foreach>    
            )    
        </where>    
    </select>
    

    批量插入

    dao:

    	int addResource(List<Resource> ResourceList);
    

    xml:

    <insert id="addResource" parameterType="java.util.List">
    	insert into resource (object_id, res_id, res_detail_value, res_detail_name)
    	values
    	<foreach collection="list" item=" ResourceList " index="index" separator=",">
    		(#{ResourceList.objectId,jdbcType=VARCHAR},
    		#{ResourceList.resId,jdbcType=VARCHAR},
    		#{ResourceList.resDetailValue,jdbcType=VARCHAR},
    		#{ResourceList.resDetailName,jdbcType=VARCHAR}
    		)
    	</foreach>
    </insert>
    

    批量修改

    dao:

    	int updateRoles(List<String> roleList);
    

    xml:

    <update id="updateRoles" parameterType="java.util.List">
    	update role
    	set enabled = '0'
    	where role_id in
    	<foreach collection="list" item="roleIds" index="index" open="(" separator="," close=")"> 
    		#{roleIds} 
    	</foreach>
    </update>
    

    批量删除

    方法一、

    dao:

    	int deleteByLogic(List<Integer> listId);
    

    xml:

    
    <delete  id="deleteByLogic"  parameterType = "java.util.List">
         delete from user where 1>2
             or id in
          <foreach collection="list"  item="item" open="(" separator="," close=")"  >
               #{item}
          </foreach>
    </delete>
    
    

    方法二、

    dao:

    	int deleteByLogic(Integer[] array);
    

    xml:

    
    <delete  id="deleteByLogic"  parameterType = "Integer[]">
         delete from user where 1>2
             or id in
          <foreach collection="array"  item="item" open="(" separator="," close=")"  >
               #{item}
          </foreach>
    </delete>
    
    
    展开全文
  • mybatis批处理
            // 获取sqlSession工厂,sqlSessionFactory是配置文件中配置的数据库连接bean
            SqlSessionFactory sqlSessionFactory = SpringContextHolder.getBean("sqlSessionFactory");
            // 获取批处理数据源,false表示手动提交事务
            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            try {
                // 获取需要批处理的mapper
                FundFlowDAO fundFlowDAO = sqlSession.getMapper(FundFlowDAO.class);
                // 批量处理集合
                fundFlowDAO.batchInsertFundFlow(insertFundFlowList);
                sqlSession.commit();
            } catch (Throwable e) {
                LogUtil.error(logger, e.toString());
                sqlSession.rollback();
            } finally {
                if (sqlSession != null) {
                    sqlSession.close();
                }
                LogUtil.info(logger, "endTime===" + (System.currentTimeMillis() - startTime) / 1000);
            }
    
    /**
     * hongshiwl.com Inc.
     * Copyright (c) 2015-2016 All Rights Reserved.
     */
    package com.opengroup.hongshi.wccy.util;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    
    
    /**
     * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext. 
     * @author sandy
     * @version $Id: SpringContextHolder.java, v 0.1 2016年4月28日 下午2:21:27 sandy Exp $
     */
    public class SpringContextHolder implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        /** 
        * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量. 
        */
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) {
            SpringContextHolder.applicationContext = applicationContext;
        }
    
        /** 
        * 取得存储在静态变量中的ApplicationContext. 
        */
        public static ApplicationContext getApplicationContext() {
            checkApplicationContext();
            return applicationContext;
        }
    
        /** 
        * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 
        */
        @SuppressWarnings("unchecked")
        public static <T> T getBean(String name) {
            checkApplicationContext();
            return (T) getApplicationContext().getBean(name);
        }
    
        /** 
        * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. 
        */
        @SuppressWarnings("unchecked")
        public static <T> T getBean(Class<T> clazz) {
            checkApplicationContext();
            return (T) getApplicationContext().getBeansOfType(clazz);
        }
    
        /** 
        * 清除applicationContext静态变量. 
        */
        public static void cleanApplicationContext() {
            applicationContext = null;
        }
    
        private static void checkApplicationContext() {
            if (applicationContext == null) {
                throw new IllegalStateException(
                    "applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
            }
        }
    }
    
    展开全文
  • Mybatis 批处理报 BadSqlGrammarException

    万次阅读 2021-08-15 08:40:00
    mybatis会抛出异常,即不允许多条语句同时执行。 解决办法 &allowMultiQueries=true 完整参数设置,支持批处理 spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&...
  • mybatis批处理数据

    2019-06-09 21:01:00
    1.传统jdbc处理 2.mybatis批处理插入 3.使用executortype处理 jdbc 处理 1.通过 for循环插入 main方法如下所示: Connection comm=null; PreparedStatement preparedStatement=null; conn=JdbcUtil...
  • Mybatis批处理

    2015-04-02 12:38:40
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--批量插入--> SELECT LAST_INSERT_ID() insert into user(name,password) values ," > ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,139
精华内容 2,455
关键字:

mybatis批处理