本記事では、MySQL Connector/C (libmysqlclient)ドライバーを使用してOceanBaseデータベースに接続し、使用する方法について説明します。
前提条件
MySQL Connector/C (libmysqlclient)をインストールして使用する前に、基本的なデータベース開発環境が設定されていることを確認してください。要件は以下のとおりです:
GCCのバージョンは3.4.6以上、推奨バージョンは4.8.5です。
CMakeのバージョンは2.8.12以上です。
Cアプリケーションの作成
ステップ1:データベース接続文字列の取得
OceanBaseデータベースのデプロイ担当者または管理者から、該当するデータベース接続文字列を取得します。例:
obclient -h100.88.xx.xx -uroot@test -p****** -P2881 -Doceanbase
データベース接続文字列には、データベースへのアクセスに必要なパラメータ情報が含まれています。アプリケーションを作成する前に、データベース接続文字列を用いてデータベースへのログインを検証し、接続文字列のパラメータが正確であるか確認することができます。
パラメータの説明:
- -h:OceanBaseデータベースへの接続IPアドレス。ODP (OceanBase Database Proxy)のアドレスである場合もあります。
- -u:テナントの接続ユーザー名。書式はユーザー@テナント#クラスタ名となります。クラスタのデフォルトテナントは sys、テナントのデフォルト管理者ユーザーは root です。データベースへ直接接続する場合はクラスタ名を指定しませんが、ODP経由で接続する際は指定が必要です。
- -p:ユーザーのパスワードです。
- -P:OceanBaseデータベースの接続ポート番号であり、ODPのリスニングポートでもあります。
- -D:接続対象のデータベース名です。
ステップ2:MySQL Connector/Cドライバーのインストール
yumを使用したMariadbクライアントのインストール
Mariadbクライアントをインストールします。
sudo yum install mariadb-devel
ステップ3:アプリケーションの作成
アプリケーションは、MySQL Connector/Cを使用し、データベースサーバーであるOBServerノードとやり取りする基本的な手順は、以下の通りです。
mysql_library_init()を呼び出してMySQLライブラリを初期化します。mysql_library_init(0, NULL, NULL);mysql_init()を呼び出して接続ハンドルを初期化します。MYSQL *mysql = mysql_init(NULL);mysql_real_connect()を呼び出してOBServerノードに接続します。mysql_real_connect (mysql, host_name, user_name, password, db_name, port_num, socket_name, CLIENT_MULTI_STATEMENTS)mysql_real_query()またはmysql_query()を呼び出して、OBServerノードにSQL文を送信します。mysql_query(mysql,"sql_statement");mysql_store_result()またはmysql_use_result()を呼び出して、その結果を処理します。result=mysql_store_result(mysql);mysql_free_result()を呼び出して、メモリをリリースします。mysql_free_result(result);mysql_close()を呼び出して、OBServerノードとの接続をクローズします。mysql_close(mysql);mysql_library_end()を呼び出して、MariaDBクライアントの使用を終了します。mysql_library_end();
サンプルコード
mysql_test.cファイルを例として、コードは以下の通りです。
#include "mysql.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
mysql_library_init(0, NULL, NULL);
MYSQL *mysql = mysql_init(NULL);
char* host_name = "xxx.xxx.xxx.xxx";//set your mysql host
char* user_name = "******"; //set your user_name
char* password = "******"; //set your password
char* db_name = "test"; //set your databasename
int port_num = 2883; //set your mysql port
char* socket_name = NULL;
MYSQL_RES* result;
MYSQL_FIELD* fields;
MYSQL_ROW row;
int status = 0;
/* connect to server with the CLIENT_MULTI_STATEMENTS option */
if (mysql_real_connect (mysql, host_name, user_name, password,
db_name, port_num, socket_name, CLIENT_MULTI_STATEMENTS) == NULL)
{
printf("mysql_real_connect() failed\n");
mysql_close(mysql);
exit(1);
}
/* execute multiple statements */
status = mysql_query(mysql, "DROP TABLE IF EXISTS test_table;");
if (status)
{
printf("Could not execute statement(s)");
mysql_close(mysql);
exit(0);
}
status = mysql_query(mysql, "CREATE TABLE test_table(id INT,name varchar(24));");
status = mysql_query(mysql, "INSERT INTO test_table VALUES(10,'hangzhou'),(20,'shanghai');");
status = mysql_query(mysql, "UPDATE test_table SET id=20 WHERE id=10;");
status = mysql_query(mysql, "SELECT * FROM test_table;");
/* did current statement return data? */
result = mysql_store_result(mysql);
if (result)
{
/* yes; process rows and free the result set */
//process_result_set(mysql, result);
int num_fields = mysql_num_fields(result);
int num_rows = mysql_num_rows(result);
printf("result: %d rows %d fields\n", num_rows, num_fields);
printf("---------------------\n");
fields = mysql_fetch_fields(result);
for (int i = 0; i < num_fields; ++i)
{
printf("%s\t", fields[i].name);
}
printf("\n---------------------\n");
while ((row = mysql_fetch_row(result)))
{
for (int i = 0; i < num_fields; ++i)
{
printf("%s\t", row[i] ? row[i] : "NULL");
}
printf("\n");
}
printf("---------------------\n");
mysql_free_result(result);
}
else /* no result set or error */
{
if (mysql_field_count(mysql) == 0)
{
printf("%lld rows affected\n",
mysql_affected_rows(mysql));
}
else /* some error occurred */
{
printf("Could not retrieve result set\n");
}
}
status = mysql_query(mysql, "DROP TABLE test_table;");
mysql_close(mysql);
return 0;
}
コード内のデータベース接続パラメータ、ご自身の環境に合わせて修正してください。以下の項目を参考に、「ステップ1」で取得したデータベース接続文字列の対応する値を設定します。
host_name:
-hの値を使用します。OceanBaseデータベースへの接続IPアドレス。ODP (OceanBase Database Proxy)のアドレスである場合もあります。user_name:
-uの値を使用します。テナントの接続ユーザー名で、書式はユーザー@テナント#クラスタ名となります。クラスタのデフォルトテナントは'sys'、テナントのデフォルト管理者ユーザーは'root'です。データベースに直接接続する場合は、クラスタ名の部分は不要ですが、ODP経由で接続する場合は指定する必要があります。password:
-pの値を使用します。ユーザーのパスワードです。db_name:
-Dの値を使用します。接続対象のデータベース名です。port_num:
-Pの値を使用します。OceanBaseデータベースの接続ポート番号であり、ODPのリスニングポートでもあります。
ステップ4:アプリケーションの実行
コードの編集が完了したら、以下のコマンドでコンパイルが可能になります。
g++ -I/usr/include/mysql/ -L/usr/lib64/mysql/ -lmysqlclient mysql_test.c -o mysql_testオプションの説明:
-Iオプション:コンパイラの検索パスを指定して、ヘッダーファイルを検出できるようにします。例えば、mysql.hヘッダーファイルが配置されているディレクトリ/usr/include/mysqlをコンパイラの検索パスに追加することで、mysql.hヘッダーファイルを検出できるようになります。find / -name mysql.h 2>/dev/nullコマンドでmysql.hファイルのパスを検索できます。-Lオプション:ダイナミックリンクライブラリの検索パスを指定します。-lオプション:リンクするライブラリファイルを指定します。-lオプションを使用する場合、ライブラリファイル名から接頭辞のlibと接尾辞の.soを省略します。例えば、上記のコマンドでライブラリファイル名がlibmysqlclient.soの場合、-lオプションではmysqlclientとだけ指定します。
実行パスを指定します。
export LD_LIBRARY_PATH=/usr/lib64/mysql以下のコマンドを使用して、アプリケーションを実行します。
./mysql_test以下の結果が出力された場合は、データベースへの接続に成功し、サンプル文が正しく実行されたことを意味します。
--------------------- id name --------------------- 20 hangzhou 20 shanghai ---------------------