Hql语句模糊查询‘like’与中文问题
2015-02-04 17:46
399 查看
在做搜索日志的关键字中遇到的问题,特此记录下来:
尝试了几次后终于搞定,hql如下:
[b]※ 这里必须注意只能使用单引号,如:" '%" + name + "%' "[/b]
like语法简介:
% 表示任意个数的任意字符
_ 表示任意一个字符
[abcdefg] 表示里面的字符任何一个,只取一个
[^c] 表示里面的字符不包含c
[a-z] 表示区间中的任一个,如c或d等
[^a-z] 表示非区间中的任一个
escape '/' 转义符,表示/之后的字符不是特殊字符。
经过一番查阅之后才明白其原理如下:
http请求是以ISO-8859-1的编码来传送url的,如果页面的content-type为utf-8 ,那么在发送请求时,会将字符转成utf-8后进行传送。
服务器收到这个字节流,默认会以ISO-8859-1来将这个字节流还原成相应的字符串,就如同这样:
服务器:cc = new String(bb,"ISO-8859-1");
客户端:bb = aa.getBytes("UTF-8");
还原字节流为节符串:request.getParameter("");
获取到这个cc,那么cc当然乱码了;
所以就产生了这样的做法:new String(request.getParameter("").getBytes("ISO-8859-1"),"UTF-8")还原成原始字符串。
中文正确了,却在模糊查询时却报异常java.sql.SQLException:Illegal mix of collations for operation 'like' ,真是醉了,又怎么不对了腻?!
以下内容copy网友的方法,因为本人试用后仍抛该异常,未能解决问题,so.....
我果断判断了下请求的参数是否为中文,若为中文则不对time、date、datetime此三种类型的字段进行模糊查询。
判断中文isChinese()方法见文章最后的代码。
对于我的非常规做法,仅供参考。欢迎评论、交流。
错误原理分析以及错误解决方法:
这是什么情况呢?查询一番后发现是数据库字段类型的问题:
从SQL语句方面分析这个问题,发现是 log.time like '%中文%' 导致整个SQL语句执行报错;
在 MySQL 5.5 以上, 若字段 Type 是 time,date,datetime,在 select 時若使用 like '%中文%' 会出現 Illegal mix of collations for operation 'like'
因此必需改成like binary '%中文%'即可避免出现错误。
到此该问题终于解决了,真是一路坎坷啊!附上判断是否为中文的代码:
首先遇到的问题是模糊查询时HQL拼写错误
尝试了几次后终于搞定,hql如下:String hql = " and (log.resourceName like '%"+ searchValue +"%'" + " or log.user like '%"+ searchValue + "%'" + " or log.time like '%"+ searchValue + "%'" + " or log.operation like '%"+ searchValue + "%'" + " or log.result like '%"+ searchValue + "%')";
[b]※ 这里必须注意只能使用单引号,如:" '%" + name + "%' "[/b]
like语法简介:
% 表示任意个数的任意字符
_ 表示任意一个字符
[abcdefg] 表示里面的字符任何一个,只取一个
[^c] 表示里面的字符不包含c
[a-z] 表示区间中的任一个,如c或d等
[^a-z] 表示非区间中的任一个
escape '/' 转义符,表示/之后的字符不是特殊字符。
接下来遇到的问题是request取得的值含有中文的话产生乱码
经过一番查阅之后才明白其原理如下:http请求是以ISO-8859-1的编码来传送url的,如果页面的content-type为utf-8 ,那么在发送请求时,会将字符转成utf-8后进行传送。
服务器收到这个字节流,默认会以ISO-8859-1来将这个字节流还原成相应的字符串,就如同这样:
服务器:cc = new String(bb,"ISO-8859-1");
客户端:bb = aa.getBytes("UTF-8");
还原字节流为节符串:request.getParameter("");
获取到这个cc,那么cc当然乱码了;
所以就产生了这样的做法:new String(request.getParameter("").getBytes("ISO-8859-1"),"UTF-8")还原成原始字符串。
String search = request.getParameter("search[value]");
String searchValue = new String(search.getBytes("ISO-8859-1"),"UTF-8");
最后遇到的问题是模糊查询中中文与数据库时间类型抛异常
中文正确了,却在模糊查询时却报异常java.sql.SQLException:Illegal mix of collations for operation 'like' ,真是醉了,又怎么不对了腻?!以下内容copy网友的方法,因为本人试用后仍抛该异常,未能解决问题,so.....
我果断判断了下请求的参数是否为中文,若为中文则不对time、date、datetime此三种类型的字段进行模糊查询。
判断中文isChinese()方法见文章最后的代码。
对于我的非常规做法,仅供参考。欢迎评论、交流。
错误原理分析以及错误解决方法:
这是什么情况呢?查询一番后发现是数据库字段类型的问题:
从SQL语句方面分析这个问题,发现是 log.time like '%中文%' 导致整个SQL语句执行报错;
在 MySQL 5.5 以上, 若字段 Type 是 time,date,datetime,在 select 時若使用 like '%中文%' 会出現 Illegal mix of collations for operation 'like'
因此必需改成like binary '%中文%'即可避免出现错误。
到此该问题终于解决了,真是一路坎坷啊!附上判断是否为中文的代码:
public class IsChineseUtil { // GENERAL_PUNCTUATION 判断中文的“号 // CJK_SYMBOLS_AND_PUNCTUATION 判断中文的。号 // HALFWIDTH_AND_FULLWIDTH_FORMS 判断中文的,号 private static final boolean isChinese(char c) { Character.UnicodeBlock ub = Character.UnicodeBlock.of(c); if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) { return true; } return false; } public static final boolean isChinese(String strName) { char[] ch = strName.toCharArray(); for (int i = 0; i < ch.length; i++) { char c = ch[i]; if (isChinese(c)) { return true; } } return false; } public static void main(String[] args) { System.out.println(isChinese("き")); System.out.println(isChinese("test,.?!%^&*(){}[]")); System.out.println(isChinese("测试")); System.out.println(isChinese("“测试”,。?!%……&*()——{}【】”")); } public static final boolean isChineseCharacter(String chineseStr) { char[] charArray = chineseStr.toCharArray(); for (int i = 0; i < charArray.length; i++) { if ((charArray[i] >= 0x4e00) && (charArray[i] <= 0x9fbb)) { return true; } } return false; } /** * @deprecated; 弃用。和方法isChineseCharacter比效率太低。 * */ public static final boolean isChineseCharacter_f2() { String str = "!?"; for (int i = 0; i < str.length(); i++) { if (str.substring(i, i + 1).matches("[\\u4e00-\\u9fbb]+")) { return true; } } return false; } }
相关文章推荐
- Hql语句模糊查询‘like’与传递中文乱码问题
- 解决hql语句查询条件为中文时结果集为空,为英文查询条件时不为空的问题
- 使用模糊查询Like时中文匹配下划线通配符无效的问题
- ACCESS模糊查询like的解决方法&&SQL查询语句通配符问题
- ACCESS模糊查询like的解决方法&&SQL查询语句通配符问题
- SqlServer 模糊查询中文查不出来问题
- hql语句中like查询 对于 / ' " % 的处理
- mysql查找语句中包含中文字符时查询失效的问题及解决方法
- Mysql数据库like模糊查询中文字段不准确的临时解决办法
- SQL查询语句通配符与ACCESS模糊查询like的解决方法
- HQL查询中文的问题笔记
- HQL语句查询中一些参数设置的问题
- SQL模糊查询语句(like)
- 数据库-Oracle【SQL模糊查询语句(like) 及SQL Server 2005 导入和导出向导】
- 老问题,PreparedStatement 的模糊查询 (like ‘%x%’)
- SQL 语句中模糊搜索查询 LIKE 关键字
- Hibernate3的Like用法,解决中文查询问题
- mysql 查询中文 like不准的问题
- sql查询模糊匹配Like的没数据一个问题
- SQL查询语句通配符与ACCESS模糊查询like的解决方法