为什么不用sql拼接呢 ?
因为sql拼接的长度是有限的 超过了就会爆
而批量处理可以理解为无数。
我就用·同一组数据的插入操作·来直观展示两者差距吧。
非批处理:
DEBUG 09-06 12:01:23,746 ==> Parameters: null, a22a4c(String), 1(String), 2(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-06 12:01:23,747 <== Updates: 1 (BaseJdbcLogger.java:159)
DEBUG 09-06 12:01:23,748 ==> Preparing: insert into teachers (id, name, gender, school_id) values (?, ?, ?, ?) (BaseJdbcLogger.java:159)
DEBUG 09-06 12:01:23,749 ==> Parameters: null, 993946(String), 1(String), 2(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-06 12:01:23,750 <== Updates: 1 (BaseJdbcLogger.java:159)
DEBUG 09-06 12:01:23,751 ==> Preparing: insert into teachers (id, name, gender, school_id) values (?, ?, ?, ?) (BaseJdbcLogger.java:159)
DEBUG 09-06 12:01:23,752 ==> Parameters: null, 189461(String), 1(String), 2(Integer) (BaseJdbcLogger.java:159)
批处理:
DEBUG 09-06 12:00:44,068 ==> Parameters: null, bda43a(String), 1(String), 2(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-06 12:00:44,069 ==> Parameters: null, 5155c3(String), 1(String), 2(Integer) (BaseJdbcLogger.java:159)
DEBUG 09-06 12:00:44,070 ==> Parameters: null, fdae74(String), 1(String), 2(Integer) (BaseJdbcLogger.java:159)
两者区别:
批量:(预编译sql一次==>设置参数===>2000次===>执行(1次)) 只预编译一次sql 然后多次传入参数,传入数据库执行一次
//Parameters: 616c1(String), b(String), 1(String)==>总时间是:总时间是:3485
非批量:(预编译sql=设置参数=执行)==》2000 总时间是:8527 每次都会编辑sql然后设置参数 然后传入数据库执行多次
那如何配置批量处理呢?
先来了解这三个:
ExecutorType.SIMPLE:这种类型的执行器没有什么特别之处。它为每个语句执行创建一个新的PreparedStatement。
ExecutorType.REUSE:这种类型的执行器将重用PreparedStatements。
ExecutorType.BATCH:如果在它们之间执行SELECT,则此执行程序将批处理所有更新语句并根据需要划分它们,以确保易于理解的行为。
配置批处理:
可以在全局变量中配置 defaultExecutorType属性 为BATCH executor是增删改查操作的主体
但是这样子增删改查都会应用这个批处理 ,就很麻烦 所以 而可以指定单个sqlSession会话为BATCH形式:
@Test
void test1() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
long start = System.currentTimeMillis();
try {
TeachersMapper teachersMapper = sqlSession.getMapper(TeachersMapper.class);
for(int i=0;i<2000;i++) {
teachersMapper.insert(new Teachers(UUID.randomUUID().toString().substring(0, 6), "1", 2));
}
sqlSession.commit();
long end = System.currentTimeMillis();
System.out.println("总时间是:"+(end-start));
}finally {
sqlSession.close();
}
}
批处理和非批处理配置区别:
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
和
SqlSession sqlSession = sqlSessionFactory.openSession();
注意:
sqlSession.commit();一定要加 不然就有问题。
问题:
Error updating database. Cause: java.sql.
SQLNonTransientConnectionException: Public Key Retrieval is
not allowed
解决方案:
在配置文件的url时追加:
allowPublicKeyRetrieval=true&useSSL=false