使⽤shardingsphere对SQLServer坑的解决
背景:最近⼀个使⽤SQLServer的项⽬,业务量太⼤,开始对业务有影响了,因此⽤户要求升级改造,技术上采⽤shardingsphere进⾏分库分表。
经过⼀系列调研,设计。。。哐哐⼀顿操作之后开始动⼑改造。pom依赖如下:
<!--sharding-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
改造后查询和写⼊都各种报错:
Caused by: org.pe.TypeException: Error setting non null for parameter #2 with JdbcType NVARCHAR . Try setting a different JdbcType for this parameter or a different configuration property. Cause: java.sql.SQLFeatureNotSupportedException: setNString
at org.pe.BaseTypeHandler.setParameter(BaseTypeHandler.java:75)
at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:87)
... 47 common frames omitted
Caused by: java.sql.SQLFeatureNotSupportedException: setNString
at org.apache.shardingsphere.shardingjdbc.jdbc.unsupported.AbstractUnsupportedOperationPreparedStatement.setNString(AbstractUnsupportedOperationPreparedStatement.java:57)    at org.pe.NStringTypeHandler.setNonNullParameter(NStringTypeHandler.java:31)
at org.pe.NStringTypeHandler.setNonNullParameter(NStringTypeHandler.java:26)
at org.pe.BaseTypeHandler.setParameter(BaseTypeHandler.java:73)
... 48 common frames omitted
核⼼错误:Caused by: java.sql.SQLFeatureNotSupportedException: setNString
问题分析:
⽹上寻了千百度,蓦然回⾸,还是没有到问题,(┭┮﹏┭┮)最后debug断点跟了源码发现:
操作数据库的PreparedStatement 是ShardingPreparedStatement
然后setNString⽀持SQLServerPreparedStatement 不⽀持ShardingPreparedStatement(改造前没问题,改造后出问题的原因)
问题解决:
到问题了,下⾯就是解决问题了,既然没有setNString的实现,那就实现⼀个呗;
第⼀步实现NVarcharTypeHandler:
package batis;
import org.pe.BaseTypeHandler;
import org.pe.JdbcType;
import org.pe.MappedJdbcTypes;
import org.pe.TypeException;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/
**
*  将 nvarchar 转成 varchar  sharingJDBC不⽀持nvarchar
*  主要是NStringTypeHandler中,没有setNString()
*/
@MappedJdbcTypes(JdbcType.NVARCHAR)
public class NVarcharTypeHandler extends BaseTypeHandler<String> {
@Override
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
if(parameter == null) {
if(jdbcType == null) {
throw new TypeException("JDBC requires that the JdbcType must be specified for all nullable parameters.");
}
try {
ps.setNull(i, jdbcType.TYPE_CODE);
} catch (SQLException var7) {
throw new TypeException("Error setting null for parameter #" + i + " with JdbcType " + jdbcType + " . " + "Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. " + "Cause: " + var7, var7);            }
} else {
try {
this.setNonNullParameter(ps, i, parameter, jdbcType);
} catch (Exception var6) {
throw new TypeException("Error setting non null for parameter #" + i + " with JdbcType " + jdbcType + " . " + "Try setting a different JdbcType for this parameter or a different configuration property. " + "Cause: " + var6, var6);
}
}
}
/**
* 这⾥使⽤setNString⽽不是setString
* @param ps
* @param i
* @param parameter
* @param jdbcType
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter);
}
@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
String(columnName);
}
@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String(columnIndex);
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String(columnIndex);
}
}
第⼆步实现加⼊数据库配置:
由于我是代理实现的数据库,所有在代码中加⼊即可
@Configuration
public class DataSourceConfig {
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory memberDb1SqlSessionFactory(DataSource dataSource)
throws Exception {
SqlSessionFactoryBean bean = getSqlSessionFactoryBean(dataSource);
bean.setTypeHandlers(new TypeHandler[] {new NVarcharTypeHandler()});
Object();
}
// ******* 其他实现
}
PS:如果是配置只修要在l中配置⼀下
<typeHandlers>
java连接sqlserver数据库
<typeHandler handler="batis.NVarcharTypeHandler"/>
</typeHandlers>
配置完成后,测试以前功能全部正常(#^.^#)
如果嫌⿇烦,有另外⼀种解决⽅案:将l中的NVARCHAR替换从VARCHAR也可以哦
到此这篇关于使⽤shardingsphere对SQLServer坑的解决的⽂章就介绍到这了,更多相关shardingsphere SQLServer内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!

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