解决Mybatis3.3中NVARCHAR2生僻字乱码
文章目录
- 1. 解决Mybatis3.3中NVARCHAR2生僻字乱码
- 1.1. 注意
- 1.2. 解决方法
- 1.2.1. 第一步、数据库的varchar2字段修改为nvarchar2
- 1.2.2. 第二步、mybatis中原来的`jdbcType=VARCHAR`修改为`jdbcType=NVARCHAR`
- 1.2.3. 第三步、重写NVARCHAR的类型处理
- 1.2.4. 注意,还需要在mybatis-config.xml中配置一下
- 1.3. 总结
1. 解决Mybatis3.3中NVARCHAR2生僻字乱码
在数据库中原来的字符串类型都是用varchar2类型存储,现在发现生僻字乱码,遂改为NVARCHAR2,但是依然生僻字乱码。
1.1. 注意
- 使用的mybatis版本是3.3,不知道再其它版本中是否有同样问题
- 这里的乱码和前后端文件等编码无关,即所有中文存入varchar2,只有生僻字乱码,其它正常
1.2. 解决方法
1.2.1. 第一步、数据库的varchar2字段修改为nvarchar2
因为varchar2和数据库的字符集有关系,而数据库在ZHS16GBK
(应该是等同于GBK吧?!)编码下,不包含生僻字;修改为AL32UTF8
后mybatis居然把所有从数据库查出的中文显示为乱码了。。。所以只能使用nvarchar2。由此可以总结出:varchar2与数据库字符集有关,而nvarchar2则与数据库字符集无关(可以在varchar2和nvarchar2字段中手动输入生僻字即可看到证据)
1.2.2. 第二步、mybatis中原来的jdbcType=VARCHAR
修改为jdbcType=NVARCHAR
如果不修改的话,mybatis的类型处理器,默认会使用StringTypeHandler
来处理,StringTypeHandler
源码如下,可以看出使用的依然是setString
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package org.apache.ibatis.type;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class StringTypeHandler extends BaseTypeHandler<String> {public StringTypeHandler() {}public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, parameter);}public String getNullableResult(ResultSet rs, String columnName) throws SQLException {return rs.getString(columnName);}public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return rs.getString(columnIndex);}public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return cs.getString(columnIndex);}
}
再来看NStringTypeHandler
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//package org.apache.ibatis.type;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class NStringTypeHandler extends BaseTypeHandler<String> {public NStringTypeHandler() {}public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setString(i, parameter);}public String getNullableResult(ResultSet rs, String columnName) throws SQLException {return rs.getString(columnName);}public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return rs.getString(columnIndex);}public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return cs.getString(columnIndex);}
}
看上去和StringTypeHandler
一样呀,调试了几个小时才调好,方法是重写NStringTypeHandler
,如下第三步
1.2.3. 第三步、重写NVARCHAR的类型处理
如下,暂时只处理了set方法(即改为setNString
),因为get出来的结果生僻字没问题,所以没有修改。
package com.ufgov.util.mybatis;import org.apache.ibatis.type.*;import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** NVARCHAR汉字生僻字乱码问题。* 主要是NStringTypeHandler中,没有setNString()*/
@MappedJdbcTypes(JdbcType.NVARCHAR)
public class NVarcharTypeHandler extends BaseTypeHandler<String> {@Overridepublic 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*/@Overridepublic void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {ps.setNString(i, parameter);}@Overridepublic String getNullableResult(ResultSet rs, String columnName) throws SQLException {return rs.getString(columnName);}@Overridepublic String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {return rs.getString(columnIndex);}@Overridepublic String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {return cs.getString(columnIndex);}
}
1.2.4. 注意,还需要在mybatis-config.xml中配置一下
<typeHandlers><typeHandler handler="com.ufgov.util.mybatis.NVarcharTypeHandler"/></typeHandlers>
1.3. 总结
- 数据库字符集,utf8比gbk范围更大,gbk无法现在生僻字。
- varchar2与数据库字符集有关,nvarchar与数据库字符集无关
- 也许mybatis对NVARCHAR的处理有bug,在NStringTypeHandler中居然没有
setNString
- 由此可见,
PreparedStatement
的setString
和setNString
实现也是不同的,可以看看源码。
解决Mybatis3.3中NVARCHAR2生僻字乱码相关推荐
- PB中生僻字乱码问题得以解决
遇到过pb中出现生僻字时,显示的是乱码,查明原因原来是解析不到生僻字,只需将 pos-改成posw,mid-改成midw函数即可
- Oracle 生僻字乱码问题
就一般情况来说,Oracle存储中英文的字段用varchar2类型就可以了,但有些时候,遇到生僻字就不行了. 需求描述: 在默认字符集环境下,实现Oracle储存生僻字: 㛃.䶮.....(使用nva ...
- java mysql 生僻字 乱码_JAVA生僻字乱码问题
我先把数据从数据库中查出来,然后输出到EXCEL表格中,但是表格中显示的是乱码.数据库中的数据是正常的,没有问题,程序有个查询功能,一个导出功能,查询功能是调用润乾展示报表,没有乱码.... 我先把数 ...
- jsoup 生僻字乱码问题解决
jsoup 简介 Java 程序在解析 HTML 文档时,相信大家都接触过 htmlparser 这个开源项目,我曾经在 IBM DW 上发表过两篇关于 htmlparser 的文章,分别是:从 HT ...
- oracle 生僻字 转码,Oracle 生僻字乱码解决方案
Oracle生僻字乱码解决方案 ""(此+夕)[suǒ]字乱码,无法正常显示(变成问号); 生僻字""(此+夕)(suo)在ZHS16GBK字符集下默认无法正常 ...
- sqlserver中文生僻字乱码问题
sqlserver中文生僻字乱码问题解决 场景:前端输入生僻字,e.g. 㙍.㮾,存入到数据库为乱码(㙍/-). 解决:修改会存生僻字的字段(一般地址字段)的数据类型为nvarchar,在插入或更新s ...
- 生僻字html乱码,Tomcat 5.5.X及以上版本的生僻字乱码解决办法
软件环境:Tomcat5.5.X 问题描述: 1)一般的汉字正常,如:中国,任务,管理. 2)生僻字出现乱码.如:喆,璟. 解决过程: 1.前言.在Tomcat4中,GET和POST使用相同的处理方式 ...
- 解决jacob用wps将word转html的时候个别生僻字乱码的问题
原创文章,转载请注明出处 用jacob将wps转html的时候,Java读入转后的html,发现有个别生僻字出现乱码, 解决方法: 因为WPS默认转成html是gb2312编码的,而gb2312不支持 ...
- was中奇怪的生僻字乱码案例
问题描述 这个今天早上提供的一个生产问题.大体是说,改资料的时候,有个客户的名字有生僻字,叫"刘",保存之后就乱码了,变成"刘?" 分析过程 乱码需要确认数据 ...
最新文章
- 编写程序,输出所有3位数的水仙花数
- 类的加载顺序和对象的实例化
- 2020华南理工计算机考研分数线,华南理工大学2020考研复试分数线已公布
- 【企业管理】高效会议关注点
- React学习小结(二)
- 排序算法之快速排序详解
- 构建java ut运行环境
- 通达OA2017恢复数据库Access denied for user 'root'@'localhost' (using password: YES)报错的解决办法
- hadoop学习之azkaban(5.1):azkaban的使用及示例 标签: 任务调度hadoopazkaban脚本
- 计算机组成原理 存储单元、存储字、存储字长、存储容量的区分
- unity剩余高度自适应实现办法
- 交集♂差集♂并集♂和其他集合的内置方法
- android仿网易云音乐引导页、仿书旗小说Flutter版、ViewPager切换、风扇叶片效果等源码...
- SEO优化与SEM(竞价)区别在哪?
- jQuery 流星雨特效
- 翻译质量评估的标准与方法
- GMSL高带宽视频数据接入的方法
- Python最简单的图形编程
- 运动APP软件开发具有什么好处?
- 加州大学河滨分校计算机科学排名,2019加州大学河滨分校排名(USNews排名)