============================================================================
原创作品,允许转载。转载时请务必以超链接形式标明原始出处、以及本声明。
请注明转自:http://yunjianfei.iteye.com/blog/
============================================================================
最近在用tornado写一个基于Rest的WebService服务端,只提供后端服务,其他webserver应用通过URL,Rest的方式来访问。
我们在开发web应用的时候,难免会想到ORM的一些框架,比如java ee中常用的hibernate, ibatis以及python中的SQLAlchemy之类。使用ORM会在一定程度上加快我们的开发效率。
一个简易ORM框架主要实现如下几个功能就足够了:
1.插入: 类对象映射为数据库记录
2.查询:数据库记录映射为类对象
3.修改、删除:可以通过自己写sql语句来搞定。
python中有类,同时也有dict字典类型,如果将字典再包装为类,则显得过渡包装了,反倒很不灵活,因此,提炼一下,python的ORM框架只需要实现如下几点就足够:
1.插入: python的dict映射为数据库记录
2.查询:数据库记录映射为python的dict以及list等
3.修改、删除:可以通过自己写sql语句来搞定。
经过一些测试,技术选型,最终确定了使用tornadb,非常轻量级,查询数据库返回的对象直接映射为python的数据类型dict或者list之类。可以用类似java中“对象.属性”的方式来访问数据。这简直是太爽了~首先,看一个小例子。
import types import time class Row(dict): """A dict that allows for object-like property access syntax.""" def __getattr__(self, name): try: return self[name] except KeyError: raise AttributeError(name) dic = Row() dic.name = 'hello' dic.num = '12334' print type(dic) print "dic.name: " + dic.name print "dic.num: " + dic.num
输出结果为:
dic.name: hello
dic.num: 12334
通过这个例子,我们可以看到,python里面的dict类型,是可以变成类似java中“对象.属性”的方式来访问的。
torndb就是通过这样的方式,查询返回的数据可以通过“.列名”来直接访问。
查询的时候直接返回dict或者list类型,那插入呢?如果可以像java一样,传入一个对象,通过ORM框架直接反射为sql操作,这样多方便啊~
还是dict,如果我们插入的时候,直接将插入的数据格式保存为dict,通过这个dict生成insert语句就可以了,经过查阅各种资料,我提炼出来了如下方法:(使用的时候直接将该方法放入torndb.py中即可)
def insert_by_dict(self, tablename, rowdict, replace=False): cursor = self._cursor() cursor.execute("describe %s" % tablename) allowed_keys = set(row[0] for row in cursor.fetchall()) keys = allowed_keys.intersection(rowdict) if len(rowdict) > len(keys): unknown_keys = set(rowdict) - allowed_keys logging.error("skipping keys: %s", ", ".join(unknown_keys)) columns = ", ".join(keys) values_template = ", ".join(["%s"] * len(keys)) if replace: sql = "REPLACE INTO %s (%s) VALUES (%s)" % ( tablename, columns, values_template) else: sql = "INSERT INTO %s (%s) VALUES (%s)" % ( tablename, columns, values_template) values = tuple(rowdict[key] for key in keys) try: cursor.execute(sql, values) #self._execute(cursor, sql, values, None) return cursor.lastrowid finally: cursor.close()
这样,插入的时候我们就再也不用写繁琐的sql语句了,只需要将我们要插入的对象使用dict封装,比如:
有个host表,里面有hostname,ip两个字段,则我们可以用如下几行代码,就可以插入到数据库:
host = {} host['hostname'] = 'test1' host['ip'] = '10.22.10.90' ret = db.insert_by_dict("Host", host)
是不是很方便呢?:)附件里是我修改过后,完整的torndb源码。欢迎大家多多下载使用。
外带一个小例子,完整版请参照我在github上发布的一个webservice框架:https://github.com/yunfeiflying/tornado-rest-web-service-framwork/
#!/usr/bin/env python2.7 # # -*- coding:utf-8 -*- # # Author : YunJianFei # E-mail : yunjianfei@126.com # Date : 2014/02/25 # Desc : Test db # """ Data Access Object This file impelements DBI for the table 'Host' The Host table's create sql is : CREATE TABLE IF NOT EXISTS `test`.`Host` ( `host_id` INT NOT NULL AUTO_INCREMENT, `host_type` INT NULL, `hostname` VARCHAR(45) NULL, `ip` VARCHAR(45) NULL, `create_time` VARCHAR(45) NULL, `cpu_count` INT NULL, `cpu_pcount` INT NULL, `memory` INT NULL, `os` VARCHAR(200) NULL, `comment` VARCHAR(200) NULL, PRIMARY KEY (`host_id`)) ENGINE = InnoDB; """ from util.dbconst import TableName, TableFields, TableSelectSql import logging class HostDao: def __init__(self, db): mysql_host = "192.168.10.11:3306" db_name = "test" db_user = "root" db_pass = "" self.db = torndb.Connection( host=mysql_host, database=db_name, user=db_user, password=db_pass ) def insert_by_dict(self, host, replace=False): try: id = self.db.insert_by_dict("Host", host, replace) return id except Exception, ex: logging.error("Insert host failed! Exception: %s Host: %s", str(ex), str(host)) return None def if_exist(self, hostname, ip): ret = self.get_by_hostname(hostname) if ret != None: return True ret = self.get_by_ip(ip) if ret != None: return True return False def get_by_ip(self, ip): sql = TableSelectSql.HOST + " where ip='" + str(ip)+"'" return self.db.get(sql) def get_all(self): sql = TableSelectSql.HOST return self.db.query(sql) def get_by_hostname(self, hostname): sql = TableSelectSql.HOST + " where hostname='" + str(hostname)+"'" return self.db.get(sql) def get_by_id(self, host_id): sql = TableSelectSql.HOST + " where host_id=%s" % str(host_id) return self.db.get(sql) def get_id_by_hostname(self, hostname): sql = TableSelectSql.HOST + " where hostname='" + str(hostname)+"'" ret = self.db.get(sql) if ret != None: return ret.host_id return None def update_worker_num_by_hostname(self, hostname, worker_num): try: sql = "UPDATE Host SET worker_num=%s WHERE hostname='%s'" % (worker_num, str(hostname)) ret = self.db.execute(sql) return ret except Exception, ex: logging.error("Update Host failed! Exception: %s hostname: %s , worker_num: %s", str(ex), str(hostname), worker_num) return None def update_worker_num_by_id(self, host_id, worker_num): try: sql = "UPDATE Host SET worker_num=%s WHERE host_id=%s" % (worker_num, host_id) ret = self.db.execute(sql) return ret except Exception, ex: logging.error("Update Host failed! Exception: %s host_id: %s , worker_num: %s", str(ex), host_id, worker_num) return None def del_by_hostname(self, hostname): try: sql = "DELETE FROM Host WHERE hostname='" + str(hostname) + "'" ret = self.db.execute(sql) return ret except Exception, ex: logging.error("Delete host failed! Exception: %s hostname: %s", str(ex), str(hostname)) return None def del_by_id(self, host_id): try: sql = "DELETE FROM Host WHERE host_id=" + str(host_id) ret = self.db.execute(sql) return ret except Exception, ex: logging.error("Delete host failed! Exception: %s host_id: %s", str(ex), host_id) return None
相关推荐
在本篇“基于Java简易ORM框架实现(二)”中,我们将深入探讨如何构建一个简单的对象关系映射(Object-Relational Mapping,ORM)框架。ORM框架是Java开发中常用的一种技术,它允许开发者以面向对象的方式操作数据库,...
在本篇讨论中,我们将深入探讨“基于Java的简易ORM框架实现”。ORM,全称Object-Relational Mapping,是将数据库中的数据与程序中的对象进行映射的技术,它简化了数据库操作,使得开发者可以像操作对象一样操作...
随着信息技术的不断发展,企业对于数据的管理和操作需求日益增长。传统的JDBC(Java Database Connectivity)虽然可以实现...本项目旨在开发一个基于Java的简易ORM框架,为企业提供轻量级、高效的数据访问解决方案。
本源码为基于Java和Kotlin的简易ORM操作工具设计,包含363个Java文件、15个XML文件等,共416个文件。该项目旨在为用户提供一个全面、便捷的ORM操作解决方案,通过Java、Kotlin技术的结合,为用户带来高效的使用体验...
不用写任何代码,就可以对表完成增删改查; 一套API支持对所有表的增删改查CRUD操作;...基于Spring Boot + Mybatis实现的通用增删改查服务API; 该模块提供了通用的数据库DDL操作接口和通用的业务数据表CRUD操作。
一款基于mybatis的ORM框架,非常强大,非常好用,不信的来试试,2024年超级优秀的ORM!!!
**基于注解的HBase ORM小工具详解** 在大数据领域,Apache HBase作为一个分布式、面向列的NoSQL数据库,常用于处理大规模数据。然而,与传统的关系型数据库不同,HBase的操作模式相对复杂,需要通过Java API进行低...
简易ORM操作工具,低代码,操作简单,功能强大,上手快,纯原生JDBC+阿里的Druid连接池,集成Mybatis-Plus的条件构造器,在此之上添加了多表连接的条件构造,使增删改查变得更容易,支持动态一对一(一对多)查询,...
本文将深入探讨基于Spring JdbcTemplate的nimble-orm工具,以及其在应对互联网环境中的表结构频繁变动时的优势。 nimble-orm是一款灵活且轻量级的ORM框架,它是针对Spring JdbcTemplate进行了一层封装,旨在提高...
### 主流ORM框架技术应用——Hibernat与MyBatis详解 #### 一、MVC设计模式概述 在深入探讨ORM框架之前,我们先来了解一下软件工程中的一个重要设计模式——MVC(Model-View-Controller),它对于理解后续ORM框架的...
9. **异步操作**: 基于.NET 6.0的异步编程模型,ORM框架支持异步数据库操作,这在处理大量数据或网络延迟时尤其有用。 10. **设计模式应用**: ORM框架通常会遵循一些设计模式,如工厂模式用于创建数据库连接,代理...
《基于SpringBoot、ORM-Mybatis、SpringMVC和多种组件构建的企业信息化开发基础平台》 本项目是一个全面的企业信息化开发基础平台,采用SpringBoot框架为核心,结合ORM框架Mybatis和SpringMVC技术,旨在为开发者...
基于SpringBoot,ORM-Mybatis,SpringMVC和多种组件构建的企业信息化开发基础平台,快速构建OA、CMS。 系统管理通用功能 单点登录: OAuth2.0+JWT单点登录/CAS单点登录 用户管理: 系统用户 角色管理: 按照企业系统...
**基于ORM的数据库框架Room** 在Android开发中,数据存储是一个关键部分,而Room数据库框架是Google官方推荐的用于Android应用程序的数据持久化解决方案。Room基于对象关系映射(ORM)理念,它允许开发者以更面向...
在这个简易版ORM框架中,我们模仿了著名的MyBatis框架,旨在简化数据库操作,提高开发效率。 在手写这个框架的过程中,我们可以理解以下核心概念和知识点: 1. **数据访问层(DAL,Data Access Layer)**:ORM框架...
本设计源码提供了一个基于Java的IDEA ORM代码生成插件,包含75个文件,其中39个java源文件,14个ftl模板文件,6张png图片,3个md文档,2个gradle文件,2个form文件,2个txt文件,1个gitignore文件,1个LICENSE文件和...
《C#代码生成器源码解析——基于自定义ORM框架》 在软件开发过程中,代码生成器是一个重要的工具,它可以显著提高开发效率,减少重复工作。本文将详细探讨一款基于C#的代码生成器,其核心是利用自定义的ORM(对象...
总的来说,这个基于Java的HBase ORM库提供了一种更高效、更直观的方式来操作HBase,它通过注解简化了数据模型的定义,减少了与HBase API的直接交互,提高了开发效率。如果你正在处理大量结构化或半结构化数据,且...
基于 protobuf 的 C++ ORM 框架, 通过.proto文件生成C++ SQL操作代码.