[lua][openresty][open-tiny-orm]开源一个简单的orm

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/geyunfei_hit/article/details/88840303

去年开始接触openresty,手里接过来的项目使用了lor,但是没有用orm,一切全部是手撸sql,各种拼接的语句充斥在业务代码中,让我非常的不能忍。因为之前有过框架开发的经验,所以有了写一个简单的orm的冲动。

那么,在互联网行当中,一个良好的orm应该有哪些特质呢?

  1. 它应该是参数化生成查询语句的

  2. 支持基本的分页操作

  3. 应该是主从分离的

  4. 应该是轻Model的

  5. 方便调试输出 本着这几个出发点,于是有了这套小巧的框架,一共几百行,十个文件 但是加入这个到你的项目中,相信会让你的开发事半功半

安装

  1. opm install yfge/open-tiny-orm

当然,也可以直接git clone

  1. git clone https://github.com/yfge/open-tiny-orm.git

model定义

  • 推荐使用配置文件,配置文件应该为 config/mysql 即可以通过 require('config.mysql')引入,里面应该是类似的结构:

  1. return {

  2. tiny = {

  3. timeout = 3000,

  4. pool = {

  5. maxIdleTime = 120000,

  6. size = 800,

  7. },

  8. clusters = {

  9. master = {"127.0.0.1", "3306"},

  10. slave = {

  11. {"127.0.0.1", "3306"},

  12. }

  13. },

  14. database = "tiny",

  15. user = "test",

  16. password = "123456",

  17. charset = "utf8",

  18. maxPacketSize = 1024*1024,

  19. }

  20. }

这样在定义Model时只需要将 'tiny' 这个数据源传入即可

  1. local model = require('tiny.orm.mysql.model')

  2. local m = model:new (

  3. 'table_test', -- 表名

  4. {

  5. 'id',

  6. 'name',

  7. 'short',

  8. 'remark',

  9. 'date'

  10. }, -- 列的定义

  11. 'tiny', -- 使用 config/mysql 中的 tiny 配置字段作为连接配置

  12. 'id', --自增 id

  13. )

  • 当然从其他的地方加入配置文件

  1. local model = require('tiny.orm.mysql.model')

  2. local config = {

  3. timeout = 3000,

  4. pool = {

  5. maxIdleTime = 120000,

  6. size = 800,

  7. },

  8. clusters = {

  9. master = {"127.0.0.1", "3306"},

  10. slave = {

  11. {"127.0.0.1", "3306"},

  12. }

  13. },

  14. database = "tiny",

  15. user = "test",

  16. password = "123456",

  17. charset = "utf8",

  18. maxPacketSize = 1024*1024,

  19. }

  20. local m = model:new(

  21. 'tiny_user',

  22. {

  23. 'id',

  24. 'name',

  25. 'passwd'

  26. },

  27. config,

  28. 'id'

  29. )

增删改查

我们推荐进行3层以上的上的分层,即将MVC中的M(model)层分为model和data两层,这样mode只负责数据的定义,而data则封装了数据的操作。 在lua中,这尤其重要,因为function是不能被序列化的

  • 引入 model 和data

  1. --- 增删改查

  2. local model = require('tiny.orm.mysql.model')

  3. local m = model:new (

  4. 'table_test', -- 表名

  5. {

  6. 'id',

  7. 'name',

  8. 'short',

  9. 'remark',

  10. 'date'

  11. }, -- 列的定义

  12. 'tiny', -- 使用 config/mysql 中的 tiny 配置字段作为连接配置

  13. 'id', --自增 id

  14. )

  15. local mysql_fac = require('tiny.orm.mysql.factory')

  16. local fac = mysql_fac:new (m) -- m 为上文的

  • 新建--> 用new_item() 生成一个新model实例,create进行创建

  1. local item = fac:new_item()

  2. item.name = 'hello world'

  3. item.show = 'hw'

  4. fac:create(item)

  • 查询,修改,删除

  1. --- item.id 已经被赋值

  2. --- id 查询

  3. local id = 1

  4. local item2 = fac:get_by_id(id)

  5. if (item2~=nil) then

  6. item2.name = 'new world '

  7. fac:save(item2) ---- 保存

  8. end

  9. --- 删除

  10. if item2 ~= nil then

  11. facdelete(item2)

  12. end

查询与分页

可以用fac:get_query 返回一个查询实例
然后就可以像其他语言的orm一样进行链式调用了

  1. cal items = nil

  2. local query = fac:get_query()

  3. --- select ... from .. where id = 1

  4. items = query:where('id',1)

  5. :first()

  6. query = fac:get_query()

  7. --- select .. from .. where name = 'hello ' limit 10,off 10 ;

  8. local items2 = query:where('name','hello')

  9. :skip(0)

  10. :take(10)

  11. :get()

  12. query = fac:get_query()

  13. --- select ... from where name = 'hello ' and id in (1,2,3,4)

  14. local items3 = query:where (name ,'hello')

  15. :where_in('id',{1,2,3,4})

  16. :get()

  17. query = fac:get_query()

  18. --- select .. from .. where .. order by ..

  19. local items4 = query:order_by('id','asc')

  20. :order_by('name')

  21. :get()

事务

我们封装了事务的操作,在多数据源下,事务是跨连接的,即在提交时会在不同的数据源(如果该数据源上有操作)创建连接,做到同时提交,同时回滚

  1. local trans = require('tiny.orm.mysql.transaction')

  2. local t = trans:new()

  3. t:start()

  4. --- 各种操作

  5. t:submit()

  6. -- 提交

  7. t:rollback()

  8. -- 回滚

日志操作

封装了一个简单的日志操作,可以通过 locallog=require('tiny.log.helper') 进行引入,之后可以在你的调试中通过 log.trace,log.debug,log.info,log.error,log.warn,log.fatal 等进行日志记录。

这些日志最终可以通过 log.get_log()得到一个table,当调用为 warn,err,fatal时,会有相应的文件名和行数输出。

最后

git 的地址为: https://github.com/yfge/open-tiny-orm 欢迎start ,follow ,and join !

关于老拐

散养程序猿,野生架构狮

二流搬砖工,三流摄影师

假正经真逗比,装文艺实二逼

所以,这么一个公众号里,会有代码,有段子,有美图,有鸡汤,反正,乱七八遭的,没准碰上哪个刚好就烦到您了呢

啥也不说,扫码关注吧

640?wx_fmt=jpeg



展开阅读全文
博主设置当前文章不允许评论。

分享一个优秀的开源ORM框架 -- petaPoco

02-26

petaPoco出现在2011年...因此老鸟可忽略该贴...目前最新版是 5.0, 但核心文件变化不大.rnrn在众多的ORM框架中, 其中不乏非常优秀的EF, 但今天仍然想写点关于PetaPoco的文字 ... 是因为有几个项目一直在使用petaPoco, 原因有2点:rn1. 轻量级, 高性能rn2. 个人偏向DataBase First的开发方式, 原因在于Toad for Oracle工具创建数据库对象迅速, 各种方便, 胜过Code First模式创建类的速度.(此处抛开各种设计模式,各种理论).rnrn------------------------------------------------------------------------------rnrn开发准备:rn1.通过Nuget添加 petaPoco的引用 rn2.在app.config文件中加入 节点, 并配置connectionString, providerName属性.rn3.打开 DataBase.tt , 修改 ConnectionStringName,以及 Namespace , Namespace, 保存以后VS会自动执行模板文件,并生成实体类文件: DataBase.Csrnrn------------------------------------------------------------------------------rnrn使用方法:rn1.实例化:rn[code=csharp]DataBase db = new Database(ConfigurationManager.ConnectionStrings["XE"]);[/code]rnrn2.查询:rn[code=csharp]var v = db.Fetch("")[/code]rnrn3.增 / 改 / 删rn[code=csharp]rnCls.Insert(); rncls.Update(); rnCls.Delete();rn[/code]rnrn支持事务以及多实体关联, 更详细的使用可以参考官网给出的Demo: [url=http://www.toptensoftware.com/petapoco/][/url]rnrn------------------------------------------------------------------------------rnrnT4对Oracle支持并不好, 有比较多的Bug, 因此我把项目中遇到的Bug, 以及需要修改的地方:rnrn1.T4实体类的Update方法 , 根据ModifiedColumns 是否为Null判断实体中是否被更新,需要修改 PetaPoco.Generator.ttinclude文件第114行, 改为 if (ModifiedColumns == null || ModifiedColumns.Count == 0) 进行判断.rnrn2.模板所生成的所有类,主键是否为自增属性始终为true, 原因 PetaPoco.Core.ttinclude 中的OracleSchemaReader 类, LoadColumns方法中 col.IsAutoIncrement 始终为true, 改为:rncol.IsAutoIncrement=col.PropertyType != "string";rnrn3.Oracle 数据库数据类型字段允许为空, 但类型中没有自动加上"?"rn修改PetaPoco.Core.ttinclude第1216行, 将"YES"改为"Y", col.IsNullable=rdr["IsNullable"].ToString()=="Y";rn并在第179行, 增加 col.PropertyType !="DateTime" 判断.rnrn其他Bug不再一一列出, 最后附上T4 模板的调试方法,方便大家遇到问题自己快速定位和优化 :rn1. .ttinclude文件的第一行修改为 <#@ template language="C#" debug="true" hostspecific="True" #>rn2. 在需要调试的代码片断附近加入: System.Diagnostics.Debugger.Launch();rn 论坛

没有更多推荐了,返回首页