SpringBoot+myBatisPlus+sharding-jdbc数据源分页查询类型
转换问题
在实际项⽬中涉及到多数据源和分表,所以采⽤了shardingsphere,为了简化代码,引⼊了mybatis plus
版本:
mybatis plus:3.3.2
springboot:2.1.5
shardingsphere : 4.0.0-RC2
错误信息:
Caused by: batis.spring.MyBatisSystemException: nested exception is org.ptions.PersistenceException:
### Error querying database. Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
### The error may exist in com/cxm/db/mapper/bi/CxmBiDemoDAO.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT id,increased_stall_count FROM cxm_bi_demo LIMIT ?,?
### Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
batis.anslateExceptionIfPossible(MyBatisExceptionTranslator.java:92)
batis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
at com.sun.proxy.$Proxy150.selectList(Unknown Source)
batis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)
at uteForIPage(MybatisMappe
rMethod.java:134)
at ute(MybatisMapperMethod.java:96)
at verride.MybatisMapperProxy.invoke(MybatisMapperProxy.java:96)
at com.sun.proxy.$Proxy157.selectPage(Unknown Source)
service.CxmBaseServiceImpl.page(CxmBaseServiceImpl.java:292)
service.CxmBaseServiceImpl.page(CxmBaseServiceImpl.java:307)
service.CxmBaseServiceImpl$$FastClassBySpringCGLIB$$5d9c5448.invoke(<generated>)
at lib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:684)
service.impl.CxmBiDemoServiceImpl$$EnhancerBySpringCGLIB$$e0e43073.page(<generated>)
service.impl.CxmBiDailyIncreasedStatisticServiceImpl.queryIn(CxmBiDailyIncreasedStatisticServiceImpl.java:86)
service.impl.CxmBiDailyIncreasedStatisticServiceImpl$$FastClassBySpringCGLIB$$588bac5b.invoke(<generated>)
at lib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
service.impl.CxmBiDailyIncreasedStatisticServiceImpl$$EnhancerBySpringCGLIB$$bbed46d4.queryIn(<generated>)
CxmRetailApplication.run(CxmRetailApplication.java:68)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:813)
... 5 common frames omitted
Caused by: org.ptions.PersistenceException:
### Error querying database. Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
### The error may exist in com/cxm/db/mapper/bi/CxmBiDemoDAO.java (best guess)
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: SELECT id,increased_stall_count FROM cxm_bi_demo LIMIT ?,?
### Cause: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
springboot aopat org.ptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:149)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
flect.NativeMethodAccessorImpl.invoke0(Native Method)
flect.NativeMethodAccessorImpl.invoke0(Native Method)
flect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at flect.Method.invoke(Method.java:498)
batis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
... 32 common frames omitted
Caused by: java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
at org.ptimize.sharding.segment.select.Value(Pagination.java:60)
at org.ptimize.sharding.segment.select.pagination.Pagination.<init>(Pagination.java:54)
at org.ptimize.sharding.segment.atePagination(LimitPaginationEngine.java:40) at org.ptimize.sharding.segment.atePagination(PaginationEngine.java:50)
at org.ie.dml.ShardingSelectOptimizeEngine.optimize(ShardingSelectOptimizeEngine.java:63)
at org.ie.dml.ShardingSelectOptimizeEngine.optimize(ShardingSelectOptimizeEngine.java:47)
at org.uter.ute(ParsingSQLRouter.java:72)
at org.ute(PreparedStatementRoutingEngine.java:66)
at org.ute(PreparedQueryShardingEngine.java:60)
at org.uteRoute(BaseShardingEngine.java:86)
at org.BaseShardingEngine.shard(BaseShardingEngine.java:70)
at org.apache.shardingsphere.statement.ShardingPreparedStatement.shard(ShardingPreparedStatement.java:224)
at org.apache.shardingsphere.ute(ShardingPreparedStatement.java:170)
flect.NativeMethodAccessorImpl.invoke0(Native Method)
flect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at flect.Method.invoke(Method.java:498)
at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:59)
at com.sun.proxy.$ute(Unknown Source)
at org.utor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)
at org.utor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)
flect.NativeMethodAccessorImpl.invoke0(Native Method)
flect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
flect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at flect.Method.invoke(Method.java:498)
at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)
at com.sun.proxy.$Proxy226.query(Unknown Source)
at utor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:67)
at org.utor.BaseExecutor.queryFromDatabase(BaseExecutor.java:324)
at org.utor.BaseExecutor.query(BaseExecutor.java:156)
at utor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:163)
at utor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:90)
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
... 38 common frames omitted
问题分析:
追踪⽇志,查看源码发现是由于shardingsphere的Pagination中有⼀个类型转换直接写死为int类型导致的,
因为分页参数⾥⾯穿的值是Long的类型,⽽下⾯这个⽅法直接强制转换为int,所以导致出错
private int getValue(final PaginationValueSegment paginationValueSegment, final List<Object> parameters) {
return paginationValueSegment instanceof ParameterMarkerPaginationValueSegment
(int) (((ParameterMarkerPaginationValueSegment) paginationValueSegment).getParameterIndex())
: ((NumberLiteralPaginationValueSegment) paginationValueSegment).getValue();
}
因为mybatisplus的分页对象IPage⾥⾯的属性是long
解决⽅案:
1:⾃定义实现adata.IPage;,
将 private long size;private long current; 修改为int 类型可以修复这个问题,但没有进⾏覆盖测试,不知道是否会引起其他问题2:重新shardingsphere的Pagination
3:弃⽤shardingsphere-core,分库分表采⽤阿⾥云的组建,多数据源采⽤AbstractRoutingDataSource⾃定义注解实现
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论