c++ poco 使用mysql中文乱码问题

poco 是c++ 一个比较好的库,现在正在学习使用它,碰到一些问题记录在此。

poco版本:poco-1.46-all ,带有数据库的支持模块

操作系统:ubuntu

1.使用poco的MySQL模块连接数据库,中文出现乱码

使用的例子是/poco-1.46-all/Data/samples/sqlite改的MySQL

mysql服务器的test数据库,全部是utf-8格式(数据库是8,表也是utf8),但是使用poco连接后,带中文的字段出现乱码

在命令行中输入

man mysql

MYSQL OPTIONS 节,看见如下设置

--default-character-set=charset_name

           Use charset_name as the default character set for the client and connection.

           A common issue that can occur when the operating system uses utf8 or another multi-byte character set is
           that output from the mysql client is formatted incorrectly, due to the fact that the MySQL client uses the
           latin1 character set by default. You can usually fix such issues by using this option to force the client
           to use the system character set instead.

           See Section 10.5, “Character Set Configuration”, for more information.

 关键就是这里,default-character-set对应的编码要和数据库的test库的编码一致

也就是说default-character-set设置为utf8才对

怎么在poco的mysql模块设置这个编码呢

看poco中的连接mysql代码如下:

    // register MySQL connector
    Poco::Data::MySQL::Connector::registerConnector();

    // create a session
    Session session(SessionFactory::instance().create("MySQL", "user=root;password=888;db=test"));

很自然的先去SessionFactory.cpp看是否有这个设置(Data/src/SessionFactory.cpp),没发现线索。

再去(Data/MySQL/src/)下面看看

先看Connector.cpp这个文件,发现一点点线索

Poco::AutoPtr<Poco::Data::SessionImpl> Connector::createSession(const std::string& connectionString)
{
    return Poco::AutoPtr<Poco::Data::SessionImpl>(new SessionImpl(connectionString));    
}

就是SessionImpl这个类型,这是真正的实现类

打开同目录下SessionImpl.cpp文件,发现这个类的构造函数中包含对connectionString的解析

std::map<std::string, std::string> options;

解析的结果全部放入上述的options中,

再朝下看,发现

//
    // Options
    //

    if (options["compress"] == "true")
    {
        _mysql.options(MYSQL_OPT_COMPRESS);
    }
    else if (options["compress"] == "false")
    {
        // do nothing
    }
    else if (options["compress"] != "")
    {
        throw MySQLException("create session: specify correct compress option (true or false) or skip it");
    }

还记得最开始的命令行 man mysql不,在 MYSQL OPTIONS 节其中就有一个compress的参数

 

_mysql.options(MYSQL_OPT_COMPRESS);

 

上述代码描述了怎么设置compress参数,看一下_mysql的类型

(Data/MySQL/include/Poco/Data/MySQL/sessionImpl.h)

 

SessionHandle _mysql;

 

是SessionHandle,然后查看(Data/MySQL/src/),SessionHandle.cpp(或SessionHandle.h)

void SessionHandle::options(mysql_option opt)
{
    int res = mysql_options(h, opt, 0);

    if (res != 0)
    {
        throw ConnectionException("mysql_options error", h);
    }
}

void SessionHandle::options(mysql_option opt, bool b)
{
    my_bool tmp = b;
    int res = mysql_options(h, opt, &tmp);

    if (res != 0)
    {
        throw ConnectionException("mysql_options error", h);
    }
}

 这里就是设置mysql options参数的地方,看见关键函数mysql_options

去google上查一下 mysql_options

这个http://dev.mysql.com/doc/refman/5.1/en/mysql-options.html

其中发现

MYSQL_OPT_COMPRESS (argument: not used) 
 MYSQL_SET_CHARSET_NAME (argument type: char *)

The name of the character set to use as the default character set. 

很明显现在我需要设置的 MYSQL_SET_CHARSET_NAME这个参数,它是个字符串类型

前面有个 compress的参数,它是bool的

找遍SessionHandle.cpp (.h)只有两个重载

void SessionHandle::options(mysql_option opt)

void SessionHandle::options(mysql_option opt, bool b)

没有设置字符串类型的,那么我们自己动手写了

继续看 http://dev.mysql.com/doc/refman/5.1/en/mysql-options.html

在最下面有例子

MYSQL mysql;
mysql_init(&mysql); mysql_options(&mysql,MYSQL_OPT_COMPRESS,0); mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc"); mysql_options(&mysql,MYSQL_INIT_COMMAND,"SET autocommit=0"); if (!mysql_real_connect(&mysql,"host","user","passwd","database",0,NULL,0)) { fprintf(stderr, "Failed to connect to database: Error: %s\n", mysql_error(&mysql)); }
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");这行就是设置字符串的

现在需要在SessionHandel.h增加一个函数声明
void options(mysql_option opt, char *c);
同时在SessionHandel.cpp实现
void SessionHandle::options(mysql_option opt, char *c)
{
    
    int res = mysql_options(h, opt, c);

    if (res != 0)
    {
        throw ConnectionException("mysql_options error", h);
    }
}

在SessionImpl.cpp文件的构造函数,最后如下

//
// Real connect
//
字符串之前增加如下语句
if (options["default-character-set"] != "")
{
    _mysql.options(MYSQL_SET_CHARSET_NAME, options["default-character-set"].c_str());
}


最后,把开始的poco中的连接mysql代码改成如下
    // register MySQL connector
    Poco::Data::MySQL::Connector::registerConnector();

    // create a session
    //Session session("user=root;password=888;db=test");
      Session session(SessionFactory::instance().create("MySQL", "user=root;password=888;db=test;default-character-set=utf8"));
    

编译,并查看一下,中文不再乱码了,^_^

使用相同的方法,可以给poco的mysql添加其它设置支持。

转载于:https://www.cnblogs.com/simfe/p/3162584.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL中文数字同时出现导致乱码问题一般是由于字符集设置不正确所导致的。在编写MySQL查询时,我们需要确保数据库连接使用的是正确的字符集。 首先,我们需要确认MySQL数据库的字符集设置。可以通过执行以下查询语句来查看数据库当前的字符集设置: ```sql SHOW VARIABLES LIKE 'character_set%'; ``` 确保以下两个参数的值是utf8或utf8mb4: - character_set_client - character_set_connection 如果字符集设置不正确,我们可以通过以下方式来修复这个问题。 1. 修改MySQL配置文件:可以编辑MySQL配置文件my.cnf或my.ini,并在[mysqld]部分添加以下两行配置: ```bash [mysqld] character_set_server = utf8mb4 collation_server = utf8mb4_unicode_ci ``` 2. 修改数据库的默认字符集:可以通过执行以下命令来修改数据库的默认字符集: ```sql ALTER DATABASE database_name DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` 需要将database_name替换为实际的数据库名。 3. 修改表的字符集:可以通过执行以下命令来修改表的字符集: ```sql ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ``` 需要将table_name替换为实际的表名。 4. 修改连接时的字符集:可以在连接MySQL数据库时指定字符集,例如在连接Java应用程序时可以使用以下代码: ```java String url = "jdbc:mysql://localhost:3306/database_name?useUnicode=true&characterEncoding=utf8mb4"; Connection conn = DriverManager.getConnection(url, username, password); ``` 需要将database_name替换为实际的数据库名。 通过以上步骤,我们可以解决MySQL中文数字同时出现导致的乱码问题。确保数据库连接使用的字符集与文本数据的字符集一致,即可正确显示中文数字。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值