web開發之數據庫技術

簡介:本文將從web開發中的數據存儲和持久化開始討論,然後引入web開發中涉及到數據庫相關技術,包括管理連接的sql庫,以及連接數據庫和不同編程語言的數據庫驅動,同時還會介紹orm機制。

💇爲什麼我們在web開發中需要數據庫💇

假設我們在設計一款基於圖片的社交軟件,我們可以通過在軟件上分享和瀏覽圖片來找到感興趣的好友,只要有基本編程經驗的人都知道,既然我們允許用戶上傳圖片,那麼勢必得有服務器爲我們進行存儲,當然我們可以使用文件進行存儲,小規模的數據可以接受,但要知道的是,我們設計的應用是要爲大量的人服務的,因此我們有必要使用高效的文件系統來爲我們提供數據的快速存儲和檢索功能,數據庫服務就是爲了完成這一使命而誕生的。

:happy: 數據庫技術簡要介紹:happy:

將大量的數據按照一定的方式組織存放在計算機中,這樣的數據集合稱之爲數據集合,而通過特定的組織方式,以及訪問方法將爲外部提供數據庫的訪問,稱之爲數據庫管理系統。常用的數據庫管理系統一般都是RDBMS,也就是關係型數據庫,他是建立在嚴格的代數數學基礎之上的,表現形式上,關係型數據庫組織爲一個個的二維表格,表格中的每一行代表一行數據,第一行是列名,代表行中每一列的實際含義,舉例說明如下:

商品編號 商品名稱 商品種類 銷售單價 進貨單價
0001 T恤衫 衣服 1000 500
0002 菜刀 廚具 300 100
0003 圓珠筆 文具 50 30

表的列稱爲字段,而每一行稱之爲表中的記錄,關係型數據庫的操作一定是以行爲單位進行讀寫的,表中一般將某一字段設置爲表中的主鍵,被設置爲主鍵的字段不允許重複,數據庫內部會將其設置爲索引,加速數據操作的過程。數據庫設計完成後,對外提供SQL,通過這一領域類型語言,可以實現對數據庫的操作。數據庫和使用數據庫的用戶構成了標準的CS模型。

🌈數據庫驅動技術 🌈 ​

前面已經提到,客戶端通過SQL來進行數據庫的訪問,這樣的情況對於我們手動的編寫SQL程序是可以滿足的,但是更多的應用場景是,我們是在應用程序中訪問數據庫,具體的表現形式就是,我們需要以其他編程語言的方式,來進行數據庫的方式,這個時候,就需要數據庫驅動技術了,數據庫驅動簡單來講,就是一種適配器接口,通過該驅動,能夠爲我們實現以編程語言的方式連接訪問數據庫,並且執行SQL語言。數據庫的具體實現也不止一種,數據庫驅動就是爲我們屏蔽掉這些差異,只需要通過簡單配置的方式就可以實現數據庫的訪問。具體實現上來講,無非就是通過網絡進行和數據庫的連接,然後將SQL發送至數據庫服務端即可。下面用一段go程序進行說明:

import (
    //通用的數據庫連接服務庫
    //執行通用的網絡鏈接服務,使用了池化思想
	"database/sql"
    "fmt"
    //執行僅導入且執行包中的init函數,允許導入後不適用
    //第三方的PostgreSQL驅動包
    _ "github.com/lib/pq"
)
var Db * sql.DB
func init() {
    var err error
    Db,err = sql.Open("postgres","user=gwp dbname=gwp password=gwp sslmode=disable")
    if(err != nil) {
        panic(err)
    }
}

通過init函數就完成了數據庫的鏈接服務,以後我們進行數據庫的訪問,都是通過該數據庫句柄進行操作的。

對了,在執行該代碼之前,我們還需要在系統中進行數據庫的初始化設置,下載安裝Postgre數據庫,然後執行以下sql代碼:

//創建用戶
createuser -P -d gwp
//創建數據庫名稱
createdb gwp
//創建post表,將id設置爲主鍵
create table posts (
	id serial primary key,
    content text,
    author varchar(255)
);

這樣我們就通過第三方編程語言的方式完成了數據庫的鏈接,下面我們討論如何進行數據的操作,也就是執行數據庫的CRUD操作。

🚂向着持久化前進🚂

在上一節中我們得到了數據操作句柄,通過該句柄,我們就能夠進行數據庫的使用了,所謂的使用,也就是我們能夠將原先以sql進行數據庫操作的方式,改成了通過編程的方式進行操作,並且還添加了特定的語言特性。現在我們可以對數據庫進行一定的操作了,比如說進行查詢,修改,新數據的插入等等。OK,我們先來簡單的看一下基本的操作,有着一個基本的認識:

type Post struct{
    Id int
    Content string
    Author string
}
func GetPost(id int) (post Post,err error) {
    post = Post{}
    err = Db.QueryRow("select id,content,author from posts where id = $1",id).
    		Scan(&post.Id,&post.Content,&post.Author)
    return
}
func (post * Post) Create() (err error) {
    statement := "insert into posts (content, author) values ($1,$2) retuning id"
    stmt,err := Db.Prepare(statement)
    if err != nil{
        return
    }
    defer stmt.Close()
    err = stmt.QueryRow(post.Content,post.Author).Scan(&post.Id)
    if err != nil {
        return
    }
    return
}

上面兩個函數分別實現了數據庫的記錄插入和查詢操作。可以看出,我們在進行數據庫的操作時,大部分可以抽象成將數據庫中表中的記錄和我們的自定義結構(面向對象中叫做對象)進行相互的映射操作。因此便引入了我們下面要講的服務:orm

🐰關係映射器ORM🐰

編程設計上就是在進行着各種程度的抽象,通過抽象我們將大的任務分解成小的任務,通過抽象,我們也將機械重複的工作進行了自動化處理。object relational mapper:關係映射器的想法便是將上面需要手動進行映射的工作變得完全自動化。下面我們用實際的代碼進行介紹:

//爲了方便,我們僅僅介紹代碼中發生的變動
import (
	"github.com/jmoiron/sqlx"
)
type Post struct{
    Id int
    Content string
    AuthorName string 'db: author'
}
var Db * sqlx.DB
Db,err = sqlx.Open("postgres","user=gwp dbname=gwp password=gwp sslmode=disable")
func (post *Post) Create)() (err error) {
    post = Post{}
    err = Db.QueryRow("insert into posts (content,author) values ($1,$2) returing id").
    		StructScan(&post)
    if(err != nil){
        return
    }
    return
}

可以看到,代碼量大大的減少了,這樣我們就沒有必要將原先的映射關係在手動的書寫一遍了,順便講解一下其原理,SturctScan方法根據結構字段的英文小寫映射到對應的表中同名字段中去,假如我們想明確結構體中和表中不同名之間的映射,那麼需要手動的進行設置,設置方法就是在定義結構體時進行備註說明。

總結,在編程應用中使用數據庫技術,不僅僅需要考慮數據庫本身,還涉及到一些僅僅用sql來操作數據中的其他問題,比如應用程序和不同數據庫的連接操作,這需要數據庫驅動來爲我們屏蔽掉這些數據庫的差異,同時,爲了建立數據表中的數據和結構(對象)的數據映射,我們還需要第三方庫來爲我們完成這些重複的工作,對於go,有sqlx和gorm這樣的第三方庫,對於java,有Hibernate和Mybatis這樣的第三方庫。

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