Hql语句模糊查询‘like’与中文问题
转载自:
http://blog.csdn.net/wo8553456/article/details/43489431在做搜索日志的关键字中遇到的问题,特此记录下来:
- 首先遇到的问题是模糊查询时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 + “%’)”;
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 + "%')";
※ 这里必须注意只能使用单引号,如:“ ’%” + name + ”%’ ”
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”);
String search = request.getParameter("search[value]");
String searchValue = new String(search.getBytes("ISO-8859-1"),"UTF-8");
- 最后遇到的问题是模糊查询中中文与数据库时间类型抛异常
以下内容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;
- }
- }
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;
}
}