博客源为书写的载体,书写以对思维的缓存 正文

Django之ORM


对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--"虚拟对象数据库"。在编程世界中有很多实现了ORM的开发框架,如:Java中常用的Hibernate、Mybatis等;Python中有Django、SQLAlchemy等。下面以Django为例,补习补习Django。

一:什么是ORM

ORM(对象关系映射),是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。ORM通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。简单来说就是:将数据库中的"表、行、字段"与我们的面向对象编程中的"类、对象、属性"来建立一一对应的映射关系。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作实体对象的属性和方法。

二:ORM的优缺点

优点:

    1.开发效率更高

    2.数据访问更抽象、简单

    3.支持面向对象封装

缺点:

    1.性能低,因为它内部是使用了大量反射,还有数据库检测,造成性能降低。

三:Django中的ORM

Django的ORM操作本质上会根据对接的数据库引擎翻译成对应的SQL语句。所以无需关心使用的是MySQL、Oracle还是其它数据库,因为如果数据库需要迁移,只需更换相应的数据库引擎即可。

orm.png

1.数据库连接

在settings.py文件中进行设置连接数据库(Django默认使用的是sqllite数据库)

以MySQL为例:

DATABASES = {
   'default': {
       'ENGINE': 'django.db.backends.mysql',
       'NAME': '数据库名',    # 数据库必须事先创建好
       'USER': '用户名',
       'PASSWORD': '密码',
       'HOST': '数据库服务器IP,本地可以使用localhost',
       'POST': '端口,默认为3306'
   }
}

2.表创建

from django.db import models

# 一个类对应数据库中的一张表,每个类继承models.MOdel类
class Article(models.Model):
   name = models.CharField(max_length=50, verbose_name=u'文章标题')

关于字段类型:

1.AutoField: 自动增长,通常不需要指定,django会自动创建名为id的自动增长属性字段
2.CharField: 字符串,必须指定的参数:max_length,表示最大字符个数
3.TextFiled: 大文本字段,一般超过4000个字符
4.IntegerField: 整形
5.BooleanField: 布尔,支持Null,True
6.NullBooleanField: 支持Null,True,False
7.DateFiled: [auto_now=False, auto_now_add=False]:
   auto_now:表示自动设置该字段为最后一次修改的时间,默认为False
   auto_now_add:表示自动设置该字段为创建时的时间,默认为False
8.DateTimeField: 日期时间
9.DecimalFiled(max_digits=None, decimal_places=None):
   十进制浮点数,适合用于保存金额,精度较高
   必须指定参数:max_digits总位数、decimal_places小数位数
10.FloatField: 浮点数,有误差
11.FileField: 上传文件字段
12.ImageField: 继承与FileFiled,对上传的内容进行校验,确保是有效地图片

关于字段约束:

1.primary_key:主键
2.ForeignKey :外键
3.null       :数据库中字段是否允许为空,默认为False
4.unique     :唯一不重复
5.default    :默认值
6.blank      :表单验证时是否允许为空,默认为False
注意:Django会为表增加自动增长的主键列,每个模型只能有一个主键列,如果使用选项设置某属性为主键列后,则django不会再生成默认的主键列。

关于表与表之间的关系:

1.ForeignKey:一对多,将字段定义在多的端中
2.ManyToManyField:多对多,将字段定义在两端中
3.OneToOneField:一对一,将字段定义在任意一端中

3.表操作(CRUD)

对于表操作,需要使用管理器来完成。管理器是Django的模型进行数据库的查询操作的接口,Django应用的每个模型都拥有至少一个管理器(默认提供一个名为objects的管理器,使用语句为:模型类.objects.方法())

增加(create --> save):

# 第一种方式:自动save()
模型类.objects.create(属性=值)
如:Article.objects.create(name="LiuCiXin")

# 第二种方式:
article = Article()
article.name = "LiuCiXin"
article.save()
# 或者简写
article = Article(name = "LiuCiXin")
article.save()

查询:

一:返回查询集QuerySet
1.filter(**kwargs):返回与所给筛选条件相匹配的QuerySet对象。

2.all():返回包含所有查询结果的QuerySet对象。

3.exclude(**kwargs):它包含了与所给筛选条件不匹配的QuerySet对象。

4.values(*field):返回一个ValueQuerySet(一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列)。

5.values_list(*field):它与values()非常相似,但它返回的是一个元组序列而values返回的是一个字典序列。

6.order_by(*field):对查询结果排序。

7.reverse():对查询结果反向排序。

8.distinct():从返回结果中剔除重复纪录。

二:返回单个数据
1.get(**kwargs):返回与所给筛选条件相匹配的对象,返回结果有且只有一个。如果符合筛选条件的对象超过一个或者没有,都会抛出错误。

2.count():返回数据库中匹配查询(QuerySet)的对象数量。

3.first():返回第一条记录。

4.last():返回最后一条记录.

5.exists():如果QuerySet包含数据,就返回True,否则返回False。

修改(update --> save):

# 第一种方式:
Article.objects.get(id = 1).update("name" = "TangNiu")

# 第二种方式:
article = Article.objects.get(id = 1)
article.name = "LiuCiXin"
article.save()
# 推荐使用第一种方式,会自动save()并且第二种方式会将所有属性重新设定一遍,效率低。

删除(delete):

Article.objects.get(id = 1).delete()

四:Django中ORM的优化

前面提到ORM的缺点是降低程序性能尤其是获取数据量特别大的情况下,现在的框架都对这方面进行优化和改进,那么Django中是如何做的呢?

1.惰性查询

创建QuerySet的时候不会马上查询数据库,只有当访问数据如:遍历QuerySet、索引、切片等等时才会发起查询操作。

2.缓存

每个查询集都包含一个缓存来最小化对数据库的访问。在新建的查询集中,缓存为空,首次对查询集求值时,会发生数据库查询,django会将查询的结果存在查询集的缓存中,并返回请求的结果,接下来对查询集求值将重用缓存的结果。但是使用索引或者切片操作,就不会缓存。

五:总结

本章只是简述了大概,还有很多细节如:条件查询、关联查询、关联删除、正反方向查询和删除等还没描述,我懒。如有需要可参考:https://blog.csdn.net/weixin_42419806/article/details/80643399

六:最后

timg-(1).jpg