在C中将MySQL结果转换为JSON字符串
如何在C中将MySQL查询的结果转换为JSON字符串 当然我知道怎么做,我只是想知道是否已经有了复制粘贴的解决方案,意识到我不想写锅炉板代码在C中将MySQL结果转换为JSON字符串,mysql,c,json,Mysql,C,Json,如何在C中将MySQL查询的结果转换为JSON字符串 当然我知道怎么做,我只是想知道是否已经有了复制粘贴的解决方案,意识到我不想写锅炉板代码 我如何搜索这个问题?Google只是忽略了c,并显示PHP等的结果。我制作的c文件比相应的PHP文件快四倍,使用ab来衡量性能: ab -k -c 300 -n 10000 localhost/tiny.php Time per request: 393.072 [ms] (mean) 用C: ab -k -c 300 -n 10000 l
我如何搜索这个问题?Google只是忽略了
c
,并显示PHP等的结果。我制作的c文件比相应的PHP文件快四倍,使用ab
来衡量性能:
ab -k -c 300 -n 10000 localhost/tiny.php
Time per request: 393.072 [ms] (mean)
用C:
ab -k -c 300 -n 10000 localhost/cgi/tiny.fcgi
Time per request: 98.237 [ms] (mean)
这是假设Apache生成了10个进程tiny.fcgi
,而PHP不使用FastCGI
FastCgiServer /var/www/cgi/tiny.fcgi -processes 10
这是PHP代码,它连接到MySQL,获取查询结果并回显JSON表示:
<?php
$mysqli = mysqli_connect("localhost", "user", "password", "db");
mysqli_set_charset($mysqli, "utf8");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$result = mysqli_query($mysqli, "SELECT * FROM table");
$rows = array();
while ($row = mysqli_fetch_assoc($result)) {
$rows[] = $row;
}
echo json_encode($rows);
用valgrind
分析这个问题,最后给出768字节仍然可以访问,我们将忽略它(可能是FastCGI中的错误)
接下来是MySQL连接和查询:
MYSQL* connection = NULL;
MYSQL_RES* result = NULL;
connection = mysql_init(NULL);
if (connection == NULL)
{
(void) FCGI_fprintf(FCGI_stderr, "Could not connect to MySQL: %s\n", mysql_error(connection));
continue;
}
// Connect to database
if (mysql_real_connect(connection, "localhost", "user", "password", "db", 0, NULL, 0) == NULL)
{
close_mysql_with_error(connection);
continue;
}
// Select from pages
if (mysql_query(connection, "SELECT * FROM table") != 0)
{
close_mysql_with_error(connection);
continue;
}
// Get result
result = mysql_store_result(connection);
// Abort if no result
if (result == NULL)
{
close_mysql_with_error(connection);
continue;
}
(我使用continue
而不是exit
或return
,因为此代码位于上面看到的while
循环中。)
这里没什么奇怪的,对吧
下一部分将创建我们的smart\u str
JSON变量,将它传递给函数result\u到\u JSON
,然后回显结果
smart_str json = {0, 0, 0};
result_to_json(result, &json);
if (json.c != NULL)
(void) FCGI_printf("json = %s\n", json.c);
smart_str_free(&json);
result\u to_json
只是MySQL结果行上的一个循环:
static void result_to_json(MYSQL_RES *result, smart_str* json)
{
MYSQL_ROW row;
int i;
int num_fields = (int) mysql_num_fields(result);
smart_str** fields = get_field_names(result, num_fields);
if (fields == NULL)
{
return;
}
smart_str_appendc(json, '[');
while ((row = mysql_fetch_row(result, num_fields)))
{
smart_str_appendl(json, "{", 1);
for (i = 0; i < num_fields; i++)
{
// key
smart_str_appendl(json, "\"", 1);
smart_str_appendl(json, fields[i]->c, fields[i]->len);
smart_str_appendl(json, "\": ", 3);
if (row[i] == NULL)
{
smart_str_appendl(json, "null", 4);
smart_str_appendl(json, ", ", 2);
}
else
{
smart_str_appendl(json, "\"", 1);
smart_str_appendl(json, row[i], strlen(row[i]));
smart_str_appendl(json, "\", ", 3);
}
}
if (json == NULL) {
free_field_names(fields, num_fields);
return;
}
// Strip last ','
json->len--;
json->len--;
smart_str_appendl(json, "}, ", 3);
}
if (json == NULL)
{
free_field_names(fields, num_fields);
return;
}
// Strip last ','
json->len--;
json->len--;
smart_str_appendl(json, "]", 1);
smart_str_0(json);
free_field_names(fields, num_fields);
return;
}
好了!剩下要做的就是对照支持FastCGI的PHP进行测量,看看PHP性能有多大的提高 ,向下滚动查看一长串语言/库。@MarcB您是说
json-c
?这将如何帮助我转换一个MYSQL\u行
?使用一个C库,您将迭代结果集中的每一行,使用列名信息和返回值创建JSON格式的数据。主要问题是您希望字符串存储在哪里(哪个代码将分配它;哪个代码将释放它,等等)。也许您希望一个版本的代码在运行时写入文件,而不是将整个字符串存储在内存中。因此,您应该能够编写一个通用函数(或一组函数)来与您选择的JSON库和MySQL配合使用。Google对“MySQL JSON”的搜索表明,web上有很多关于在MySQL中处理JSON的信息。MySQL 5.7中甚至有内置的支持。@OlleHärstedt:在某种程度上,您需要学习如何使用基本工具,并找出如何将这些基本工具串联在一起以产生复杂的结果。e、 g.从mysql开始,找出如何从mysql中获取结果字符串,然后将其输入json库。您可以跳过FastCGI,生成apache模块,使其更快:)
static void result_to_json(MYSQL_RES *result, smart_str* json)
{
MYSQL_ROW row;
int i;
int num_fields = (int) mysql_num_fields(result);
smart_str** fields = get_field_names(result, num_fields);
if (fields == NULL)
{
return;
}
smart_str_appendc(json, '[');
while ((row = mysql_fetch_row(result, num_fields)))
{
smart_str_appendl(json, "{", 1);
for (i = 0; i < num_fields; i++)
{
// key
smart_str_appendl(json, "\"", 1);
smart_str_appendl(json, fields[i]->c, fields[i]->len);
smart_str_appendl(json, "\": ", 3);
if (row[i] == NULL)
{
smart_str_appendl(json, "null", 4);
smart_str_appendl(json, ", ", 2);
}
else
{
smart_str_appendl(json, "\"", 1);
smart_str_appendl(json, row[i], strlen(row[i]));
smart_str_appendl(json, "\", ", 3);
}
}
if (json == NULL) {
free_field_names(fields, num_fields);
return;
}
// Strip last ','
json->len--;
json->len--;
smart_str_appendl(json, "}, ", 3);
}
if (json == NULL)
{
free_field_names(fields, num_fields);
return;
}
// Strip last ','
json->len--;
json->len--;
smart_str_appendl(json, "]", 1);
smart_str_0(json);
free_field_names(fields, num_fields);
return;
}
static smart_str** get_field_names(MYSQL_RES *my_result, int num_fields)
{
smart_str** fields; // Array of pointers
MYSQL_FIELD *field = NULL;
int i;
// Allocate size of array
fields = malloc(num_fields * sizeof(smart_str*));
if (fields == NULL)
{
return NULL;
}
for (i = 0; i < num_fields; i++)
{
field = mysql_fetch_field(my_result);
if (field == NULL) {
// TODO: Free fields[]
free(fields);
return NULL;
}
fields[i] = malloc(sizeof(smart_str));
if (fields[i] == NULL) {
// TODO: Free fields[]
free(fields);
return NULL;
}
else
{
fields[i]->c = NULL;
smart_str_appendl(fields[i], field->name, strlen(field->name));
}
return fields;
}
static void free_field_names(smart_str** strings, int size)
{
int i;
for (i = 0; i < size; i++)
{
smart_str_free(strings[i]);
free(strings[i]);
}
free(strings);
}