2
    INSERT INTO rbp_users
       (user_id, user_name, passwd, bank_id, descr, stat, p_exp, user_type_id, email_address)
    VALUES
       (rbp_userid_seq.NEXTVAL ,
        'any_user_name',
        'some_encrypted_password',
        1,
        N'əəııööğğşşççüü', --unicode string
        'E',
        SYSDATE,
        2,
        NULL);

上面插入带有 NVARCHAR 字段“descr”的 Oracle 表可以通过 PL/SQL Developer 正常工作。但是我不能在 MyBatis DAO Mapper XML 的 unicode 字段之前写“N”:

<insert id="addUser" parameterType="User" flushCache="true">
    INSERT INTO rbp_users
       (user_id, user_name, passwd, bank_id, descr, stat, p_exp, user_type_id, email_address)
    VALUES
       (rbp_userid_seq.NEXTVAL ,
        #{userName,            javaType=String,     jdbcType=VARCHAR},
        pswcode(#{password,    javaType=String,     jdbcType=VARCHAR}),
        #{bankId,              javaType=Integer,    jdbcType=NUMERIC},
        N#{description,         javaType=String,     jdbcType=NVARCHAR},
        #{userStatus,          javaType=String,     jdbcType=VARCHAR},
        #{passwordExpireDate,  javaType=Date,       jdbcType=DATE},
        #{userTypeId,          javaType=Integer,    jdbcType=NUMERIC},
        #{emailAddress,        javaType=String,     jdbcType=VARCHAR})

    <selectKey resultType="java.lang.Integer" keyProperty="userId">
        SELECT rbp_userid_seq.currval from dual
    </selectKey>
</insert>

这引发和错误:

org.springframework.jdbc.InvalidResultSetAccessException:使用 JdbcType VARCHAR 为参数 #8 设置 null 时出错。尝试为此参数设置不同的 JdbcType 或不同的 jdbcTypeForNull 配置属性。原因:java.sql.SQLException:无效的列索引
; SQL [] 的 ResultSet 访问无效;嵌套异常是 java.sql.SQLException: Invalid column index
    在 org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:237)
    在 org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    在 org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
    在 org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365)
    在 $Proxy20.insert(未知来源)
    在 org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:237)
    在 org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:79)
    在 org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)
    在 $Proxy37.addUser(未知来源)
    在 com.azercell.paymentgateway.service.UserServiceImpl.addUser(UserServiceImpl.java:156)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在 org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
    在 org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    在 org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:42)
    在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    在 org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
    在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    在 org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    在 $Proxy38.addUser(未知来源)
    在 com.azercell.paymentgateway.service.UserServiceImplTest.testAddUser(UserServiceImplTest.java:101)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
    在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:242)
    在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:58)
    在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:240)
    在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:48)
    在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:233)
    在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    在 org.junit.runners.ParentRunner.run(ParentRunner.java:303)
    在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    在 org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
    在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
    在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
原因:java.sql.SQLException: Invalid column index
    在 oracle.jdbc.driver.OraclePreparedStatement.setNullCritical(OraclePreparedStatement.java:4554)
    在 oracle.jdbc.driver.OraclePreparedStatement.setNull(OraclePreparedStatement.java:4541)
    在 oracle.jdbc.driver.OraclePreparedStatementWrapper.setNull(OraclePreparedStatementWrapper.java:1283)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在 org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy.invoke(AbstractQueryReport.java:235)
    在 $Proxy83.setNull(未知来源)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在 org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:66)
    在 $Proxy84.setNull(未知来源)
    在 org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:39)
    在 org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:91)
    在 org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:77)
    在 org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:58)
    在 org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:71)
    在 org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:44)
    在 org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:108)
    在 org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75)
    在 org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:145)
    在 org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:134)
    在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    在 org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:355)
    ... 51 更多

如果从“N#{description, javaType=String, jdbcType=NVARCHAR}”中删除“N”,则不会引发异常,但插入的字符串会损坏。

4

2 回答 2

2

使用以下参数执行 Tomcat 后,我​​可以解决问题:

-Doracle.jdbc.defaultNChar=true
-Doracle.jdbc.defaultNChar=true  

来源:将国家字符插入 oracle NCHAR 或 NVARCHAR 列不起作用

于 2012-12-05T12:25:15.843 回答
1

我认为您根本不必在 XML 中的 unicode 字段之前提及“N”,因为您正在提及其中的 jdbcType。

在某些环境中,系统的默认编码不能很好地与 XML 文件喜欢的 unicode 编码配合使用。如果您在使用 Reader 作为输入解析 iBATIS XML 文件时遇到编码问题,您可以更改默认编码以匹配 XML 文件的编码。例如:

 String resource = “properties/sqlMap-config.xml”;
 Resources.setCharset(Charset.forName('UTF-8”)); // change the default encoding
 Reader reader = Resources.getResourceAsReader(resource);
 SqlMapClient sqlMap = SqlMapClientBuilder.buildSqlMap(reader);

“<strong>setCharset”方法会将用于所有未来调用的编码更改为“<strong>getResourceAsReader”。

于 2012-12-04T08:47:11.437 回答