ORM框架

本文會列舉多個ORM框架,並介紹各自實現的思想、特點。

數據庫模式(Database Schema)

Schema是什麼?如圖所示。
在這裏插入圖片描述

Schema的表示法

對於熟悉SQL的DBA來說,SQL代碼就能當做“Schema表示法”了,如下:

CREATE TABLE user
(
    user_id int PRIMARY KEY,
    username varchar(15) NOT NULL,
    email varchar(255) NOT NULL
)

不是所有人都熟悉SQL語句,對於技術水平薄弱的業務人員,可以使用「模式圖(schema diagram)」表示法,見《數據庫系統概念》2.4節。如書上的這幅圖所示。
在這裏插入圖片描述

【重點來了】對開發人員來說,面臨一些困難:

  • 開發人員對SQL語句的掌握比較生疏,遠不如DBA
  • 開發使用的語言是面向對象的,和SQL的思維模式差異大
  • 目前非關係數據庫(NoSQL)遠不如關係數據庫成熟可靠,項目中還是採用RDBMS

因爲這些困難,開發人員需要一種新的“Schema表示法”。下面例舉幾個常用的ORM框架,看看這些框架的“表示法”長什麼樣。

例如SQLAlchemy ORM中的Declarative Mapping,其表示法如下:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey

Base = declarative_base()

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

再如Rails中的Active Record,代碼如下:

class User < ApplicationRecord
end

上述代碼怎麼啥都沒有呢?這是因爲Rails採用「推斷式」方案,所以不需要開發人員編寫映射代碼,只要數據庫存在合適的表即可。表怎麼創建呢?在Rails開發中,一般是通過Migrations創建表,因此可以認爲Migration纔是Rails的”Schema表示法“,如下:

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :nickname

      t.timestamps
    end
  end
end

【對比】SQLAlchemy ORM和Rails,前者採用「聲明式」方案、後者採用「推斷式」方案,區別類似編譯型語言和解釋型語言。
Rails以極高的開發效率著稱,採用的「推斷式」方案讓開發者不用寫映射代碼(ActiveRecord一行代碼都沒有,Migration是自動生成的不用手寫)。

Schema持久化

Schema在ORM中表示完畢後,數據庫中並不存在對應的Schema。我們要在數據庫中創建Schema對應的表。因爲ORM在內存中,數據庫在磁盤上,所以這一過程也叫做持久化。

項目是否需要Schema持久化呢:

  • 如果數據庫早已存在,ORM是後來才引入的,那麼Schema已經存在於數據庫中,無需進行持久化
  • 如果Schema一開始就是通過ORM表示法(而不是SQL表示法)描述的,那麼需要持久化

持久化到底該怎麼做呢?說的直白一點,無非就是要在RDBMS中創建表(用DDL語句創建)。在大多ORM框架中,開發人員只需要簡單幾行代碼,就能夠完成持久化了。ORM框架會根據Schema表示法構造一些DDL語句,並執行DDL語句,這個過程的示意圖如下。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0TiXezWP-1571311796341)(https://upload-images.jianshu.io/upload_images/14066340-354cbebf59dea63d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]

舉個例子,看看SQLAlchemy中如何進行持久化的。在SQLAlchemy ORM中,通過調用Base.metadata.create_all來創建表,代碼如下:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey

Base = declarative_base()
class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    nickname = Column(String)

engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)  # Schema持久化

再舉個例子,看看Rails中如何進行持久化的。在app/db/migrate目錄下建立了一些Migration後,命令行執行$ rails db:migrate就可以在數據庫創建表了。

CRUD操作、數據庫會話

數據驗證

確保存入數據庫的數據一定是合法的,例如:確保每個用戶都要有一個合法的郵箱地址。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章