了解ORM框架看这一篇就够了

2,904 阅读4分钟

ORM是啥

  • ORM是一种强大的数据操作工具。支持以面向对象的方式对数据库进行增删改查,而不必关注底层数据库的细节。
  • ORM 的全称是 Object Relational Mapping。Object代表应用程序中的对象,Relational表示的是关系型数据库,Mapping即是映射。结合起来就是在程序中的对象和关系型数据库之间建立映射关系,这样就可以用面向对象的方式,方便快捷地操作数据。

image.png

  • 具体的映射关系如下:

image.png

为啥要用ORM

  • 数据操作是实现功能的核心,大部分应用程序都有大量数据查询需求。用户在前端页面每一次操作的背后,几乎都离不开后端程序的数据操作。因此掌握一个强大的数据操作工具对日常开发有很大帮助。
  • ORM的强大源于它的设计。

数据操作结构

通过下图,可以了解应用程序是如何实现的数据的增删改查的。

  • 持久化层是作为业务逻辑层和数据库层的桥梁,为业务层提供数据增删改查的接口,接收业务层的指令,与数据库建立连接获取对应的数据。
  • 通过这个图我们可以得到以下三点信息:
    1. ORM就是处于持久化层的一个东西
    2. ORM支撑了数据的增删改查。
    3. ORM接收业务层指令后最终还是转换成SQL语句,发送给数据库api驱动器

image.png

实现步骤

  • 如下是使用python ORM中的SQLAlchemy进行user数据表的查询示例
from sqlalchemy import create_engine, Column, Integer, String 
from sqlalchemy.orm import sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 
 
# 初始化一个数据库链接对象
Engine = create_engine('postgresql://user:password@localhost/mydatabase') 
# 建立一个会话工厂类
Session = sessionmaker(bind=Engine) 
 
# 声明一个模型基类
Base = declarative_base() 
 
# 继承模型基类,定义User模型
class User(Base): 
    __tablename__ = 'users' 
 
    id = Column(Integer, primary_key=True) 
    name = Column(String) 
    email = Column(String) 
 
# 创建一个会话对象
session = Session() 
 
# 使用ORM查询user模型对应数据库数据
users = session.query(User).all() 
 
# 关闭会话
session.close() 
  • 以下是使用Sql进行同样的查询示例。
import psycopg2 
 
# 创建数据库链接
conn = psycopg2.connect( 
    host="localhost", 
    database="mydatabase", 
    user="user", 
    password="password") 
 
# 创建一个cursor(类似于会话对象)
cur = conn.cursor() 
 
# 使用sql语句执行查询
cur.execute("SELECT * FROM users") 
 
# 获得查询结果
users = cur.fetchall() 
 
# 关闭连接
cur.close() 
conn.close() 
  • 对比两个示例,可以发现ORM需要多一步,定义数据库映射模型类。

ORM vs. SQL

  • ORM为业务层提供了更友好的接口,但其最后还是将业务层的指令转换sql语句。为什么不直接使用sql?使用ORM有什么其他优势吗?
  • 接下来我们从各个方面对比一下两者的区别

image.png

ORM不是python语言独有的,其他面向对象语言也有ORM框架

image.png

权衡的艺术

  • 任何技术都有其优缺点。

    • 如:Python字典的查询的时间复杂度之所以可以做到接近常数级,是因为其为每个字典多维护了一个散列表,会占用大量的内存。这样的设计是一种以空间换时间的方式,在追求计算速度的场景非常适用,但当内存资源不足的时则会出现问题。
    • django的template模块,使用声明式的方式渲染UI,这样固然没有直接使用js的dom接口性能好,但更直观,隐藏实现细节,可读性更好,相应地遍提升了可维护性。
    • 软件运维方面:分布式集群部署一定比单点部署好吗?职责分离提高信息安全同时也增加了运维成本?
    • 前端框架:vue使用模板以声明式地方式渲染UI和JQuery以命令式方式操作dom。
  • 古人云:尺有所短,寸有所长,正是这个道理。所以权衡才显得更为重要。

总结

  • 经过对比,可以明显看出ORM框架实际上是提高开发者体验,牺牲了部分性能提高了可维护性。这是设计权衡的结果,没有万能的技术,只有最合适的技术。作为一名软件开发者,需要的是根据场景权衡出最合适的方案。

参考资料