orm
orm 全稱 object relation mapping 對象映射關(guān)系,目的是解決面向?qū)ο蠛完P(guān)系數(shù)據(jù)庫之間存在的互不匹配的現(xiàn)象。
sql注入曾經(jīng)是一種常見的網(wǎng)絡(luò)攻擊方式,針對程序編寫疏忽而產(chǎn)生的問題比如:通過sql語句實現(xiàn)無賬號登錄、刪除甚至篡改數(shù)據(jù)庫。這是由于以前sql語句是拼接后執(zhí)行的,因此在動態(tài)參數(shù)完成拼接時若有帶有sql操作的關(guān)鍵字的動態(tài)參數(shù)參與拼接,則整體結(jié)果會向惡意注入者期望的方向執(zhí)行。
orm就很好的解決了這些問題,在其底層邏輯中會帶有轉(zhuǎn)義操作,不擔心注入問題,而且對于我們的struct結(jié)構(gòu)體而言,也提供了對應(yīng)關(guān)系操作,對于編程者來說是極大地便利:將注意力從數(shù)據(jù)庫的細節(jié)轉(zhuǎn)移到業(yè)務(wù)邏輯上。orm作為中間層,可以簡化數(shù)據(jù)庫的遷移操作。
orm的缺點:不能夠生成所有的sql業(yè)務(wù)語句,有些復雜的還是需要sql原生語句操作;性能低于直接使用sql語句的。
gorm
golang的一個orm框架。
使用示例
創(chuàng)建表
sql
CREATE TABLE users( name VARCHAR(50), age INT);
gorm
type User struct{
name stringg
age int
}
db.Table(“users”).CreateTable(&User{})
創(chuàng)建users表,內(nèi)容由結(jié)構(gòu)體來定義的。
插入數(shù)據(jù)
sql
INSERT INTO users (name, age) VALUES ('ee','18')
gorm
user := User{
name : "ee",
age : 18,
}
db.Create(&user)
先定義一個User類的結(jié)構(gòu)體user,然后調(diào)用gorm的Create函數(shù)參數(shù)為user,插入到數(shù)據(jù)庫中。
查詢
sql
SELECT * FROM users WHERE name="ee";
gorm
var users [ ]User//定義一個User類型的數(shù)組名字叫做users
db.Where(“name=?”,”ee”).Find(&users) //方法1:查詢所有結(jié)果放入users數(shù)組
db.Where(&User{name:”ee”,age:18}).Find(&users)
db.Where(map[string] interface{}{"name":"ee","age":18}).Find(&users)
這是三種gorm中的查詢方式分別是通過sql、struct、map來查詢數(shù)據(jù)。
獲取第一條匹配記錄
sql
SELECT * FROM users WHERE name="ee" limit 1;
gorm
var user User
db.Where("name=?","ee").First(&user)
在gorm有一個單獨的函數(shù)來獲取第一條數(shù)據(jù)
批量查詢需要創(chuàng)建一個數(shù)組來接受數(shù)據(jù),這里需要創(chuàng)建一個單個變量來接受查詢出來的數(shù)據(jù)。
LIMIT多條數(shù)據(jù)
sql
SELECT * FROM users LIMIT 3;
gorm
var users [ ]User
db.Limit(3).Find(&users)
LIKE AND IN
sql
SELECT * FROM users WHERE role='admin' OR role ='super_admin';
gorm
db.Where("role=?","admin”).Or("ole=?",super_admin").Find(&users)
db.Where("name LIKE ?","%ee%").Find(&user)
db.Where("name=? AND age>=?”, "ee", "18").Find(&users)
db.Where("name in (?)",[ ]string{"ee","sh"}).Find(&usere)
非選項
sql
SELECT * FROM users WHERE name <> "ee";
gorm
db.Not("name","ee").First(&users)
gorm支持查詢鏈
db.Where("name=?","ee").Or("name=?","sh").Not("age=?",18).Find(&users)
部分字段查詢
sql
SELECT name, age FROM users;
gorm
db.Select(“name, age”).Find(&users)
db.Select([ ]string{“name”,”age”}).Find(&users)
可以選擇指定的字段來進行獲取。
數(shù)據(jù)排序
sql
SELECT * FROM users ORDER BY age DESC name;
gorm
db.Order("age desc").Order("name").Find(&users)
count函數(shù)獲取記錄條數(shù)
sql
SELECT count(*) FROM users WHERE name ='ee';
gorm
var count int
db.Where("name=?","ee").Count(&count)
將創(chuàng)建的int類型以指針的方式傳入(對指針操作使修改生效)
數(shù)據(jù)更新
sql
UPDATE users SET name='hello' WHERE id=111;
gorm
var user User
db.Where("id=?", "111").First(&user)
Db.Model(&user).Update("name","hello")
更新時先取出來再進行修改
多個屬性修改
gorm
db.Model(&user).Updates(map[string]interface{}{“name”:”hello”,”age”:18})
db.Model(&user).Update(User{name:"hello",age:18})
刪除
sql
DELETE FROM users WHERE id=10;
gorm
var user User
db.Where("id=?","10").First(&user)
db.Delete(&user)
先找id為10的數(shù)據(jù),保存到user中,將數(shù)據(jù)傳入到刪除函數(shù)中,批量刪除和查詢是對應(yīng)的, 先批量查詢出來然后批量傳入到刪除數(shù)據(jù)中。
db.Where("name=?","ee").Delete(User{})
軟刪除
很多模型中有DeletedAt字段,那么就自動獲取到了軟刪除的功能,那么在調(diào)用Delete的時候 數(shù)據(jù)并不會從數(shù)據(jù)庫中永久刪除而是將字段DeletedAt的值設(shè)置成當前的時間。
gorm支持事務(wù)
數(shù)據(jù)庫中的事務(wù)是很必要的一個事情,在grom中是支持事務(wù)的,不過是需要我們自己來簡單的實現(xiàn)一些,假如說我們的事務(wù)是三步,我們要做的操作是:
執(zhí)行操作前
tx :=db.Begin() //代表事務(wù)開始
tx.Create()
之后對操作進行判斷,如果成功執(zhí)行了的話就執(zhí)行2,繼續(xù)3。
如果在這之間有一個操作失敗了(需要我們通過if來進行判斷),就調(diào)用
tx.Rollback
進行回滾操作
如果整個事務(wù)執(zhí)行完了就要進行提交
tx.commit()
將整個事務(wù)過程進行提交