论坛首页 Java企业应用论坛

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

浏览 26777 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-03-09  
wuweixian你好,谢谢你的回复
经过测试,使用binary修改数据库也没有解决问题!
os:linux
mysql:4.0.14
试试下面的测试吧:
--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('夏');
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('麦肯姆');
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 '%夏%';
alter table usertest modify username varchar(30) binary NOT NULL default '';
select * from usertest where username like '%夏%';
select * from usertest where username like  binary('%夏%');


************************************************
这是后面几条的结果
mysql> select * from usertest where username like '%夏%';
+----+----------+
| id | username |
+----+----------+
|  1 | 美文     |
|  2 | 美国项目 |
|  3 | 李文     |
|  4 | 老唐     |
|  5 | 梦漂     |
|  6 | 龙武     |
|  7 | 夏       |
|  8 | 阿夏     |
|  9 | 迪娜     |
| 10 | 海韵男   |
| 11 | 老木匠   |
| 12 | 老泥巴   |
| 13 | 李夏雨   |
| 14 | 麦肯姆   |
| 15 | 南慕容   |
| 16 | 南南     |
| 17 | 能上能下 |
| 18 | 上南洋   |
| 19 | 塑料模具 |
| 20 | 拖泥     |
+----+----------+
20 rows in set (0.00 sec)

mysql> alter table usertest modify username varchar(30) binary NOT NULL default '';
Query OK, 20 rows affected (0.00 sec)
Records: 20  Duplicates: 0  Warnings: 0

mysql> select * from usertest where username like '%夏%';
+----+----------+
| id | username |
+----+----------+
|  7 | 夏       |
|  8 | 阿夏     |
|  9 | 迪娜     |
| 10 | 海韵男   |
| 11 | 老木匠   |
| 12 | 老泥巴   |
| 13 | 李夏雨   |
| 14 | 麦肯姆   |
| 15 | 南慕容   |
| 16 | 南南     |
| 17 | 能上能下 |
| 18 | 上南洋   |
| 19 | 塑料模具 |
| 20 | 拖泥     |
+----+----------+
14 rows in set (0.01 sec)

mysql> desc usertest
    -> ;
+----------+--------------------+------+-----+---------+----------------+
| Field    | Type               | Null | Key | Default | Extra          |
+----------+--------------------+------+-----+---------+----------------+
| id       | int(9) unsigned    |      | PRI | NULL    | auto_increment |
| username | varchar(30) binary |      |     |         |                |
+----------+--------------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

select * from usertest where username like  binary('%夏%');
+----+----------+
| id | username |
+----+----------+
|  7 | 夏       |
|  8 | 阿夏     |
|  9 | 迪娜     |
| 10 | 海韵男   |
| 11 | 老木匠   |
| 12 | 老泥巴   |
| 13 | 李夏雨   |
| 14 | 麦肯姆   |
| 15 | 南慕容   |
| 16 | 南南     |
| 17 | 能上能下 |
| 18 | 上南洋   |
| 19 | 塑料模具 |
| 20 | 拖泥     |
+----+----------+
14 rows in set (0.00 sec)

那么现在的问题是什么呢?我这里没有windows下的mysql,是不是windows下的mysql就没有这个问题呢?
请测试一下.
0 请登录后投票
   发表时间:2004-03-25  
1、mysql本身有在使用中文字段作为查询条件时候的返回记录不准确的问题。在使用了binary之后,这个问题的范围大大的缩小。如果不是查询单个汉字的情况下,基本不会出现问题。(具体测试情况看上面的帖子)
2、hibernate中可以使用binary,例如
    select obj from User as obj where obj.name=binary('张三‘);
3、mysql的驱动很多,选择一个合适的驱动很重要,在我们的项目中,经过无数次的尝试,最后使用的是mm.mysql-2.0.2-bin.jar ,这个驱动对中文的支持不错,到目前为止没有发现bug
0 请登录后投票
   发表时间:2004-03-26  
2.0.2 对于大小写莫些情况下敏感 2.0.11bug最少
0 请登录后投票
   发表时间:2004-03-27  
3Q!
0 请登录后投票
   发表时间:2004-04-20  
在windows 2k pro下 my.ini里 添加
default-character-set=gb2312

我的一点问题没有啊,

mysql> select * from usertest where username like '%夏%';
+----+----------+
| id | username |
+----+----------+
|  7 | 夏       |
|  8 | 阿夏     |
| 13 | 李夏雨   |
+----+----------+
3 rows in set (0.09 sec)
0 请登录后投票
   发表时间:2004-04-20  
好象问题不是出在mysql驱动上,而是你们设置的mysql默认字符集问题,mysql默认是英文的,要手工在配置文件中设置default-character-set=gb2312 ,我的好几个系统都是这样,没什么问题啊.
0 请登录后投票
   发表时间:2004-04-21  
MasterJedi 写道
好象问题不是出在mysql驱动上,而是你们设置的mysql默认字符集问题,mysql默认是英文的,要手工在配置文件中设置default-character-set=gb2312 ,我的好几个系统都是这样,没什么问题啊.

在我尝试解决这个问题的时候,化了很多功夫,default-character-set=gb2312 ,default-character-set=gbk我都试过,都是没有效果的。至于为什么我们两人的测试结果不一样,我想可能和环境有关系。另外我们的表没有使用innodb,我们使用了myism。还有我们数据库里面已经有几十万条数据使用gbk编码保存进去的,这也是需要考虑的一个因素。我会在windows环境下测试一下的。
    不过如果使用gb2312我到是怀疑会有问题。因为如果是某些比较生僻的汉字的时候,会怎么样呢,多半是乱码。
0 请登录后投票
   发表时间:2004-04-21  
maohy 写道
在我尝试解决这个问题的时候,化了很多功夫,default-character-set=gb2312 ,default-character-set=gbk我都试过,都是没有效果的。至于为什么我们两人的测试结果不一样,我想可能和环境有关系。另外我们的表没有使用innodb,我们使用了myism。还有我们数据库里面已经有几十万条数据使用gbk编码保存进去的,这也是需要考虑的一个因素。我会在windows环境下测试一下的。
    不过如果使用gb2312我到是怀疑会有问题。因为如果是某些比较生僻的汉字的时候,会怎么样呢,多半是乱码。


我怀疑是你使用GBK存入的时候mysql的字符集不是gbk,结果导致插入的数据出了问题,你可否按如下顺序做一下测试?
1、取消mysql服务,在my.ini中添加default-character-set=gbk,重新启动mysql;
2、建立新数据库,建立新表并插入初始化数据
3、在mysql操作符下进行query
0 请登录后投票
   发表时间:2004-05-21  
我没有修改默认的字符集(iso8859-1),可以把汉字写入到mysql中。但是不知道为什么,读出来的却都是一些“?”,在模糊查询的时候虽然查出来的是?,但是查询的精度还是比较准确的。
0 请登录后投票
   发表时间:2004-05-21  
MySQL中文模糊检索问题的解决方法

--------------------------------------------------------------------------------
2003-4-10 16:23:23 林兴陆
 
在 MySQL 下,在进行中文模糊检索时,经常会返回一些与之不相关的
记录,如查找 "-0x1.ebea4bfbffaacp-4%" 时,返回的可能有中文字符,却没有 a 字符存在。
本人以前也曾遇到过类似问题,经详细阅读 MySQL 的 Manual ,发现可以
有一种方法很方便的解决并得到满意的结果。

例子:
·希望通过“标题”对新闻库进行检索,关键字可能包含是中英文,如
下 SQL 语句:
select id,title,name from achech_com.news where title like '-0x1.ebea4bfbebe84p-4%'
返回的结果,某些 title 字段确定带了“a”关键字,而有些则只有中文,
但也随之返回在检索结果中。
解决方法,使用 BINARY 属性进行检索,如:
select id,title,name from achech_com.news where binary title like '-0x1.ebea4bfbebe84p-4%'
返回的结果较之前正确,但英文字母区分大小写,故有时在检索如“Achech”
及“achech”的结果是不一样的。
知道了使用 BINARY 属性可以解决前面这个问题,再看看 MySQL 支持的
UCASE 及 CONCAT 函数,其中 UCASE 是将英文全部转成大写,而 CONCAT 函
数的作用是对字符进行连接,以下是我们完全解决后的 SQL 语句:
select id,title,name from achech_com.news where binary ucase(title) like concat('%',ucase('a'),'%')
检索的步骤是先将属性指定为 BINARY ,以精确检索结果,而被 like 的 title
内容存在大小写字母的可能,故先使用 ucase 函数将字段内容全部转换成大
写字母,然后再进行 like 操作,而 like 的操作使用模糊方法,使用 concat
的好处是传进来的可以是直接的关键字,不需要带“%”万用符,将“'a'”直接
换成你的变量,在任何语言下都万事无忧了。
当然你也可以这么写:
select id,title,name from achech_com.news where binary ucase(title) like ucase('0x0.00020bfbebe08p-1022%')
检索的结果还算满意吧,不过速度可能会因此而慢N毫秒喔。

相关资料:
Relate:
20.16 Case Sensitivity in Searches
By default, MySQL searches are case-insensitive (although there are some character sets that are never case insensitive, such as czech). That means that if you search with col_name LIKE 'a%', you will get all column values that start with A or a. If you want to make this search case-sensitive, use something like INDEX(col_name, "A")=0 to check a prefix. Or use STRCMP(col_name, "A") = 0 if the column value must be exactly "A".
0 请登录后投票
论坛首页 Java企业应用版

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