mysql数据库默认的字符集是latin1。默认情况下,我们编译的httpd插件是可以正常读取该类型的数据库,并且不会出现乱码。但是,如果我们的数据库变成其他格式,比如UTF8,那么默认读取出来的数据就是乱码,且无论我们怎么设置参数都不会起作用。(转载请指明出于breaksoftware的csdn博客)

我们看一个utf8类型数据库的例子,使用以下指令查看字符集

 SHOW VARIABLES LIKE 'character_set_%';

通过character_set_database的值,我们可以得知该数据库类型是utf8。这样我们在读取该数据库时,便需要指定utf8字符集。在其他语言中,我们一般如此设置

“charset=utf8"

我们尝试将这句话加入到连接数据库的参数中

status = apr_dbd_open(driver, pool_db, "host=localhost;user=user_name;pass=password;dbname=database_name;charset=utf8", &handle);

这句api可以执行成功,但是读取的结果还是乱码!这很不科学,于是我浏览了下apr数据库相关函数,发现没有一个特定的接口可以设定字符集。可以想象apr-util库只是对libmysql++-dev 复杂接口的封装。那么存在一种可能:apr-util实现还不全面。我们阅读apr_dbd_open的实现

    struct {const char *field;const char *value;} fields[] = {{"host", NULL},{"user", NULL},{"pass", NULL},{"dbname", NULL},{"port", NULL},{"sock", NULL},{"flags", NULL},{"fldsz", NULL},{"group", NULL},{"reconnect", NULL},{NULL, NULL}};unsigned int port = 0;apr_dbd_t *sql = apr_pcalloc(pool, sizeof(apr_dbd_t));sql->fldsz = FIELDSIZE;sql->conn = mysql_init(sql->conn);if ( sql->conn == NULL ) {return NULL;}for (ptr = strchr(params, '='); ptr; ptr = strchr(ptr, '=')) {/* don't dereference memory that may not belong to us */if (ptr == params) {++ptr;continue;}for (key = ptr-1; apr_isspace(*key); --key);klen = 0;while (apr_isalpha(*key)) {/* don't parse backwards off the start of the string */if (key == params) {--key;++klen;break;}--key;++klen;}++key;for (value = ptr+1; apr_isspace(*value); ++value);vlen = strcspn(value, delims);for (i = 0; fields[i].field != NULL; i++) {if (!strncasecmp(fields[i].field, key, klen)) {fields[i].value = apr_pstrndup(pool, value, vlen);break;}}ptr = value+vlen;}if (fields[4].value != NULL) {port = atoi(fields[4].value);}if (fields[6].value != NULL &&!strcmp(fields[6].value, "CLIENT_FOUND_ROWS")) {flags |= CLIENT_FOUND_ROWS; /* only option we know */}if (fields[7].value != NULL) {sql->fldsz = atol(fields[7].value);}if (fields[8].value != NULL) {mysql_options(sql->conn, MYSQL_READ_DEFAULT_GROUP, fields[8].value);}
#if MYSQL_VERSION_ID >= 50013if (fields[9].value != NULL) {do_reconnect = atoi(fields[9].value) ? 1 : 0;}
#endif#if MYSQL_VERSION_ID >= 50013/* the MySQL manual says this should be BEFORE mysql_real_connect */mysql_options(sql->conn, MYSQL_OPT_RECONNECT, &do_reconnect);
#endifreal_conn = mysql_real_connect(sql->conn, fields[0].value,fields[1].value, fields[2].value,fields[3].value, port,fields[5].value, flags);

粗略读了一下这段代码,可以得出以下几点判断:

  1. apr_dbd_open内部使用mysql_real_connect连接数据库
  2. apr_dbd_open可以解析的参数只有fields数组中定义的字段
  3. apr_dbd_open封装了mysql_options函数用于设置相关参数

我们从mysql的开发文档(http://dev.mysql.com/doc/refman/5.7/en/mysql-real-connect.html)中可以查阅到如下一句话

The user and passwd parameters use whatever character set has been configured for the MYSQL object. By default, this is latin1, but can be changed by calling mysql_options(mysql, MYSQL_SET_CHARSET_NAME, "charset_name") prior to connecting.

可以见得我们需要使用mysql_options,传递MYSQL_SET_CHARSET_NAME来设置字符集。但是通过对apr-util库的通篇搜索,mysql_options只是在apr_dbd_open中被使用了,且还搜索不到MYSQL_SET_CHARSET_NAME。那么我们可以认定apr-util还没实现”字符集选择“的功能。我们需要自己手工修改代码(/usr/src/apr-util-1.5.4/dbd/apr_dbd_mysql.c)

    struct {const char *field;const char *value;} fields[] = {{"host", NULL},{"user", NULL},{"pass", NULL},{"dbname", NULL},{"port", NULL},{"sock", NULL},{"flags", NULL},{"fldsz", NULL},{"group", NULL},{"reconnect", NULL},{"charset", NULL},{NULL, NULL}};

先设定好需要解析的字段,再在mysql_real_connect之前插入

    if (fields[10].value != NULL) {mysql_options(sql->conn, MYSQL_SET_CHARSET_NAME, fields[10].value);}

如此,重新编译apr-util和httpd库,我们的插件便可以支持数据库字符集的选择了。

服务器架设笔记——httpd插件支持mysql字符集选择相关推荐

  1. 服务器架设笔记——打通MySQL和Apache

    在<服务器架设笔记--使用Apache插件解析简单请求>一文中,我们已经可以获取请求内容.这只是万里长征的第一步.因为一般来说,客户端向服务器发起请求,服务器会有着复杂的业务处理逻辑.举个 ...

  2. 服务器架设笔记——使用Apache插件解析简单请求

    一般来说,对于一个请求,服务器都会对其进行解析,以确定请求的合法性以及行进的路径.于是本节将讲解如何获取请求的数据.(转载请指明出于breaksoftware的csdn博客) 我们使用<服务器架 ...

  3. 服务器架设笔记——多模块和全局数据

    随着项目工程的发展,多模块设计和性能优化是在所难免的.本文我将基于一些现实中可能遇到的需求,讲解如何在Apache的Httpd插件体系中实现这些功能.(转载请指明出于breaksoftware的csd ...

  4. 服务器架设笔记——Apache模块开发基础知识

    通过上节的例子,我们发现Apache插件开发的一个门槛便是学习它自成体系的一套API.虽然Apache的官网上有对这些API的详细介绍,但是空拿着一些零散的说明书,是很难快速建立起一套可以运行的系统. ...

  5. CentOS4.4下邮件服务器架设笔记之windows AD整合功能实现

    1.通过"CentOS4.4下邮件服务器架设笔记之邮件网关功能实现"这一篇文章,我们已经实现了邮件网关功能,但是对于microsoft ad 平台下exchange邮件系统用户来说 ...

  6. 简述mysql字符集选择方法_MySQL字符集选择

    一. 怎样选择合适的字符集 对MySQL数据库来说,字符集很重要,因为数据库存储的数据大部分都是各种文字,字符集对数据库的存储,处理性能都会有所影响. 主要考虑一下几方面的因素 1.满足应用支持语言的 ...

  7. 服务器架设笔记——编译Apache及其插件

    之前一直从事Windows上的客户端软件开发,经常会处理和服务器交互相关的业务.由于希望成为一个全栈式的工程师,我对Linux上服务器相关的开发也越来越感兴趣.趁着年底自由的时间比较多,我可以对这块做 ...

  8. 服务器架设笔记——搭建用户注册和验证功能

    之前介绍的Apache Httpd相关内容,都是些零散的知识点.而实际运用中,我们要根据不同的业务,将这些知识点连接起来以形成各种组合,来满足我们的需求.(转载请指明出于breaksoftware的c ...

  9. RHCE课程-RH253Linux服务器架设笔记五-APACHE服务器配置(4)

    JSP(Java Server Pages)是由Sun Microsystems公司倡导.许多公司一起参与建立的一种基于Java技术的动态网页技术标准. Apache只是一个Web服务器,不能运行JS ...

最新文章

  1. Error writing file '/tmp/...' (Errcode: 28)
  2. 系统聚类(hierarchical clustering analysis)
  3. spring预加载与懒加载_通过Spring将继承树加载到List中
  4. arduino支持python吗_python能给arduino的板子编程吗?stm32支持吗?什么游戏引擎支持python?...
  5. HDFS写入HBase
  6. PyTorch:模型训练-模型参数parameters
  7. SoapUI接口测试工具测试webservice
  8. 如何进行信息化项目需求调研
  9. 苹果手机signin_苹果iphone弹出sign in to itunes store怎么办
  10. 科学研究设计五:实验设计
  11. oracle 将钱转换万元单位,oracle 金额单位转换
  12. Rhino6.9软件安装教程|兼容WIN10
  13. 【ESP 保姆级教程】疯狂传感器篇 —— 案例:ESP8266 + MQ3酒精传感器 + webserver(局域网内曲线变化图)
  14. 互联网日报 | 5月7日 星期五 | 街电与搜电完成合并;IBM发布2nm芯片制程;首届中国国际消费品博览会开幕...
  15. 如何在面试中回答 “你最大的缺点是什么?”
  16. Docker使用注意事项
  17. java反编译工具gd gson,浅谈Android中static修饰符,及Gson转String实例
  18. Kaggle:Home Credit Default Risk 特征工程构建及可视化(2)
  19. 未来计算机可能无处不在,未来计算机科学的发展趋势是什么?
  20. [Java笔记]day15

热门文章

  1. 机器学习四剑客1——Numpy
  2. ubuntu18.04上安装TensorFlow2.0
  3. 使用Python,OpenCV实现图像之间超快速的颜色转移
  4. deepspeech实时语音识别
  5. Linux那些事儿 之 戏说USB(9)面纱
  6. java利用递归画杨辉三角_用java程序编写杨辉三角形,初学者适用
  7. jmeter吞吐量图形显示_Jmeter系列(43)- 详解 Jmeter 图形化 HTML 压测报告之 Charts 模块...
  8. 基于简化点云地图的语义边缘对齐的单目定位方法
  9. Udacity机器人软件工程师课程笔记(二)-样本搜索和找回-基于漫游者号模拟器
  10. C和C++混合编程的Makefile的编写!