溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么使用shardingsphere對SQLServer坑進(jìn)行解決

發(fā)布時間:2022-03-30 14:06:05 來源:億速云 閱讀:189 作者:iii 欄目:開發(fā)技術(shù)

這篇“怎么使用shardingsphere對SQLServer坑進(jìn)行解決”文章的知識點(diǎn)大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細(xì),步驟清晰,具有一定的借鑒價(jià)值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“怎么使用shardingsphere對SQLServer坑進(jìn)行解決”文章吧。

背景:最近一個使用SQLServer的項(xiàng)目,業(yè)務(wù)量太大,開始對業(yè)務(wù)有影響了,因此用戶要求升級改造,技術(shù)上采用shardingsphere進(jìn)行分庫分表。

經(jīng)過一系列調(diào)研,設(shè)計(jì)。。。哐哐一頓操作之后開始動刀改造。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>

改造后查詢和寫入都各種報(bào)錯:

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

問題分析:

網(wǎng)上尋了千百度,驀然回首,還是沒有找到問題,(┭┮﹏┭┮)  最后debug斷點(diǎn)跟了源碼發(fā)現(xiàn):

操作數(shù)據(jù)庫的PreparedStatement 是ShardingPreparedStatement

怎么使用shardingsphere對SQLServer坑進(jìn)行解決

 然后setNString支持SQLServerPreparedStatement 不支持ShardingPreparedStatement(改造前沒問題,改造后出問題的原因)

怎么使用shardingsphere對SQLServer坑進(jìn)行解決

問題解決:

找到問題了,下面就是解決問題了,既然沒有setNString的實(shí)現(xiàn),那就實(shí)現(xiàn)一個唄;

第一步 實(shí)現(xiàn)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 轉(zhuǎn)成 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);
    }
 
 
}

第二步 實(shí)現(xiàn)加入數(shù)據(jù)庫配置:

由于我是代理實(shí)現(xiàn)的數(shù)據(jù)庫,所有在代碼中加入即可

@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();
    }
 
   // ******* 其他實(shí)現(xiàn)
}

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

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

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

如果嫌麻煩,有另外一種解決方案:將mapper.xml中的NVARCHAR替換從VARCHAR也可以哦

以上就是關(guān)于“怎么使用shardingsphere對SQLServer坑進(jìn)行解決”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI