【译】Simple MySQL ORM for C

Jun 07, 2016 pm 03:46 PM
for mysql or orm simple

一直不知道有ORM这种东西,直到和 @海坡 交流后才接触。 在项目中,需要将数据存储到数据库中,首先想到的是生成各种raw SQL的解决方法。但随着项目的进展,发现它很不灵活。譬如可能因为有新的需求,在数据库student表中添加dept_no字段,那在各种raw SQ中

一直不知道有ORM这种东西,直到和 @海坡 交流后才接触。

在项目中,需要将数据存储到数据库中,首先想到的是生成各种raw SQL的解决方法。但随着项目的进展,发现它很不灵活。譬如可能因为有新的需求,在数据库student表中添加dept_no字段,那在各种raw SQ中就需要进行修改了,工程浩大。如果操作(插入\修改\删除)数据库表中的数据,和操作数据对象一样,可以简化很多的操作,便于数据层的变更,而不必修改逻辑层代码。

//项目随手摘录的一个构造插入指定对象数据的INSERT语句的方法。
int gtd_genInsertSql(struct task_t &toinsert,char *sql, int nUserID)
{
    int curr = 0;

    //task_id | user_id | strtext
    curr += sprintf(sql,"insert into task values(%d,%d,'%s',",
        toinsert.id,nUserID/*user_id*/,toinsert.strtext);

    //ctime    
    char buffer[32];
    ::memset(buffer,0,sizeof(buffer));

    strftime(buffer,32,"'2012-%m-%d %H-%M-%S',",&(toinsert.ctime));
    strncpy(sql+curr,buffer,strlen(buffer));
    curr += strlen(buffer);
......
    *(sql + curr) = ')';
    curr++;
    return curr;
}
ログイン後にコピー

ORM,即对象关系映射,ORM的设计就是数据库持久层的设计。目前流行有一些成熟的ORM框架,对应各种语言都有。

因为项目实际需要,挑选了一个轻便的框架:Simple MySQL ORM for C。google了下,只发现有Simple MySQL ORM for C作者的一篇英文博文介绍而已:http://ales.jikos.cz/smorm/。「打米量家底」,因为那篇文章不太长,所以把它翻译过来了。记得年前 @独酌逸醉 有提到过,他有翻译StackOverFlow上的精华帖。现在看来,譬如对C++熟悉,完全可以去看看外国的程序员社区。一方面你本身是程序员,专业对口,认得大多数单词;另一方面,国外高手也多,不为是提高技术的好机会;最后,它确实提高英语的好方法,赞一个。

http://ales.jikos.cz/smorm/

【译】Simple MySQL ORM for C

作者:alesak

c版本Simple MySQL ORM是用python的脚本完成的,它可以用来连接已经创建的MySQL数据库,读取数据库表所对应的数据结构,当然,也可以通过此数据结构和方法创建表。这些可以让开发者使用c语言很方便的更新/修改/删除数据库中的数据。

之前,笔者需要在强大的数据库里面存储检索结构化数据。笔者更倾向于使用MySQL和c语言。但笔者对自己写的粗糙代码和互联网上找到的巨费资源的解决方案已经很厌烦了,所以干脆自己写了一个。很简单,很天真,下笔粗糙(python不是笔者的母语,抱歉了)。但相信情人眼里出西施,笔者想象着让它更有用一点。还有,关于它的文档。。。

考虑到这只是一个技术文章,而不是一个使用手册。笔者最后取消了此文章提到的项目,所以它有待考验。不支持MySQL里头的一些数据类型。这个项目的起因之一是笔者不喜欢MySQL提供的c api,所以代之以“更时髦”的万事俱备的api~但,笔者发现它有些地方还不够好,因为笔者还没完成。

让我们开始吧。首先,你必须创建你的数据库表。笔者更喜欢一下这种方式,因为只有这样才能更充分使用数据库。

CREATE DATABASE ex1;

CREATE TABLE ex_customer (
  id int NOT NULL auto_increment,
  name char(32),
  PRIMARY KEY  (id)
);

CREATE TABLE ex_item (
  customer_id int,
  itemname char(32)
);
ログイン後にコピー

接下来,我们创建一个简单的python脚本db.py:

dbname = "ex1"
name = "db"
tables = { }
ログイン後にコピー

在接下来,让它执行吧 :P

python rdb.py
ログイン後にコピー

当然,比起真正的rock,少点听觉享受。可能你会问,笔者到底要怎么连接到数据库啊?当然,那些只是默认用户写的……但看看我们得到的结果。我们可以已经有两个文件产生了,分别是:db.h和db.c。前者包含是象征数据库表的数据结构声明和操作这些数据结构的方法;后者包含了方法的定义,接着的是数据初始化的语句。我们来看看:

typedef struct db_ex_customer {
        int id;
        char * name;
} db_ex_customer;

typedef struct db_ex_item {
        int customer_id;
        char * itemname;
} db_ex_item;
ログイン後にコピー

相信没有进一步解释这些东西的必要。让我们使用它们吧!笔者新建了ex1.c文件。注意:为了更容易读懂代码,笔者没有处理错误的返回值:

#include <db.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

int main (int argc, char **argv)
{
	int ret;
	MYSQL global_mysql;
	MYSQL *m;

	db_ex_customer *cust1;
	db_ex_item *item1, *item2;

	mysql_init (& global_mysql);

	/*
	 * connect to MySQL as usual
	 */
	m = mysql_real_connect (& global_mysql, "localhost", "root", "", "ex1", 3036, NULL, 0);

	/*
	 * pass the MySQL connection to function, that initializes the "ORM"
	 */
	ret = db_init (& global_mysql);

	/*
	 * the *__new method creates empty structure
	 */
	cust1 = db_ex_customer__new ();
	/*
	 * setting the structure attribute with allocated string,
	 * it will be freed during call of *__free method
	 */
	cust1->name = strdup ("alesak");

	/*
	 * this method inserts the structure into according table.
	 * If it has serial field, its value is reflected into structure
	 */
	ret = db_ex_customer__insert (cust1);

	item1 = db_ex_item__new ();
	/*
	 * let's use the serial value from newly inserted customer
	 */
	item1->customer_id = cust1->id;
	item1->itemname = strdup ("simple orm");

	ret = db_ex_item__insert (item1);

	item2 = db_ex_item__new ();
	item2->customer_id = cust1->id;
	item2->itemname = strdup ("advanced orm");

	ret = db_ex_item__insert (item2);

	db_ex_customer__free (cust1);
	db_ex_item__free (item1);
	db_ex_item__free (item2);

	return (0);
}</time.h></string.h></stdio.h></db.h>
ログイン後にコピー

编译下:

cc -I `mysql_config --cflags` ex1.c db.c `mysql_config --libs` -o ex1
ログイン後にコピー

运行可执行文件,发现它没错。这意味着,它已经一些数据已被存储。至少如果你让评价它,笔者会说很优雅。接下来,怎么去检索这些数据?假设,我们已经知道数据库表中记录的键值,笔者又新建了ex2.c文件。

#define _XOPEN_SOURCE 500
#include <db.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

int main (int argc, char **argv)
{
	int ret;
	MYSQL global_mysql;
	MYSQL *m;

	db_ex_customer *cust1;
	db_ex_item *item1, *item2;

	mysql_init (& global_mysql);

	m = mysql_real_connect (& global_mysql, "localhost", "root", "", "ex1", 3036, NULL, 0);

	ret = db_init (& global_mysql);

	cust1 = db_ex_customer__get_by_id (3);
	if (cust1) {
		fprintf (stdout, "I have customer named \'%s\'\n", cust1->name);
		db_ex_customer__free (cust1);
	}

	return (0);
}</time.h></string.h></stdio.h></db.h>
ログイン後にコピー

跟前边一样,编译,然后执行:

cc -I. `mysql_config --cflags` ex2.c db.c `mysql_config --libs` -o ex2
./ex2
ログイン後にコピー

最后,笔者不想让ORM自动创建相关数据的查询,因为笔者相信它能做的好。(老实说,如果使用默认的MyISAM,它不可能判断相关数据)。当然,接下来笔者想要新建笔者自己的、超复杂的ex_items表与ex_customer标连接后的SELECT检索。编辑一下db.py:

dbname = "ex1"
name = "db"
tables = {
		"ex_item" :[("get", "get_customer_items",
			[("INTEGER", "customer_id")], "SELECT ex_item.* FROM ex_item WHERE customer_id = ?")]
	}
ログイン後にコピー

重新执行db.puy脚本会添加新的db_ex_item__get_customer_items_*方法集。这些方法灵活之处在于,可以增加INTEGER类型的参数,在特定的SQL上打开游标:从游标读取一行记录,关闭游标。我们扩展ex2.c:

#define _XOPEN_SOURCE 500
#include <db.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

int main (int argc, char **argv)
{
	int ret;
	MYSQL global_mysql;
	MYSQL *m;

	db_ex_customer *cust1;
	db_ex_item *item1, *item2;

	mysql_init (& global_mysql);

	m = mysql_real_connect (& global_mysql, "localhost", "root", "", "ex1", 3036, NULL, 0);

	ret = db_init (& global_mysql);

	cust1 = db_ex_customer__get_by_id (3);
	if (cust1) {
		fprintf (stdout, "I have customer named \'%s\'..\n", cust1->name);

		db_ex_item__get_customer_items_open (cust1->id);

		while ((item1 = db_ex_item__get_customer_items_fetch ()) != NULL) {
			fprintf (stdout, ".. and found his item named \'%s\'\n", item1->itemname);
			db_ex_item__free (item1);
		}
		db_ex_item__get_customer_items_close ();

		db_ex_customer__free (cust1);
	}

	return (0);
}</time.h></string.h></stdio.h></db.h>
ログイン後にコピー

得偿所愿,它打印的结果:

I have customer named 'alesak'..
.. and found his item named 'simple orm'
.. and found his item named 'advanced orm'
ログイン後にコピー

以上,朋友们!这里是http://ales.jikos.cz/smorm/rdb.py 脚本。更确切的说,别下载这个破烂东西。但如果你喜欢这个点子,请告诉笔者:alesak#gmail.com。全文完。

感谢作者 @alesak。Simple MySQL ORM for C我没有亲手测试,找时间补上测试篇。另,笔者水平有限,欢迎扶正拍砖。以上。

捣乱 2013-3-22

http://daoluan.net

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MySQLテーブルロックテーブルを変更するかどうか MySQLテーブルロックテーブルを変更するかどうか Apr 08, 2025 pm 05:06 PM

MySQLがテーブル構造を変更すると、メタデータロックが通常使用され、テーブルがロックされる可能性があります。ロックの影響を減らすために、次の測定値をとることができます。1。オンラインDDLでテーブルを使用できます。 2。バッチで複雑な変更を実行します。 3.小規模またはオフピーク期間中に操作します。 4. PT-OSCツールを使用して、より細かい制御を実現します。

MySQLユーザーとデータベースの関係 MySQLユーザーとデータベースの関係 Apr 08, 2025 pm 07:15 PM

MySQLデータベースでは、ユーザーとデータベースの関係は、アクセス許可と表によって定義されます。ユーザーには、データベースにアクセスするためのユーザー名とパスワードがあります。許可は助成金コマンドを通じて付与され、テーブルはCreate Tableコマンドによって作成されます。ユーザーとデータベースの関係を確立するには、データベースを作成し、ユーザーを作成してから許可を付与する必要があります。

mysqlは支払う必要がありますか mysqlは支払う必要がありますか Apr 08, 2025 pm 05:36 PM

MySQLには、無料のコミュニティバージョンと有料エンタープライズバージョンがあります。コミュニティバージョンは無料で使用および変更できますが、サポートは制限されており、安定性要件が低く、技術的な能力が強いアプリケーションに適しています。 Enterprise Editionは、安定した信頼性の高い高性能データベースを必要とするアプリケーションに対する包括的な商業サポートを提供し、サポートの支払いを喜んでいます。バージョンを選択する際に考慮される要因には、アプリケーションの重要性、予算編成、技術スキルが含まれます。完璧なオプションはなく、最も適切なオプションのみであり、特定の状況に応じて慎重に選択する必要があります。

高負荷アプリケーションのMySQLパフォーマンスを最適化する方法は? 高負荷アプリケーションのMySQLパフォーマンスを最適化する方法は? Apr 08, 2025 pm 06:03 PM

MySQLデータベースパフォーマンス最適化ガイドリソース集約型アプリケーションでは、MySQLデータベースが重要な役割を果たし、大規模なトランザクションの管理を担当しています。ただし、アプリケーションのスケールが拡大すると、データベースパフォーマンスのボトルネックが制約になることがよくあります。この記事では、一連の効果的なMySQLパフォーマンス最適化戦略を検討して、アプリケーションが高負荷の下で効率的で応答性の高いままであることを保証します。実際のケースを組み合わせて、インデックス作成、クエリ最適化、データベース設計、キャッシュなどの詳細な主要なテクノロジーを説明します。 1.データベースアーキテクチャの設計と最適化されたデータベースアーキテクチャは、MySQLパフォーマンスの最適化の基礎です。いくつかのコア原則は次のとおりです。適切なデータ型を選択し、ニーズを満たす最小のデータ型を選択すると、ストレージスペースを節約するだけでなく、データ処理速度を向上させることもできます。

MySQLのクエリ最適化は、特に大規模なデータセットを扱う場合、データベースのパフォーマンスを改善するために不可欠です MySQLのクエリ最適化は、特に大規模なデータセットを扱う場合、データベースのパフォーマンスを改善するために不可欠です Apr 08, 2025 pm 07:12 PM

1.正しいインデックスを使用して、データの量を削減してデータ検索をスピードアップしました。テーブルの列を複数回検索する場合は、その列のインデックスを作成します。あなたまたはあなたのアプリが基準に従って複数の列からのデータが必要な場合、複合インデックス2を作成します2。選択した列のみを避けます。必要な列のすべてを選択すると、より多くのサーバーメモリを使用する場合にのみサーバーが遅くなり、たとえばテーブルにはcreated_atやupdated_atやupdated_atなどの列が含まれます。

RDS MySQL Redshift Zero ETLとの統合 RDS MySQL Redshift Zero ETLとの統合 Apr 08, 2025 pm 07:06 PM

データ統合の簡素化:AmazonrdsmysqlとRedshiftのゼロETL統合効率的なデータ統合は、データ駆動型組織の中心にあります。従来のETL(抽出、変換、負荷)プロセスは、特にデータベース(AmazonrdsmysQlなど)をデータウェアハウス(Redshiftなど)と統合する場合、複雑で時間がかかります。ただし、AWSは、この状況を完全に変えたゼロETL統合ソリューションを提供し、RDSMYSQLからRedshiftへのデータ移行のための簡略化されたほぼリアルタイムソリューションを提供します。この記事では、RDSMysQl Zero ETLのRedshiftとの統合に飛び込み、それがどのように機能するか、それがデータエンジニアと開発者にもたらす利点を説明します。

MySQLのユーザー名とパスワードを入力する方法 MySQLのユーザー名とパスワードを入力する方法 Apr 08, 2025 pm 07:09 PM

MySQLのユーザー名とパスワードを入力するには:1。ユーザー名とパスワードを決定します。 2。データベースに接続します。 3.ユーザー名とパスワードを使用して、クエリとコマンドを実行します。

MySQL:初心者向けのデータ管理の容易さ MySQL:初心者向けのデータ管理の容易さ Apr 09, 2025 am 12:07 AM

MySQLは、インストールが簡単で、強力で管理しやすいため、初心者に適しています。 1.さまざまなオペレーティングシステムに適した、単純なインストールと構成。 2。データベースとテーブルの作成、挿入、クエリ、更新、削除などの基本操作をサポートします。 3.参加オペレーションやサブクエリなどの高度な機能を提供します。 4.インデックス、クエリの最適化、テーブルパーティション化により、パフォーマンスを改善できます。 5。データのセキュリティと一貫性を確保するために、バックアップ、リカバリ、セキュリティ対策をサポートします。

See all articles