使用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.apache.ibatis.type.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.apache.ibatis.type.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.apache.ibatis.type.NStringTypeHandler.setNonNullParameter(NStringTypeHandler.java:31)
    at org.apache.ibatis.type.NStringTypeHandler.setNonNullParameter(NStringTypeHandler.java:26)
    at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:73)
    ... 48 common frames omitted

核心错误:Caused by: java.sql.SQLFeatureNotSupportedException: setNString

问题分析:

网上寻了千百度,蓦然回首,还是没有找到问题,(┭┮﹏┭┮)  最后debug断点跟了源码发现:

操作数据库的PreparedStatement 是ShardingPreparedStatement

然后setNString支持SQLServerPreparedStatement 不支持ShardingPreparedStatement(改造前没问题,改造后出问题的原因)

问题解决:

找到问题了,下面就是解决问题了,既然没有setNString的实现,那就实现一个呗;

第一步 实现NVarcharTypeHandler:

package cn.preserve.config.mybatis;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.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 {
        return rs.getString(columnName);
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return rs.getString(columnIndex);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return cs.getString(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()});
        return bean.getObject();
    }

   // ******* 其他实现
}

PS:如果是配置只修要在mybatis-config.xml中配置一下

<typeHandlers>
	<typeHandler handler="cn.preserve.config.mybatis.NVarcharTypeHandler"/>
</typeHandlers>

配置完成后,测试以前功能全部正常(#^.^#)

如果嫌麻烦,有另外一种解决方案:将mapper.xml中的NVARCHAR替换从VARCHAR也可以哦

到此这篇关于使用shardingsphere对SQLServer坑的解决的文章就介绍到这了,更多相关shardingsphere SQLServer内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 使用shardingsphere对SQLServer坑的解决

    背景:最近一个使用SQLServer的项目,业务量太大,开始对业务有影响了,因此用户要求升级改造,技术上采用shardingsphere进行分库分表. 经过一系列调研,设计...哐哐一顿操作之后开始动刀改造.pom依赖如下: <!--sharding--> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-

  • SqlServer中如何解决session阻塞问题

    简介 对于数据库运维人员来说创建session或者查询时产生问题是常规情况,下面介绍一种很有效且不借助第三方工具的方式来解决类似问题. 最近开始接触运维工作,所以自己总结一些方案便于不懂数据库的同事解决一些不太紧要的数据库问题.类似方法很多理论也很多,我就不做深究,就是简单写一个方案,便于菜鸟使用的. 阻塞理解 在Sql Server 中当一个数据库会话中的事务正锁定一个或多个其他会话事务想要读取或修改的资源时,会产生阻塞(Blocking).通常短时间的阻塞没有问题,且是较忙的应用程序所需要的

  • Android 弹出软键盘所遇到的坑及解决方法

    demo下载 重要代码: //1.此layout作为最外层的layout: //2.设置需要调整的view: setAdjustView(View view); //3.如果需要控制输入框的显示与隐藏,可以实现OnInputViewVisibleListener接口: public class SoftInputAdjustLayout extends RelativeLayout { private static final String TAG = SoftInputAdjustLayout

  • MySQL5.7中的sql_mode默认值带来的坑及解决方法

    在正常项目开发过程中,如果MySQL版本从5.6升级到5.7版本.作为DBA在考虑数据库版本升级带来的影响时,一般会有几个注意点: sql_mode optimizer_switch 本文主要内容是MySQL升级到5.7版本之后,由于默认的 sql_mode 值带来的坑以及对应的解决方案. 案例一:ONLY_FULL_GROUP_BY 问题描述 MySQL版本从5.6升级至5.7之后,部分SQL执行报错,报错信息如下: ERROR 1055 (42000): Expression #3 of X

  • 浅谈vue引入css,less遇到的坑和解决方法

    在使用vux开发手机页面时,引入vux的公共样式less一直报错,通过各种百度,Google都没有解决,走了很多弯路.最后才发现钻牛角尖了,可以换一种方法引入. 1.报错的使用:在App中 @ ./~/css-loader?{"minimize":false,"sourceMap":false}!./~/vux/src/styles/reset. less 3:10-115 @ ./~/css-loader?{"minimize":false,&

  • 基于IOS端微信分享失效的踩坑及解决方法

    最近的一个公众号是基于vue的spa应用,在接入微信分享和微信语音的时候出现了:在Android上一切正常,但是在ios端调用wx.config的时候总是失败,去翻了官方文档也并没有找到解决方案,最后在测试中发现是因为初始化的时候传入的URL的问题.具体过程如下: 微信config接口配置,官方文档如下: 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支

  • ant-design-vue按需加载的坑的解决

    问题 在vue-cli4.x中按需加载ant-design-vue,在编译时报错,错误如下 原因 ant-design-vue使用less预处理器.在less3.0版本以前,javascriptEnabled属性默认为true,3.0以后默认为false.地址 目前项目中less版本为3.0.4,所以在编译中会报错 解决办法 第一种办法,在vue.config.js中添加如下配置 css: { loaderOptions: { less: { javascriptEnabled: true }

  • pip安装tensorflow的坑的解决

    在我看来学习不难,配置一些环境真的很痛苦,之前的caffe配置,一口老血.. 不过用Python遇到了pip安装,真的赞,可是在用pip装tensorflow,竟然抛错?????黑脸.. 一.一开始中途报错,可能是网问题,所以报times out(猜测) 后来发现可能是pip命令不对 我是cpu,应该选2,之前写的1. 二.后来直接pip install tensorflow,tensorflow装完,自动装numpy却报错了.因为我之前自己用了numpy,早就装了.而每个tensorflow都

  • ASP .NET Core API发布与部署以及遇到的坑和解决方法

    最近在写.Net Core的API,由于之前没接触过Core,所以自己的想法很简单,感觉和.Net都是差不多的东西,发布部署还是按.Net的那一套来,可谓是困难重重,走了不少弯路. 也没什么漂亮的词语,也不是技术大牛,就是抱着学习技术的态度,随手写写这一套流程,以及遇到的问题跟解决方法. 一.安装服务器环境 IIS  Path-->Control Panel\All Control Panel Items\Programs and Features 没细致研究,全装了~ 二.发布API 1.选择

  • Python绘制雷达图时遇到的坑的解决

    ValueError: The number of FixedLocator locations (9), usually from a call to set_ticks, does not match the number of ticklabels (8). 运行书中例题时发现了这个错误, 原代码如上: import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rcParams['font

随机推荐