mysql orm c语言_【译】Simple MySQL ORM for C

一直不知道有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++熟悉,完全可以去看看外国的程序员社区。一方面你本身是程序员,专业对口,认得大多数单词;另一方面,国外高手也多,不为是提高技术的好机会;最后,它确实提高英语的好方法,赞一个。

下面是《Simple MySQL ORM for 》的译文,原文链接: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

#include

#include

#include

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);

}

编译下:

cc -I `mysql_config --cflags` ex1.c db.c `mysql_config --libs` -o ex1

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

#define _XOPEN_SOURCE 500

#include

#include

#include

#include

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);

}

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

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

#include

#include

#include

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);

}

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

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://www.mzph.cn/news/528422.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ruby mysql 占位符_ruby操作常用数据库

使用Ruby DBI模块目录Ruby DBI模块为ruby程序访问数据库提供了一个与数据库无关的接口,就像perl的DBI模块一样。这篇文章将讲述如何编写基于DBI的ruby程序。这篇文章是对DBI规范文档(specification documents)的补充,而不是要替代规范文档,更…

threejs获取模型坐标_Threejs倒影实现解析

倒影是在自然界中非常常见的一种现象,例如水面倒影、镜子。我们都知道,眼睛之所以能够看到某个物体,是因为物体本身能够发光或者物体能够反射其它的物体所发的光,这些光进入到我们的眼里就形成了该物体影像。倒影形成也是一种光学…

aws java mysql_java - AWS EC2 / MySql - spring boot无法从datasource确定jdbc url - 堆栈内存溢出...

我有一个简单的Spring Boot应用程序,我试图在基于Amazon AMI的Amazon EC2实例上部署。 它使用MySql数据库(版本8.0.15)。我在AWS上创建了数据库,当我从本地系统指向它的配置时,它可以工作。 我也可以从MySql Workbench访问它。但是当我将Spri…

debian 删除mysql数据库_Debian中完全卸载MySQL的方法

作者: 字体:[增加 减小] 类型:转载这篇文章主要介绍了Debian中完全卸载MySQL的方法,同时介绍了清理方法,可以做到彻底卸载mysql,需要的朋友可以参考下之前服务器上配置测试用的服务环境,我偷懒顺手用网上现成的脚本进行安装&#…

python123外汇兑换计算器_Python 3.x--使用re模块,实现计算器运算实例

1 importre23 #乘除运算处理,可以处理不含括号的加减和乘除函数(只处理乘除)4 defmulti_and_divi(arg):5 #传入参数为列表,如:[3*2-1*9/3,0]6 val arg[0]7 #对字符串进行乘除匹配:如3*2-1*9/3,就匹配:3*28 …

python修改文件名字数字_python实现多进程按序号批量修改文件名的方法示例

本文实例讲述了python实现多进程按序号批量修改文件名的方法。分享给大家供大家参考,具体如下:说明文件名命名方式如图,是数字序号开头,但是中间有些文件删掉了,序号不连续,这里将序号连续起来,…

遗传算法求函数最大值实验_小知识:什么是遗传算法

1 什么是遗传算法遗传算法(GeneticAlgorithm, GA)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法。其主要特点是直接对结构对象进行操作,不存在求导和函数连续性的限定;…

$dbms=mysql_Oracle dbms

Oracle dbms_random包的用法 Oracle dbms_random包的用法 1.dbms_random.value方法 dbms_random是一个可以生成随机数或者字符串的程序包。这个包有initialize()、seed()、terminate()、value()、normal()、random()、string()等几个函数,但value()是最常用Oracle d…

js定位div坐标存入mysql_JavaScript与Div 对层定位和移动获得坐标

1:移动图层 获得点的x轴y轴坐标,从而进行绝对定位(注意:竖拉框会影响 x 轴 y 轴坐标值)var x,y,z,downfalse,objfunction init(){objevent.srcElement //事件触发对象obj.setCapture() //设置属于当前对象的鼠标捕捉zobj.style.zIndex …

mysql 不指定 长度吗_mysql中整数类型后面的数字,是不是指定这个字段的长度?比如int(11),11代表11个字节吗?...

原先对mysql不太理解,但也没有报错。但理解的不够深入。这次补上。原来以为int(11)是指11个字节,int(10)就是10个字节。我错了。http://zhidao.baidu.com/link?urlpuYWaGBQNKNHgffO5kdvXshF3KmX8OuB4Mor3HXapbNHa8m1CdlF8PJTqVuKa1eKcEd6Bv2NKUr3I-KJr5…

python绘制折线图显示数据_漂亮图表也可用python信手拈来!一文教你学会用Python绘制堆积折线图...

今天,和大家聊聊关于Python绘图相关的东东哦,还是和大家继续深耕Python经典的matplotlib库哦!好啦,咱们就开始吧!首先,咱们聊聊如何在Python中去绘制经典的堆积折线图到这可能有些朋友可能会问了&#xff1…

linux下使用odbc连接mysql_Linux环境下通过ODBC访问MSSql Server

为了解决Linux系统连接MSSql Server的问题,微软为Linux系统提供了连接MSSql Server的ODBC官方驱动。通过官方驱动,Linux程序可以方便地对MSSql Server进行访问。官网提供了三个版本的驱动,分别用于以下发行版的Linux系统:64bit Re…

python画图代码对比_Python实现代码差异对比分析

在写代码过程,有时需要对比查看两个代码文件的不同,肉眼查看费事费力,很难进行对比找出不同。例如,程序运行报错时,会对比自己先前写的代码或者参考别人代码,有哪些地方不对,此时便可以通过该程…

insert into user mysql root_跳过授权表登录后使用insert into创建root权限用户

起因:刚刚搭建好的mysql数据库,做基础优化时,不小心把所有用户都删除了,并且退出了。没办法,只好跳过授权表登录,新建root用户。过程如下:一、停掉mysql,跳过授权登录[rootexplnk-za…

matplotlib 设置标注方向_Python 使用matplotlib画图添加标注、及移动坐标轴位置

import matplotlib.pyplot as pltimport matplotlibimport numpy as np#解决中文乱码问题,引入windows字体库myfont matplotlib.font_manager.FontProperties(fnamerC:/Windows/Fonts/msyh.ttf)x np.linspace(-3,3,50)y 2*x 1plt.plot(x,y)plt.figure(1,figsize…

flyway配置mysql_Flyway快速上手教程

一、Flyway是什么官网解释地非常全面,可先大致阅读一下。简单地说,flyway是一个能对数据库变更做版本控制的工具。二、为什么要用Flyway在多人开发的项目中,我们都习惯了使用SVN或者Git来对代码做版本控制,主要的目的就是为了解决…

mysql主从 单点_MySQL主从复制虽好,能完美解决数据库单点问题吗?

一、单个数据库 服务器 的缺点数据库服务器存在单点问题;数据库服务器资源无法满足增长的读写请求;高峰时数据库连接数经常超过上限。二、如何解决单点问题增加额外的数据库服务器,组建数据库集群;同一集群中的数据库服务器需要具…

java包含关系图_Java——Spring框架完整依赖关系图!再复习了解加工一下吧?

因为spring-core依赖了commons-logging,而其他模块都依赖了spring-core,所以整个spring框架都依赖了commons-logging,如果有自己的日志实现如log4j,可以排除对commons-logging的依赖,没有日志实现而排除了commons-logg…

java ora 28040_Oracle 11g与112c中ORA-28040 错误解决

今天遇到一个连接192.168.56.102这个库报错Java.sql.SQLException: ORA-28040: No matching authentication protocolOracle 12C下查询此报错oralce:/oracle/db/app/12.1.0/db/network/admin> oerr ora 2804028040, 0000, "No matching authentication protocol"/…

java中有序数组比无序数值好_java面向对象的有序数组和无序数组的比较

packageaa;classArray{//定义一个有序数组private long[] a;//定义数组长度private intnElems;//构造函数初始化public Array(intmax){a new long[max];nElems 0;}//size函数public intsize(){returnnElems;}//定义添加函数public void insert(longvalue){//将value赋值给数组成…