繁体   English   中英

如何使用MyBatis和Spring集成将unicode插入Oracle NVARCHAR

[英]How to insert unicode to Oracle NVARCHAR using MyBatis with Spring integration

    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: Error setting null for parameter #8 with JdbcType VARCHAR . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: Invalid column index
; invalid ResultSet access for SQL []; nested exception is java.sql.SQLException: Invalid column index
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:237)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:71)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:365)
    at $Proxy20.insert(Unknown Source)
    at org.mybatis.spring.SqlSessionTemplate.insert(SqlSessionTemplate.java:237)
    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:79)
    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:40)
    at $Proxy37.addUser(Unknown Source)
    at com.azercell.paymentgateway.service.UserServiceImpl.addUser(UserServiceImpl.java:156)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:319)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:42)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy38.addUser(Unknown Source)
    at com.azercell.paymentgateway.service.UserServiceImplTest.testAddUser(UserServiceImplTest.java:101)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:242)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:58)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:240)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:48)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:233)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:303)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:76)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.sql.SQLException: Invalid column index
    at oracle.jdbc.driver.OraclePreparedStatement.setNullCritical(OraclePreparedStatement.java:4554)
    at oracle.jdbc.driver.OraclePreparedStatement.setNull(OraclePreparedStatement.java:4541)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.setNull(OraclePreparedStatementWrapper.java:1283)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.apache.tomcat.jdbc.pool.interceptor.AbstractQueryReport$StatementProxy.invoke(AbstractQueryReport.java:235)
    at $Proxy83.setNull(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:66)
    at $Proxy84.setNull(Unknown Source)
    at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:39)
    at org.apache.ibatis.executor.parameter.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:91)
    at org.apache.ibatis.executor.statement.PreparedStatementHandler.parameterize(PreparedStatementHandler.java:77)
    at org.apache.ibatis.executor.statement.RoutingStatementHandler.parameterize(RoutingStatementHandler.java:58)
    at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:71)
    at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:44)
    at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:108)
    at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:75)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:145)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:134)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:355)
    ... 51 more

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

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

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

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

我认为您根本不需要在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);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM