求教,ORM是什么?能用从C#中说明么

求教,ORM是什么?能用从C#中说明么,第1张

ORM的全称是Object Relational Mapping,即对象关系映射,是随着面向对象的软件开发方法发展而产生的。面向对象(Object-Oriented)是当今企业级应用开发环境中的主流开发方法,关系数据是企业级应用环境中永久存放数据的主流数据存储系统。当今企业级基于关系数据库开发的信息系统越来越多,而在你打开每个信息系统的数据访问层的时候,看到的几乎都是近似相同模式的重复性的代码。从软件复用技术的角度来看,这部分完全可以抽取出来加以复用,用以改善软件开发的生命周期,从而可有力保障在企业信息化建设中能及时的提供软件产品并具有更可靠的质量,且使得软件的开发和维护成本更低。这就是ORM的职责所在。也有人持不同意见,如ORM有性能损失。就让我们来分析下。

首先,让我们来做下比较,在同等条件同等数据量的情况,不使用ORM与使用ORM相比,显然不使用ORM执行时间会快那么一点点,但这点你很快就觉得没什么可值得骄傲的了:比如你在某次页面数据交互中,因使用ORM执行时间用了200ms,而没有使用ORM执行时间只须要190ms,提高了10ms啊!!!如果你做的是底层,提高的是CPU运算速度或者是I/O的速度,确实不赖。而这里是信息系统,这些在用户面前根本就感觉不到,即使你用了210ms、220ms用户也不关心这些,然而为了能够提高这些微不足道的x毫秒,你却要写大量重复的代码,不停的Ctrl+C/Ctrl+V,最后代码日积月累,你的代码行确实增加了,而且很快,日复一日,年复一年...恭喜,你终于成为一个代码量超过x万行的伟大的代码民工(不享受农民工待遇的“高级高素质”IT民工)!其实通过Cache的实现,能够实现对性能的调优。

其次,从项目周期和开发进度上来说,ORM无疑提供了最佳方案。对象映射可以使业务对象与数据库分离,使数据库层透明,开发人员真正的面向对象。ORM通过对开发人员隐藏SQL细节可以大大的提高生产力。没有哪个项目不计成本,无限制拖延下去的,多数是尽少投入尽快完成,还要易维护。使用ORM可以大大降低学习和开发成本。实际开发中,真正对客户有价值的是其独特的业务功能,而不应该把大量时间花费在写数据访问、增删改查(CRUD)方法、后期的Bug查找和维护上。在使用ORM后,ORM框架已经把数据库变成了我们所熟悉的实体对象,我们只需了解面向对象开发就可以实现数据库应用程序的开发,不需要浪费时间在SQL上。同时也可减少代码量,减少数据层出错机会。

再次,从职业生涯规划和人员能力提升方面,ORM因为节省大量的开发时间,无疑可以让开发人员有机会去做更有意义的事情,涉猎更多的知识。如果某人始终从事的都是这些模式重复的代码开发,顶多就是个熟练工。

最后,从根本上讲,当前信息系统开发基本上都是基于面向对象和关系数据库的,而面向对象是从软件工程基本原则(如耦合、聚合、封装、继承、多态),而关系数据库则是从数学理论(如关系模型、关系代数、关系运算、函数依赖)发展而来的,两套理论存在显著的区别。ORM就是为解决这个不匹配的现象而产生的。所以从某种意义讲,在ORM还未完全普遍存在的情况下,这种CRUD,也为想进入IT行业的一些青年提供了入门的机会;如果某天ORM像SQL语句或程序的顺序、分支、循环一样普遍,这样的IT从业者,何去何从还另当别论,然而国人大多数开发人员都是做CRUD的。

另外,Choice is only choice! 选不选择ORM是你自己的事,选择什么的ORM工具也是你来make a decision。不选择ORM你就不停的写CRUD呗,每人同情你;选择了ORM并且选择了合适的ORM工具你就享受它给你带来的益处吧。但如今很难定论那种工具才是最好的,各有优缺点。譬如面向对象与面向过程一样,OO提出这些年了也很成熟了,但今天面向过程的开发依然不少,且薪酬待遇比OO开发的强多了。如果非要给好工具做个判断,也许通用、兼容性、易学易用是个选择的依据。当然你选择所熟悉的,成员都能很好 *** 作且能满足项目的需要,也许对你而言就是好的。一个技术再好若你不熟悉或不能满足你的特殊要求或你不用,对你也没有什么意义。当然这里不是说让你固步自封,不去接触新东西,恰恰相反而是要广泛涉猎,深入理解,不要老在一个地方兜圈子。LING TO SQL很不错,但是如果你用Oracle或Access、Sysbase、DB2...,却选择用LING TO SQL那就是你的事了;如果你想为每一种数据库都使用特定的ORM工具,这也是你自己的决定。选择一个工具重要的是你要能够很好的驾驽它,为你所用,而不是让你围着它转。

附注,EntitysCodeGenerate的设计是基于两个原则,ORM和“帕累托法则”(也作“80/20或90/10法则”),也就是说:花比较少(10%-20%)的力气就可以解决大部分(80%-90%)的问题,这样通过ORM框架,就仅需要付出少数时间和精力来解决剩下的少部分问题,这无疑缩短了整个项目的开发周期同时又保证了质量。对于特别复杂或海量数据处理等的特殊情况,也提供了相应方案,可用DbCore+SQL/存储过程来优化,实际中这部分在项目中所占比例很小,有些时候如赶工抢占先机,这部分也可以在项目后期优化。EntitysCodeGenerate可以和多种Web服务器或应用服务器良好集成,如今已经支持几乎所有流行的数据库。该工具最早一直是作者内部使用,并未公布,如今共享出来,欢迎交流,批评斧正!

转载仅供参考,版权属于原作者。祝你愉快,满意请~~哦

1. 事实上,交易不帮你在这里多...除非你想有运行在多个HTTP请求(你很可能不希望)的交易。 有什么用在这些情况下是“乐观锁定”。 Django的ORM不支持,据我所知。但一直以来关于添加此功能。 那么,你是你自己的。基本上,你应该做的就是添加一个“版本”字段,你的模型,并把它传递给一个隐藏字段。正常周期的更新是: 读取数据并显示给 用户可以修改数据 用户发布的数据 该应用程序将其保存回数据库。 乐观锁,当你保存数据,你检查,如果你得到了从后面的版本是作为一个在数据库中,然后更新数据库和版本。如果它们不是,那有一直以来被加载的数据的变化。 你可以做到这一点与像一个单一的SQL调用:UPDATE ... WHERE version = 'version_from_user'

这个调用将更新数据库只有在版本仍然是

2. 我就是这样做的Django的乐观锁:updated = Entry.objects.filter(Q(id=e.id) &&Q(version=e.version))\

.update(updated_field=new_value, version=e.version+1)

if not updated:

raise ConcurrentModificationException()

上面列出的代码可以在自定义管理。 我提出以下假设: 筛选()。update()方法会导致在一个单一的数据库查询过滤器是懒惰 数据库查询是原子 这些假设都足以确保没有其他人之前已经更新了条目。如果有多个行被更新这样你的交易。 警告Django的文件: 请注意,update()方法是 直接转换为SQL 这是一个批量 *** 作 直接更新。它不运行任何 保存(您的模型)的方法,或发出 该pre_save或post_save信号

3. 这个问题是有点老了,我的回答有点晚,但经过我的理解使用这个已被固定在Django 1.4:select_for_update(nowait=True)

看到文档 返回一个QuerySet,将锁定行,直到事务结束,产生一个SELECT ...有关支持的数据库UPDATE的SQL。 通常情况下,如果另一个事务已获得所选择的行上的锁,则查询将阻塞,直到锁被释放。如果这不是你想要的行为,请致电select_for_update(NOWAIT=TRUE)。这将使调用非阻塞的。如果已经获取了冲突的锁被另一个事务时的QuerySet进行评估,DatabaseError的将得到提升。 当然,这只会工作,如果后端支持的“选择更新”功能,这对于例如SQLite不。不幸的是:nowait=True不支持MySql的,有你有nowait=False,这只会阻塞,直到锁被释放。

4. 对于未来的参考,退房离开的时候(在浏览器中,例如崩溃)的页面,并锁定它锁定的方式,不留下永恒的锁,通过javascript的解锁的混合物。下

5. 你应该Django的交易中间件,至少,甚至不管这个问题。 至于你实际有编辑数据的问题...是的,使用锁。或: 检查什么版本正在更新对(这样做牢固,不能简单地破解系统说,他们正在更新的最新副本!),且仅当该版本是最新的更新。否则,返回一个新页面与原来的版本,他们编辑,他们提交的版本,和别人写的新版本(S)。问他们变成一体,完全取决于最新的版本。你可以尝试类似的diff +补丁工具集,但你需要有方法工作失败的案例,无论如何,所以开始了。此外,您将需要保存的版本历史记录,并允许管理员恢复的变化,在无意的情况下或向上,但你应该有反正。 有很可能是Django应用程序/库,做这个最适合你。

6. 为了安全起见,数据库需要支持事务。 如果字段是“自由形式”如文字等等,你需要允许可以编辑的字段(你不能有所有权的数据),你可以存储在变量中的原始数据。 当committs,检查输入数据从原始数据更改(如果不是,你不需要通过重写旧数据打扰DB) 如果原来在数据库中的当前数据是可以保存,如果它改变了你可以示区别,并问该怎么办。 如果字段是一个数字如账户余额,在商店等项目的数量,你可以自动处理它,如果你计算出原始值(存储开始时填写表单)和新的价值,你就可以开始一个事务读取当前值之间的差额新增的差别,然后结束交易。如果你不能有负值,则应该中止交易,如果结果为负,并告诉 我不知道Django的,所以我不能给你德cod3s .. )

7. 另一个需要注意的是这个词“原子”.a个原子,你的数据库的更改要么发生或无法快速搜索说明这个问题问Django中的原子 *** 作。

8. 上面的想法updated = Entry.objects.filter(Q(id=e.id) &&Q(version=e.version))\

.update(updated_field=new_value, version=e.version+1)

if not updated:

raise ConcurrentModificationException()

看起来不错,应该能正常运行,即使没有序列化的交易。 问题是如何将deafult。保存()的行为,以不必须做人工管道来调用。update()方法。 我看着自定义管理想法。 我的计划是覆盖被称为Model.save_base()来执行更新的经理。 这是在Django 1.3当前代码def _update(self, values, **kwargs):

return self.get_query_set()._update(values, **kwargs)

什么需要恕我直言做的是这样的:def _update(self, values, **kwargs):

#TODO Get version field value

v = self.get_version_field_value(values[0])

return self.get_query_set().filter(Q(version=v))._update(values, **kwargs)

类似的事情需要发生的删除。但是删除是有点难度的Django是相当巫术在这方面通过django.db.models.deletion.Collector。 这是奇怪的,像Django的modren工具缺乏对Optimictic Concurency控制指导。 当我解开这个谜,我会更新这个帖子。希望解决方案将是不涉及万吨编码,怪异的意见,跳绳重要部分的Django等的一个很好的Python的方式

9. 从这里开始: 我假设将举行一个隐藏字段中你试图挽救细节的表格。def save(self):

if(self.id):

foo = Foo.objects.get(pk=self.id)

if(foo.timestamp >self.timestamp):

raise Exception, "trying to save outdated Foo"

super(Foo, self).save()

Django里面,管理数据库和sqlarchemy类似,也是通过orm框架来实现的。所有的数据库的建立,都是在model.py里面通过类来实现的。

首先看看如何创建一个单表:

a. 先定义一个类,继承models.Model, 然后根据需求定义参数,这些参数的类型和变量后面会进一步阐述

models.py

from django.db import models

class UserInfo(models.Model):

username = models.CharField(max_length=32)

password = models.CharField(max_length=64)

b. 注册app

settings.py

INSTALLED_APPS = [

‘django.contrib.admin‘,

‘django.contrib.auth‘,

‘django.contrib.contenttypes‘,

‘django.contrib.sessions‘,

‘django.contrib.messages‘,

‘django.contrib.staticfiles‘,

‘app01‘,

]

c.执行命令。 第一条命令会生成一个初始化文件,第二个命令会生成对应的表

python manage.py  makemigrations

python manage.py  migrate

这样,就在PyCharm自带的sqlite数据库里面成功的生成了一个app01_UserInfo的表。这个表默认会有一个自增的id作为主键,另外两个字段是我们通过类创建的。

d. 如果希望使用mysql,因为Django默认使用了MySqldb模块,这个在3.0版本里面不存在,会直接报错。我们需要改为pymysql的模块,方法如下:

在project同名文件夹下的__init__文件中添加如下代码即可:

import pymysql

pymysql.install_as_MySQLdb()

2. 对于单表的增删改查询

查询

获取所有结果,获取到的结果是一个QuerySet的类似列表的对象,每一个元素本身又是一个对象,包括了id,name,password等属性。

obj = models.UserInfo.objects.all()

<QuerySet [<UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>, <UserInfo: UserInfo object>]>

可以通过filter进行过滤,相当于sql的where语句,因为结果也是QuerySet,因此需要再使用first()获取第一个值

obj = models.UserInfo.objects.filter(id=nid).first()

增加

models.UserInfo.objects.create(username=u,password=p,user_group_id=3)

删除,可以在filter的基础上进行删除

models.UserInfo.objects.filter(id=nid).delete()

修改,有两种常见方式

第一个方式

models.UserInfo.objects.filter(id=nid).update(username=u,password=p)

第二个方式

obj=models.UserInfo.objects.filter(id=nid)

obj.username=u

obj.save()


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/6699268.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-26
下一篇 2023-03-26

发表评论

登录后才能评论

评论列表(0条)

保存