一、背景
在实际开发中,很多时候我们需要存储一些表情Emojit或者特殊符号,这个时候如果你单纯去获取用户带有表情包的名称数据去存储时,数据库存储存储会出现乱码,所以我们在存储前需要对用户的数据进行unicode编码后再存储,获取的时候再进行unicode转码显示即可。
二、问题
但是由于转码后的数据在数据库中存储的是带有\u开头的2或4位的16进制表示的字符,这个时候如果我们需要对用户名称进行查询或者模糊查询,直接使用sql查询编码后的数据,此时是查不到数据的。
例如:
编码后的数据:\u521d\u26\u26\u5fc3
使用sql:SELECT * from test where name = "\u521d\u26\u26\u5fc3";(查不到数据)
SELECT * from test where name like "%\u521d\u26\u26\u5fc3%";(查不到数据)
三、解决方式
- 使用“\\”代替“\”进行全匹配时
sql查询:SELECT * from testwhere name = "\\u521d\\u26\\u26\\u5fc3";
- 使用“_”代替“\”模糊匹配时
sql查询:SELECT * from test where name like "%_u521d_u26_u26_u5fc3%";
- 使用“\\\\”代替“\”模糊查询
sql查询:SELECT * from testwhere name like "%\\u26\\\\u26%";
四、编码以及解码
字符串转码成unicode编码:
public static String encodeUnicode(String string) {
StringBuilder sb= new StringBuilder();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i); // 取出每一个字符
sb.append("\\u").append(Integer.toHexString(c));// 转换为unicode
}
return sb.toString();
}
unicode转成字符串:
public static String decodeUnicode(String unicode) {
StringBuilder sb = new StringBuilder();
String[] hex = unicode.split("\\\\u");
for (int i = 1; i < hex.length; i++) {
int data = Integer.parseInt(hex[i], 16);
sb.append((char) data);
}
return sb.toString();
}
unicode转成_u形式的编码:
public static String encodeToMysqlUnicode(String string) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < string.length(); i++) {
char c = string.charAt(i); // 取出每一个字符
sb.append("_u" + Integer.toHexString(c)); // 转换为unicode
}
return sb.toString();
}