IBatis和MyBatis的差别还是挺大的,但是变化的类通常还有对应的类型和方法,过渡时改变的只是类型,但是对于批量处理这一块的变化却是非常大的,很多API直接废弃,也没有新的API对应,导致IBatis升级到MyBatis在批量处理上的代码修改力度很大。
先来看看JDBC批量数据处理的套路,首先我们可以看看数据库是否支持批量更新这种操作:
DatabaseMetaData.supportsBatchUpdates(),当然在使用批量操作的时候肯定已经确定使用的数据库是支持的。一般来说,我们的流程是这样的:
Statement stmt = conn.createStatement();
conn.setAutoCommit(false);
String sql = "insert into book(id, name, price)" + "values (1,'Java编程思想',100)";
stmt.addBatch(sql);
sql = "insert into book(id, name, price)" + "values (1,'高等数学',68)";
stmt.addBatch(sql);
int[] rows = stmt.executeBatch();
conn.commit();
stmt.close();
conn.close();
这里的写法是简单示意,未必能用于生产。这里可以看到,批处理是以事务方式进行处理的。下面来看看IBatis是如何进行批量数据处理的,与JDBC不同,IBatis对事物的操作有这么几个API:
void startTransaction() throws SQLException;
void startTransaction(int var1) throws SQLException;
void commitTransaction() throws SQLException;
void endTransaction() throws SQLException;
这个和JDBC接口略有差别,但是完全可以理解,其中endTransaction()是用来cleanup的,只需记住你必须在调用startTransaciton()后合适时机调用endTransaction(),他们的命名也很对称,再来看看IBatis对批量数据处理提供的API:
void startBatch() throws SQLException;
int executeBatch() throws SQLException;
List executeBatchDetailed() throws SQLException, BatchException;
public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException;
executeBatchDetailed()是executeBatch()的增强版,建议使用executeBatchDetailed()。下面的execute()是一个回调方式的执行,你可以将批处理的代码封装进去,以回调方式编写体现的是面向对象编程的思想,让后续维护更优雅。
MyBatis中,批量处理的方式是指定一个批处理类型的SqlSession:
SqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
这几个方法都能指定ExecutorType,
ExecutorType.SIMPLE:这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。
ExecutorType.REUSE:这个执行器类型会复用预处理语句。
ExecutorType.BATCH:这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行,必要时请把它们区分开来以保证行为的易读性。ExecutorType.BATCH就是我们要的,