mybatis 更新时为什么返回值是-1

mybatis 更新时为什么返回值是-1

原因

返回-1,是由于defaultExecutorType的引起的,defaultExecutorType有三个执行器SIMPLE、REUSE和BATCH。

默认情况下,mybatis 的 update 操作返回值是记录的 matched 的条数,并不是影响的记录条数。将 MyBatis 中的 executorType 修改成 BATCH 【批量模式】后,会让更新结果 返回值变成 -1

解决

在 Spring 配置文件中,做如下修改


    
    


// BATCH 改为 SIMPLE

其中BATCH可以批量更新操作缓存SQL以提高性能,但是有个缺陷就是无法获取update、delete返回的行数

分析

默认情况下,mybatis 的 update 操作返回值是记录的 matched 的条数,并不是影响的记录条数。

mybatis 仅仅只是返回的数据库连接驱动(通常是 JDBC )的返回值,也就是说,驱动告知更新 2 条记录受影响。

通过对 JDBC URL 显式的指定 useAffectedRows 选项,我们将可以得到受影响的记录的条数:

jdbc:mysql://${jdbc.host}/${jdbc.db}?useAffectedRows=true

MyBatis 插入模式:ExecutorType

Mybatis 内置的 ExecutorType 有3种

  1. simple [默认],
  2. batch
  3. Reuse

SimpleExecutor - 该模式下每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。(可以是Statement或PrepareStatement对象)

BatchExecutor - 执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理的;BatchExecutor相当于维护了多个桶,每个桶里都装了很多属于自己的SQL,就像苹果蓝里装了很多苹果,番茄蓝里装了很多番茄,最后,再统一倒进仓库。(可以是Statement或PrepareStatement对象)

ReuseExcutor - 执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。(可以是Statement或PrepareStatement对象)

批量插入

配置

Spring 配置文件中

applicationContext.xml



   
   

SpringMVC Test 插入多条数据

package com.uj.crud.test;

import java.util.UUID;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.uj.crud.bean.Employee;
import com.uj.crud.dao.EmployeeMapper;

/**
 * 批量插入 测试
 */

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class MapperTest {
	
	@Autowired
	EmployeeMapper employeeMapper;
	
	@Autowired
	SqlSession sqlSession;
 
	@Test
	public void testCRUD(){
		EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
		for(int i = 0;i<1000;i++){
			String uid = UUID.randomUUID().toString().substring(0,5)+i;
			mapper.insertSelective(new Employee(null,uid, "M", uid+"@qq.com", 1));
		}
	}
}

问题:

  1. 在Insert操作时,在事务没有提交之前,没有办法获取到自增的id;

参考

MyBatis 学习笔记(七)批量插入ExecutorType.BATCH效率对比

Mybatis深入剖析 -Executor分析

Mybatis Update操作返回值问题

你可能感兴趣的:(SSM)