论坛首页 Java企业应用论坛

关于hibernate+mysql在用中文作为查询条件时候bug的解决方案

浏览 26776 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-03-02  
在mysql中如果写这样的语句
select * from user where name='张三';
结果可能大大出乎我们的意料
可能是
id    name
1    张三
2    李四
3    王五
不要吓一跳,这是真的.我们在mysql的多个版本里测试都有这个问题.

mysql提供的解决方案如下
select * from user where name=binary('张三');
这样加了binary之后,查询会根据二进制来找.问题可以解决.

可是现在我们使用了hibernate+mysql
配置如下
hibernate.dialect net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class org.gjt.mm.mysql.Driver
hibernate.connection.url jdbc:mysql://10.0.0.1:3306/database_name?useUnicode=true&characterEncoding=GBK


hsql:
select obj from User obj where obj.name=binary('张三');
这样是不行的.

那应该怎么办呢.请指教
   发表时间:2004-03-03  
maohy 写道
在mysql中如果写这样的语句
select * from user where name='张三';
结果可能大大出乎我们的意料
可能是
id    name
1    张三
2    李四
3    王五
不要吓一跳,这是真的.我们在mysql的多个版本里测试都有这个问题.


你的mysql的版本是多少?name field的类型是什么?有那么多的中文应用系统采用mysql,从来没有听说过mysql有这样的问题。用手上的mysql做测试也没有出现你的问题。
0 请登录后投票
   发表时间:2004-03-03  
试一下,下面的语句吧。

--drop table usertest;
create TABLE usertest (
  id int(9) unsigned NOT NULL auto_increment,
  username varchar(30) NOT NULL default '',
  primary key  (id)
  )
TYPE=InnoDB;

insert into usertest (username) VALUES('美文');
insert into usertest (username) VALUES('美国项目');
insert into usertest (username) VALUES('李文');
insert into usertest (username) VALUES('老唐');
insert into usertest (username) VALUES('梦漂');
insert into usertest (username) VALUES('龙武');
insert into usertest (username) VALUES('夏');

select * from usertest where username like '%夏%'
这是结果:7 rows fetched ( 0.03 sec)
哈哈,所有的记录都找到了

我们在4.0.18  和4.0.15下测试都有这个问题.
0 请登录后投票
   发表时间:2004-03-03  
的确有这个问题,以前我做培训项目的时候,查一个人的姓名有些字会出来一些毫不相干的字。 但加了个binary 可能会出现移植的问题。
在hibernate里你查
select obj from User as obj where obj.name='张三‘;
也会出来其他的么? 我没测试过
0 请登录后投票
   发表时间:2004-03-03  
你使用的是LIKE,而不是你最初发贴里面说的=啊,因为mysql 的LIKE操作是按照ASCII 操作的,所以LIKE的时候是可能有问题的。

只用修改一下你的create table的script:

create TABLE usertest (
id int(9) unsigned NOT NULL auto_increment,
username varchar(30) BINARY NOT NULL default '',
primary key (id)
)
TYPE=InnoDB;

在create的时候就使用binary,而不是在query的时候加。
0 请登录后投票
   发表时间:2004-03-03  
>>你使用的是LIKE,而不是你最初发贴里面说的=啊,因为mysql 的LIKE  操作是按照ASCII 操作的,所以LIKE的时候是可能有问题的。


like不行,用=的时候也有问题的
不信你试一下



这三个字

不过你说的解决办法我到是要试试看,比较关心这样的解决办法会不会有什么问题,效率如何? 
0 请登录后投票
   发表时间:2004-03-05  
Quake Wang 写道
你使用的是LIKE,而不是你最初发贴里面说的=啊,因为mysql 的LIKE操作是按照ASCII 操作的,所以LIKE的时候是可能有问题的。

只用修改一下你的create table的script:

create TABLE usertest (
id int(9) unsigned NOT NULL auto_increment,
username varchar(30) BINARY NOT NULL default '',
primary key (id)
)
TYPE=InnoDB;

在create的时候就使用binary,而不是在query的时候加。


老大,这种解决方法在不行啊,我测试过了,还是能找到不相关的数据。
我的数据表是已经存在的,我用
alter table usertest modify  username        varchar(32) binary;       
在改了表结构之后还是能找到不相关的数据。
郁闷ing

我考虑直接修改hibernate的源代码,加上支持binary这种语法的功能,请大侠指点一下这样可以解决问题吗?
0 请登录后投票
   发表时间:2004-03-05  
我的环境:
MySQL 3.23.38-nt, Windows2000 Chinese Pro.

MySQL的版本有些老,但是使用binary create table or alter table,你说的问题都无法重现,中文是正常的。

觉得在你说的4.0.x版本里面也不应该有中文的问题,你的OS是什么?

或者你去mysql的网站上找找看,我是没有听说过这样的问题,good luck
0 请登录后投票
   发表时间:2004-03-06  
我的os是linux
这个问题是肯定存在的.
比如象我在上面列举的那几个字.你可以试试
我们原来是在查询中加binary来解决的.
0 请登录后投票
   发表时间:2004-03-07  
os:win2000p;
MySQL:4.0.14;
结果:
没有修改表结构之前:
mysql> select * from usertest where username like '%夏%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  2 | 美国项目 |
|  3 | 李文     |
|  4 | 老唐     |
|  5 | 梦漂     |
|  6 | 龙武     |
|  7 | 夏       |
+----+----------+
7 rows in set (0.00 sec)

mysql> select * from usertest where username like '%美%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  2 | 美国项目 |
+----+----------+
2 rows in set (0.00 sec)

mysql> select * from usertest where username like '%老%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  3 | 李文     |
|  4 | 老唐     |
|  5 | 梦漂     |
+----+----------+
4 rows in set (0.00 sec)

mysql> select * from usertest where username like '%文%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  2 | 美国项目 |
|  3 | 李文     |
|  4 | 老唐     |
|  5 | 梦漂     |
|  6 | 龙武     |
|  7 | 夏       |
+----+----------+
7 rows in set (0.00 sec)

修改表结构以后:
mysql> alter table usertest modify username varchar(32) binary;
Query OK, 7 rows affected (0.02 sec)
Records: 7  Duplicates: 0  Warnings: 0

mysql> select * from usertest where username like '%文%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  3 | 李文     |
+----+----------+
2 rows in set (0.00 sec)

mysql> select * from usertest where username like '%老%';
+----+----------+
| id | username |
+----+----------+
|  4 | 老唐     |
+----+----------+
1 row in set (0.00 sec)

mysql> select * from usertest where username like '%夏%';
+----+----------+
| id | username |
+----+----------+
|  7 | 夏       |
+----+----------+
1 row in set (0.00 sec)

mysql> select * from usertest where username like '%美%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  2 | 美国项目 |
+----+----------+
2 rows in set (0.00 sec)

建议你先弄清楚问题的本质,然后去改源码。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics