如何使用MyBatis / Spring实现批处理操作?

我想知道如何使用MyBatis 3和Spring 3使用insert语句实现批处理操作?

例如,以下是目前正在进行的操作:

spring.xml:

   ${context.factory}                   

MyService.xml:

  insert into ... // code removed  

MyService.java:

 public interface MyService { public void insertMyRecord (MyRecord); } 

MyController.java:

 @Controller public class MyController { @Autowired private MyService myService; @Transactional @RequestMapping( .... ) public void bulkUpload (@RequestBody List myRecords) { for (MyRecord record : myRecords) { myService.insertMyRecord(record); } } } 

免责声明:这只是用于演示目的的伪代码

那么我该怎么做才能把它变成一个批处理过程呢?

理想情况下,我希望能够以最少的“入侵”代码进行,即使用注释更优先,但如果不可能,那么下一个最好的东西是什么?

此外,这需要仅针对此一项服务进行配置,而不是针对项目中的所有内容进行配置。

这是运行和测试的示例…使用批处理更新多行(ibatis + java)

在这个前。 我正在更新参加桌子的人数和派对。

 public static int updateBatch(List attendingUsrList) { SqlSession session = ConnectionBuilderAction.getSqlSession(); PartyDao partyDao = session.getMapper(PartyDao.class); try { if (attendingUsrList.size() > 0) { partyDao.updateAttendingCountForParties(attendingUsrList); } session.commit(); } catch (Throwable t) { session.rollback(); logger.error("Exception occurred during updateBatch : ", t); throw new PersistenceException(t); } finally { session.close(); } } 

定义变量的模型类:

 public class MyModel { private long attending_count; private String eid; public String getEid() { return eid; } public void setEid(String eid) { this.eid = eid; } public long getAttending_count() { return attending_count; } public void setAttending_count(long attending_count) { this.attending_count = attending_count; } } 

party.xml代码

批处理执行的实际查询

  UPDATE parties SET attending_user_count = #{model.attending_count} WHERE fb_party_id = #{model.eid}  

接口代码在这里

 public interface PartyDao { int updateAttendingCountForParties (@Param("attendingUsrList") ListattendingUsrList); } 

这是我的批处理会话代码

 public static synchronized SqlSession getSqlBatchSession() { ConnectionBuilderAction connection = new ConnectionBuilderAction(); sf = connection.getConnection(); SqlSession session = sf.openSession(ExecutorType.BATCH); return session; } SqlSession session = ConnectionBuilderAction.getSqlSession(); 

上面接受的答案实际上并没有为MyBatis提供批处理模式。 您需要通过ExecutorType.BATCH选择正确的Executor。 这可以作为参数传递给标准MyBatis API中的SqlSession.openSession,或者,如果使用MyBatis-Spring,则作为SqlSessionTemplate的选项传递。 通过以下方式完成:

     

没有别的事情需要做。

我不确定我完全理解这个问题,但我会尽力给你我的想法。

为了制作单一服务,我建议生成服务接口:

 public void bulkUpload (@RequestBody List myRecords) 

然后,您可以检查对象的类型并调用propper映射器存储库。

然后,您可以通过创建一个通用界面来更多地进一步通用:

 public interface Creator { void create(T object); } 

并通过mapper接口扩展它:

 public interface MyService extends Creator{} 

现在最复杂的一步是:获取特定类型的对象,查看确切的mapper实现此类的Creator接口(使用javareflectionAPI)并调用特定方法。

现在我给你在我的一个项目中使用的代码:

 package com.mydomain.repository; //imports ... import org.reflections.Reflections; @Repository(value = "dao") public class MyBatisDao { private static final Reflections REFLECTIONS = new Reflections("com.mydomain"); @Autowired public SqlSessionManager sqlSessionManager; public void create(Object o) { Creator creator = getSpecialMapper(Creator.class, o); creator.create(o); } // other CRUD methods @SuppressWarnings("unchecked") private  T getSpecialMapper(Class specialClass, Object parameterObject) { Class parameterClass = parameterObject.getClass(); Class mapperClass = getSubInterfaceParametrizedWith(specialClass, parameterClass); return sqlSessionManager.getMapper(mapperClass); } private static  Class getSubInterfaceParametrizedWith(Class superInterface, Class

parameterType) { Set> subInterfaces = REFLECTIONS.getSubTypesOf(superInterface); for (Class subInterface: subInterfaces) { for (Type genericInterface : subInterface.getGenericInterfaces()) { if (!(genericInterface instanceof ParameterizedType)) continue; ParameterizedType parameterizedType = (ParameterizedType) genericInterface; Type rawType = parameterizedType.getRawType(); if (rawType instanceof Class && ((Class) rawType).isAssignableFrom(superInterface)) { for (Type type: parameterizedType.getActualTypeArguments()) { if (type instanceof Class && ((Class) type).isAssignableFrom(parameterType)) { return subInterface; } } } } } throw new IllegalStateException(String.format("No extension of %s found for parametrized type %s ", superInterface, parameterType)); } }

警告! 此方法可能会对性能产生不良影响,因此请将其用于非性能关键操作

如果你想要批量插入,我建议使用mybatis foreach进行批量插入,如下所述。

如果您认为不想为每种类型的对象编写sql,最好使用Hibernate或任何其他高级ORM。 MyBatis只是一个SQL映射接口。