springboot之使⽤通⽤Mapper批量添加数据
通⽤Mapper是⼀款针对mybatis进⾏扩展的轻量级组件,使⽤起来⾮常⽅便。当调⽤其针对mysql进⾏批量添加数据的⽅法时,发现报错,仔细研究了⼀番,发现是在使⽤通⽤
Mapper上出现了问题。下⾯贴出本⽂使⽤的通⽤的Mapper github 地址及其版本。
继承通⽤Mapper的DAO层⽰例代码:
package light.sbex;
batis.mappermon.Mapper;
batis.mappermon.MySqlMapper;
public interface TEntityDAO extends Mapper<TEntityDO>,MySqlMapper<TEntityDO>{
}
批量添加数据的⽰例代码:
package light.sbex;
import java.util.ArrayList;
import java.util.List;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import t.ApplicationContext;
@SpringBootApplication
public class Example3Main {
public static void main(String[] args) {
ApplicationContext ctx=SpringApplication.run(Example3Main.class, args);
System.out.println("");
List<TEntityDO> tEntityDOList=new ArrayList<TEntityDO>(10);
tEntityDOList.add(new TEntityDO("1"));
tEntityDOList.add(new TEntityDO("2"));
tEntityDOList.add(new TEntityDO("3"));
tEntityDOList.add(new TEntityDO("4"));
tEntityDOList.add(new TEntityDO("5"));
tEntityDOList.add(new TEntityDO("6"));
tEntityDOList.add(new TEntityDO("7"));
tEntityDOList.add(new TEntityDO("8"));
tEntityDOList.add(new TEntityDO("9"));
tEntityDOList.add(new TEntityDO("10"));
TEntityDAO Bean(TEntityDAO.class);
tEntityDAO.insertList(tEntityDOList);
}
}
运⾏程序后,出现如下错误:
Exception in thread "main" batis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.SpecialProvider.dynamicSQL).  Cause: java    batis.anslateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
batis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy62.insert(Unknown Source)
batis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:278)
at org.apache.ibatis.ute(MapperMethod.java:57)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy63.insertList(Unknown Source)
at light.sbex.Example3Main.main(Example3Main.java:33)
Caused by: org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.SpecialProvider.dynamicSQL).  Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.SpecialProvider
at org.apache.ibatis.builder.ateSqlSource(ProviderSqlSource.java:103)
at org.apache.ibatis.builder.BoundSql(ProviderSqlSource.java:73)
at org.apache.ibatis.BoundSql(MappedStatement.java:292)
at org.utor.statement.BaseStatementHandler.<init>(BaseStatementHandler.java:64)
at org.utor.statement.PreparedStatementHandler.<init>(PreparedStatementHandler.java:40)
at org.utor.statement.RoutingStatementHandler.<init>(RoutingStatementHandler.java:46)
at org.apache.ibatis.wStatementHandler(Configuration.java:545)
at org.utor.SimpleExecutor.doUpdate(SimpleExecutor.java:48)
at org.utor.BaseExecutor.update(BaseExecutor.java:117)
at org.utor.CachingExecutor.update(CachingExecutor.java:76)
springboot是啥at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:198)
at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:185)
flect.NativeMethodAccessorImpl.invoke0(Native Method)
flect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at flect.Method.invoke(Method.java:606)
batis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:433)
... 6 more
Caused by: java.lang.InstantiationException: tk.mybatis.mapper.provider.SpecialProvider
at java.wInstance(Class.java:364)
at org.apache.ibatis.builder.ateSqlSource(ProviderSqlSource.java:85)
... 22 more
当出现该错误之后,随⼿在⽹上搜索了⼀把,看看别⼈是怎么解决的。到如下⼀篇⽂章(⽂章的链接如下⽂),⾮常遗憾该⽂章也没有给出更加实际的解决办法。
  我把⽬光停留在了⽤于访问数据库的DAO层 TEntityDAO 类上⾯,该接⼝继承了Mapper和MySqlMapper 两个接⼝,这两个接⼝有啥区别呢?带着这个疑问,我进⼊到这两
个接⼝。细看了两个接⼝之后,发现Mapper只是提供普通的CRUD,⽽批量添加数据接⼝在后者。两者区别在这⼉。下⾯贴出这两个接⼝的截图。
                    通⽤Mapper接⼝
                  批量添加接⼝
看到这两个接⼝的区别,回想到通⽤Mpper配置,配置扫描时时只添加了通⽤Mapper接⼝,tk.mybatis.mappermon.Mapper ,是不是也要把批量添加的接⼝也要添加到接⼝扫描配置⾥⾯。
通⽤接⼝扫描代码:
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
Properties properties=new Properties();
properties.put("mappers","tk.mybatis.mappermon.Mapper");
MapperScannerConfigurer msc=new MapperScannerConfigurer();
msc.setBasePackage(DataSourceConfig.PACKAGE);
msc.setSqlSessionFactoryBeanName(DataSourceConfig.SESSION_FACTORY_BEAN_NAME);
return msc;
}
修改后的通⽤接⼝扫描代码:
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
Properties properties=new Properties();
properties.put("mappers","tk.mybatis.mappermon.batis.mappermon.MySqlMapper");
MapperScannerConfigurer msc=new MapperScannerConfigurer();
msc.setBasePackage(DataSourceConfig.PACKAGE);
msc.setSqlSessionFactoryBeanName(DataSourceConfig.SESSION_FACTORY_BEAN_NAME);
return msc;
}
重新运⾏程序后,还真是这⼉的原因。
总结:通⽤Mapper基本的CRUD⽅法和批量操作数据库的⽅法不是放在⼀起,需要由程序按需加载。
⽰例代码已经上传到github,代码中没有数据库相关的配置,运⾏代码之前,需要把数据库相关的配置补上。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。