在做搜索日志的关键字中遇到的问题,特此记录下来:
- 首先遇到的问题是模糊查询时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 + "%')";
※ 这里必须注意只能使用单引号,如:" '%" + 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");
- 最后遇到的问题是模糊查询中中文与数据库时间类型抛异常
中文正确了,却在模糊查询时却报异常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;
}
}