首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

ibatis自定义数据类型在不支持汉语的数据库存储汉字

2013-10-16 
ibatis自定义数据类型在不支持中文的数据库存储汉字道理很简单,把gbk的汉字转换成iso编码存进数据库就可以

ibatis自定义数据类型在不支持中文的数据库存储汉字
道理很简单,把gbk的汉字转换成iso编码存进数据库就可以了,读出来的时候把iso转换成gbk还原出原始的汉字。
ibatis可以自定义类型处理器,在这里面做编码转换再适合不过了!
sqlmap-config.xml:

public class Main {    private static SqlMapClient sqlMapClient = null;    // 读取配置文件    static {        try {            InputStream in = Main.class.getClassLoader().getResourceAsStream("sqlmap-config.xml");            sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(in);            in.close();        } catch (IOException e) {            e.printStackTrace();        }    }    public static User selectUserById(int id) throws Exception {        return (User) sqlMapClient.queryForObject("User.getUserByUserId", id);    }    public static void insertUser(User user)throws Exception {       sqlMapClient.insert("User.insertUser", user);    }    public static void main(String[] args) throws Exception {        User u = new User();        u.setId(123456);        u.setName(new ChineseString("中国"));        u.setBirth(new Date());        Main.insertUser(u);        u = Main.selectUserById(u.getId());        System.out.println(u);    }}

这么做,只要数据库服务器的编码方式兼容iso编码,存储中文都不会有问题。看上去很完美的解决方案,但是还有个问题,存储的数据的长度的变化。

看一下我们的mysql:
mysql>  show variables like 'character%';
+--------------------------+------------------------------------+
| Variable_name            | Value                              |
+--------------------------+------------------------------------+
| character_set_client     | gbk                                |
| character_set_connection | gbk                                |
| character_set_database   | utf8                               |
| character_set_filesystem | binary                             |
| character_set_results    | gbk                                |
| character_set_server     | utf8                               |
| character_set_system     | utf8                               |
| character_sets_dir       | D:\programs\mysql5\share\charsets\ |
+--------------------------+------------------------------------+
8 rows in set (0.00 sec)
数据库是utf8编码的。

mysql> show create table user \G
*************************** 1. row ***************************
       Table: user
Create Table: CREATE TABLE `user` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL,
  `birth` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTA
MP
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select * from user where id =12345;
+-------+-------+---------------------+
| id    | name  | birth               |
+-------+-------+---------------------+
| 12345 | ???ú   | 2013-10-15 10:22:45 |
+-------+-------+---------------------+
1 row in set (0.00 sec)
mysql> select length(name) from user where id = 12345;
+--------------+
| length(name) |
+--------------+
|            8 |
+--------------+
1 row in set (0.00 sec)

“中国”的gbk编码是d6 d0 b9 fa,转化成了4个iso字符,在utf-8里面,0080 ~07FF之间的字符占2个字节,这4个字符都在这个范围内,共占8个字节。
而正常存储"中国"只需要6个字节,一个汉字在utf编码下是3个字节,如下:

mysql> set names gbk;  --在客户端设置一下编码才能正常的插入中文
Query OK, 0 rows affected (0.00 sec)

mysql> insert into user values(123456,'中国',now());
Query OK, 1 row affected (0.04 sec)
mysql> select * from user where id = 123456;
+--------+------+---------------------+
| id     | name | birth               |
+--------+------+---------------------+
| 123456 | 中国    | 2013-10-15 10:39:18 |
+--------+------+---------------------+
1 row in set (0.00 sec)
mysql> select length(name) from user where id = 123456;
+--------------+
| length(name) |
+--------------+
|            6 |
+--------------+
1 row in set (0.00 sec)

可见,同样是存储“中国”两个汉字,原先要6个字节,现在变为8个字节。
mysql5里面,varchar(N),指的是N个字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放N个,最大大小是65532字节。
因此,原先我们可以用name varchar(2),现在必须用name varchar(4)。

ps:set names gbk 是让mysql server 和客户端之间的传输用gbk编码,存储在server上的还是utf8,在客户端查询时仍然需要gbk码,因为cmd命令行默认是gbk编码的。、
或者是这么搞:
mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.00 sec)
mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)
参考文档:

http://blog.csdn.net/lovingprince/article/details/2768849

http://www.cnblogs.com/doit8791/archive/2012/05/28/2522556.html

源码下载地址:http://download.csdn.net/detail/goldenfish1919/6403209

热点排行