是不是所有的 数据库的转义 sql 语句对_和%转义方式都一样

如何转义emoji表情,让它可以存入utf8的数据库?_问答_ThinkSAAS
如何转义emoji表情,让它可以存入utf8的数据库?
如何转义emoji表情,让它可以存入utf8的数据库?
unicode emoji是4个字节的,存不进MySQL里,找到一个转义的库,但是转为Unicode之后,还是4个字节,一样存不进,应该说根本没转。转为其他格式的emoji又怕以后新增了表情不好做,你们在不改数据库编码的前提下,是怎么弄的?
方法1:base_encode64
这种方法是可以,但是旧数据没有经过encode操作,取数据的时候如果统一进行decode的话,旧数据会丢失的。
方法2:urlencode
这个似乎可以,对没有经过encode的数据进行decode也不会有影响,而且多次decode似乎也不会有影响。你们说这个方法有缺陷吗?
=======================
一个发现,微信获取用户基本信息的时候,返回笑哭那个表情的是ud83dude02,而我存储的时候,报错说这个 xF0x9Fx98x82 值不能存储,请问这是怎么回事,自动转码了,转成的这是什么?是微信转码过了吗?微信那个经过unicode解码,可以得到笑哭的表情
给一个标准的解决方案:
mysql的版本必须为v5.5.3或更高
把数据库的编码改成utf8mb4 -- UTF-8 Unicode
然后需要存储emoji表情的字段选择utf8mb4_general_ci
数据库连接也需要改为utf8mb4
设置完成后,应该可以看到如下类似字符集设置结果。那么可以直接的存入数据库,无需做任何额外的事情了。
mysql& SHOW VARIABLES WHERE Variable_name LIKE 'character_set_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
rows in set (0.00 sec)
我在做微信公众平台开发时遇到过这个问题,微信用户的昵称可以包含表情(坑爹- -!)。于是我就将整个昵称转换成HEX字符串存在MySQL中,目前用户1W+,系统稳定,题主可以参考一下此方案。
MySQL支持hex() and unhex()函数。Java可以使用mons.codec.binary.Hex工具类。其他语言也有相应的方法。
试试微博或qq里面的那种方式?用简单的编码来映射,比如微笑可以用[wx]或/wx。不过表情多了之后4个字符不怎么够用。。。
我看了一下 decode 的源码,应该是不会出现问题。
只要没有%解码后肯定还是原来的字符(串),有% 会出现两种情况,一种是解码成功,这个时候肯定就不是原来的字符串了,一种是解码失败,抛出异常(其实这个异常可以作为是否 encode的标准)。
解码还算是比较严格吧,作为用户名的情况下 出现 %还解码成功的概率比较小吧,对于这部分你可以手动改数据库,应该不会有很多。
你试试这个函数,之前弄微信自定义菜单的时候,也接触过Emoji表情,当时看到用的这个函数把Emoji表情的编码给转换了。
function utf8_bytes($cp) {
if ($cp & 0x10000){
return chr(0xF0 | (($cp & 0x1C0000) && 18)).
chr(0x80 | (($cp & 0x3F000) && 12)).
chr(0x80 | (($cp & 0xFC0) && 6)).
chr(0x80 | ($cp & 0x3F));
}else if ($cp & 0x800){
return chr(0xE0 | (($cp & 0xF000) && 12)).
chr(0x80 | (($cp & 0xFC0) && 6)).
chr(0x80 | ($cp & 0x3F));
}else if ($cp & 0x80){
return chr(0xC0 | (($cp & 0x7C0) && 6)).
chr(0x80 | ($cp & 0x3F));
return chr($cp);
我是这么玩儿的
//处理名字的emoji符号
$tmpStr = json_encode($text); //暴露出unicode
$tmpStr = preg_replace("#(ue[0-9a-f]{3})#ie","addslashes('1')",$tmpStr); //将emoji的unicode留下,其他不动
$text = json_decode($tmpStr);
我这个刚解决的这个问题(后端是java实现的,数据库Mysql),供参考。
1、修改存储emoji字段编码,例如放在username字段中:
ALTER TABLE user CHANGE username username VARCHAR(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_
2、java在执行数据库插入、更新操作前,要先执行 sql语句"set names utf8mb4"语句。
使用BOLO类型
将数据库编码改为utf8mb4
我是用这个处理的~
有一种编码叫 utfmb4,支持 4 位长度的 utf8 编码
喏,你的 MySQL 版本必须为 5.5 以上的
不用转,直接数据库转成utf8mb4, 我以前就是这么干的
不用更改整个数据库的把。。。create xxx() charset=utf8mb4 单表 utf8mb4就行了把
因为我的项目中需要对字数有限制的需求,涉及到逐字计数,在这基础上我增加了emoji的功能完美实现。你需要代码的话请再告诉我,我提供给你。
添加你想要问的问题
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信今天看啥 热点:
SQL或HQL预编译语句,能够防止SQL注入,但是不能处理%和_特殊字符,hqlsql
最近项目在做整改,将所有DAO层的直接拼接SQL字符串的代码,转换成使用预编译语句的方式。个人通过写dao层的单元测试,有以下几点收获。
dao层代码如下
//使用了预编译sql
public List&IndvConfigModel& selectConfigBySuffix(String suffix)
String hql = &from IndvConfigModel where configKey like '%'||?||'%'&;
return this.selectConfigByHQL(hql, new Object[]{suffix});
单元测试代码和执行结果如下:
public void testLike()
List&IndvConfigModel& list = dao.selectConfigBySuffix(&picQual&);
Assert.assertEquals(list.size(), 2);// 1.true
list = dao.selectConfigBySuffix(&picQua%&);
Assert.assertEquals(list.size(), 2);// 2.true
list = dao.selectConfigBySuffix(&pic'Qual&);
Assert.assertEquals(list.size(), 0);//3. true
1、第一个断言是true,说明上面的做法,的确能够起到模糊查询的效果&
2、第二个断言是true,说明%被认为是模糊匹配,并没有被oracle看成普通的字符。这说明预编译语句,是不能处理参数值中的特殊字符的。遇到%和_这种数据库模糊查询的特殊字符,需要使用者自己转义.
3、第三个断言没有报异常。说明:预编译语句已经对oracle的特殊字符单引号,进行了转义。即将单引号视为查询内容,而不是字符串的分界符。
由于SQL注入其实就是借助于特殊字符单引号,生成or 1= 1这种格式的sql。预编译已经对单引号进行了处理,所以可以防止SQL注入
是的,预编译有个类是PreparedStatement.这个类的对象是通过参数?来传值的例:String sql = &select * from table where id = ?&;Connection con = .....///这里得到是数据库的连接PreparedStatement ps = con.prepareStatement(sql);ps.setInt(1,id);//这里的数据库语句所用到的参数要被设置的,如果你传入了错的值,或不同类型的值,它在插入到数据库语句中会编译不通过,这也就防止了SQL注入。
很可惜,如果你是组合hql字符串的话,是防止不了的,要防止的话,也要用占位符,比如query=session.createQuery(&select
:password&);
query.setParameter(&id&.userForm.getId());
...如果你不想这么做的话,就要自己写一个filter,自动把所有的request参数值处理一下,如特殊字符前加上\,就不会有注入错误了
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&&&&&&&&&&&&&
数据库前沿最近更新java拼接SQL语句的特殊字符转义 - 推酷
java拼接SQL语句的特殊字符转义
& & & 在实际的项目开发中,往往会根据用户在界面的文本框中输入的信息,去数据库中做模糊查询。
如果使用的是原始的JDBC和SQL,往往需要对用户的输入进行转义,避免生成的sql语法错误,或者防止SQL注入。
& & &比如对输入的%和_和',就需要进行转义,因为这3个字符是SQL的特殊字符,如果不处理会导致sql出错或者是查询数据不正确。
& & & 假如有这样1个查询请求,模糊查询标题中包含a%b_cc'd的记录,正确的sql应该是下面这样的:
& & & select * from t_sch_work_info t where& t.title like& '%a/%b/_cc''d%' ESCAPE '/';
这就需要对String content = &a%b_cc'd&;进行转义后,再拼成SQL语句:
* 对content的内容进行转换后,在作为oracle查询的条件字段值。使用/作为oracle的转义字符,比较合适。&br&
* 既能达到效果,而且java代码相对容易理解,建议这种使用方式&br&
* &%'& + content + &'%
ESCAPE '/' &这种拼接sql看起来也容易理解&br&
* @param content
public static String decodeSpecialCharsWhenLikeUseBackslash(String content)
// 单引号是oracle字符串的边界,oralce中用2个单引号代表1个单引号
String afterDecode = content.replaceAll(&'&, &''&);
// 由于使用了/作为ESCAPE的转义特殊字符,所以需要对该字符进行转义
// 这里的作用是将&a/a&转成&a//a&
afterDecode = afterDecode.replaceAll(&/&, &//&);
// 使用转义字符 /,对oracle特殊字符% 进行转义,只作为普通查询字符,不是模糊匹配
afterDecode = afterDecode.replaceAll(&%&, &/%&);
// 使用转义字符 /,对oracle特殊字符_ 进行转义,只作为普通查询字符,不是模糊匹配
afterDecode = afterDecode.replaceAll(&_&, &/_&);
return afterD
* 对content的内容进行转换后,在作为oracle查询的条件字段值。使用\作为oracle的转义字符。&br&
* 这种做法也能达到目的,但不是好的做法,比较容易出错,而且代码很那看懂。&br&
* &%'& + content + &'%
ESCAPE '\' &这种拼接sql实际上是错误的.&br&
* &%'& + content + &'%
ESCAPE '\\' &这种拼接sql才是正确的&br&
* @param content
public static String decodeSpecialCharsWhenLikeUseSlash(String content)
// 单引号是oracle字符串的边界,oralce中用2个单引号代表1个单引号
String afterDecode = content.replaceAll(&'&, &''&);
// 由于使用了\作为ESCAPE的转义特殊字符,所以需要对该字符进行转义
// 由于\在java和正则表达式中都是特殊字符,需要进行特殊处理
// 这里的作用是将&a\a&转成&a\\a&
afterDecode = afterDecode.replaceAll(&\\\\&, &\\\\\\\\&);
// 使用转义字符 \,对oracle特殊字符% 进行转义,只作为普通查询字符,不是模糊匹配
afterDecode = afterDecode.replaceAll(&%&, &\\\\%&);
// 使用转义字符 \,对oracle特殊字符_ 进行转义,只作为普通查询字符,不是模糊匹配
afterDecode = afterDecode.replaceAll(&_&, &\\\\_&);
return afterD
&在oracle中使用ESCAPE的时候,可以指定转义符号。通过上面的\和/的转义,发现更适合使用/来让程序变得更容易理解
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致关于sql语句中的单引号(‘ ) 和双引号(“) 的处理问题?
[问题点数:100分,结帖人findcsdn]
关于sql语句中的单引号(‘ ) 和双引号(“) 的处理问题?
[问题点数:100分,结帖人findcsdn]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
2005年 总版技术专家分年内排行榜第一2004年 总版技术专家分年内排行榜第一
2006年 总版技术专家分年内排行榜第六2003年 总版技术专家分年内排行榜第八
2005年 总版技术专家分年内排行榜第四
2006年11月 总版技术专家分月排行榜第一2006年3月 总版技术专家分月排行榜第一2006年2月 总版技术专家分月排行榜第一2006年1月 总版技术专家分月排行榜第一2005年12月 总版技术专家分月排行榜第一
2009年7月 荣获微软MVP称号2010年7月 荣获微软MVP称号2008年7月 荣获微软MVP称号
2005年2月 Delphi大版内专家分月排行榜第一
本帖子已过去太久远了,不再提供回复功能。}

我要回帖

更多关于 mysql数据库转义字符 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信