ไปใช้งาน PHP Laravel ORM ซึ่งสอดคล้องกับเอกสารอย่างเป็นทางการของ laravel https://laravel.com/docs/10.x/queries
แบ่งออกเป็นสไตล์ Go (การใช้การเชื่อมโยงโครงสร้าง struct) และสไตล์ PHP (การใช้โครงสร้างแผนที่)
สำหรับการใช้งานสไตล์ PHP คุณสามารถใช้เอกสารประกอบของตัวสร้างคิวรี laravel เป็นข้อมูลอ้างอิง และพยายามกู้คืนแบบ 1:1
ยังอยู่ในช่วงเบต้า โปรดใช้ด้วยความระมัดระวัง เนื่องจากไม่มีการติดแท็ก จึงสามารถใช้ได้โดยใช้ go mod เท่านั้น
# go.mod
require github.com/gohouse/gorose/v3 masterไปใช้งานสไตล์
package main
import (
gorose "github.com/gohouse/gorose/v3"
// 引入mysql驱动
_ "github.com/go-sql-driver/mysql"
)
type User struct {
Id int64 `db:"id,pk"` // 这里的 pk 是指主键
Name string `db:"name"`
Email string `db:"email"`
// 定义表名字,等同于 func (User) TableName() string {return "users"}, 二选一即可
// TableName string `db:"users" json:"-"`
}
func ( User ) TableName () string {
return "users"
}
var rose = gorose . Open ( "mysql" , "root:123456@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=true" )
func db () * gorose. Database {
return rose . NewDatabase ()
}
func main () {
// select id,name,email from users limit 1;
var user User
db (). To ( & user )
// insert into users (name,email) values ("test","[email protected]");
var user = User { Name : "test" , Email : "[email protected]" }}
db (). Insert ( & user )
// update users set name="test2" where id=1;
var user = User { Id : 1 , Name : "test2" }
db (). Update ( & user )
// delete from users where id=1;
var user = User { Id : 1 }
db (). Delete ( & user )
}การใช้งานสไตล์ PHP และแบบสอบถามการใช้งานสไตล์ Go มีดังต่อไปนี้ การเปรียบเทียบ SQL:
select id,name,email from users where id = 1 and name = " test " // php 风格写法
user , err := db (). Table ( "users" ).
Select ( "id" , "name" , "email" ).
Where ( "id" , "=" , 1 ). Where ( "name" , "test" ).
First ()
// go 风格写法
var user = User { Id : 1 , Name : "test" }
err := db (). To ( & user )การใช้งานทั้งสองแบบข้างต้นมีผลลัพธ์ที่เหมือนกัน จะเห็นได้ว่ายกเว้นความแตกต่างในการผูกกับโมเดลตาราง วิธีการอื่นก็เป็นเรื่องปกติ
การเชื่อมต่อฐานข้อมูลเดี่ยวสามารถใช้ได้โดยตรงในลักษณะเดียวกับอินเทอร์เฟซอย่างเป็นทางการ
var rose = gorose . Open ( "mysql" , "root:123456@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=true" )ยังสามารถใช้ได้
var conf1 = gorose. Config {
Driver : "mysql" ,
DSN : "root:123456@tcp(localhost:3306)/test?charset=utf8mb4&parseTime=true" ,
Prefix : "tb_" ,
Weight : 0 ,
MaxIdleConns : 0 ,
MaxOpenConns : 0 ,
ConnMaxLifetime : 0 ,
ConnMaxIdleTime : 0 ,
}
var rose = gorose . Open ( conf )หรือใช้คลัสเตอร์การแยกการอ่าน-เขียนเพื่อบังคับให้อ่านข้อมูลจากฐานข้อมูลการเขียนภายในธุรกรรมโดยอัตโนมัติ
var rose = gorose . Open (
gorose. ConfigCluster {
WriteConf : []gorose. Config {
conf1 ,
conf2 ,
},
ReadConf : []gorose. Config {
conf3 ,
conf4 ,
}
},
) ขณะนี้ มีการรองรับฐานข้อมูลทั้ง 5 ฐานข้อมูลข้างต้นแล้ว สำหรับฐานข้อมูลทั่วไป คุณจะต้องเพิ่มอินเทอร์เฟซ gorose/driver/dialect.IDialect เพิ่มเติมเท่านั้น สำหรับฐานข้อมูลที่ไม่ใช่สากล ตราบใดที่มีการใช้อินเทอร์เฟซ gorose/driver.IDriver ฐานข้อมูลใด ๆ สามารถรองรับในทางทฤษฎีได้ รวมถึง redis, mongo ฯลฯ การดำเนินการลูกโซ่ ORM ทั้งหมดสามารถนำไปใช้ผ่านอินเทอร์เฟซนี้ได้ การดำเนินการลูกโซ่ ORM ทั้งหมดอยู่ใน gorose/builder.Context และสามารถรับข้อมูลต้นฉบับได้โดยตรง
// 全自动事务, 有错误会自动回滚, 无错误会自动提交
// Transaction 方法可以接收多个操作, 同用一个 tx, 方便在不同方法内处理同一个事务
db (). Transaction ( func ( tx gorose. TxHandler ) error {
tx (). Insert ( & user )
tx (). Update ( & user )
tx (). To ( & user )
})
// 手动事务
tx = db (). Begin ()
tx (). Insert ( & user )
tx (). Update ( & user )
tx (). To ( & user )
tx (). Rollback ()
tx (). Commit ()
// 全自动嵌套事务
db (). Transaction ( func ( tx gorose. TxHandler ) error {
tx (). Insert ( & user )
...
// 自动子事务
tx (). Transaction ( func ( tx2 gorose. TxHandler ) error {
tx2 (). Update ( & user )
...
}
}
// 手动嵌套事务
var tx = db (). Begin ()
// 自动子事务
tx (). Begin () // 自动 savepoint 子事务
...
tx (). Rollback () // 自动回滚到上一个 savepoint
...
// 手动子事务
tx (). SavePoint ( "savepoint1" ) // 手动 savepoint 到 savepoint1(自定义名字)
...
tx (). RollbackTo ( "savepoint1" ) // 手动回滚到自定义的 savepoint
tx (). Commit ()เมื่อแทรกและอัปเดตข้อมูล หากคุณใช้โมเดลโครงสร้างเป็นออบเจ็กต์ข้อมูล ค่าประเภทศูนย์จะถูกละเว้นตามค่าเริ่มต้น หากคุณต้องการบังคับให้เขียน คุณสามารถส่งผ่านในฟิลด์ที่ต้องถูกบังคับให้เขียนโดยเริ่มจาก พารามิเตอร์ที่สอง เช่น:
var user = User { Id : 1 , Name : "test" }
// 这里不会对 sex 做任何操作,
//update user set name="test" where id=1
db (). Update ( & user )
// 这里会强制将sex更改为0
//update user set name="test", sex=0 where id=1
db (). Update ( & user , "sex" )
// 等同于
db (). Table ( & user ). Where ( "id" , 1 ). Update ( map [ string ] any { "name" : "test" , "sex" : 0 })) หากไม่มีเงื่อนไข โดยที่ฟิลด์ที่ระบุ pk ในแท็กจะถูกเพิ่มเป็นเงื่อนไขโดยอัตโนมัติ เช่น: db:"id,pk" เนื่องจากระบุ pk หากค่าของ id ไม่ใช่ 0 จะเป็น id จะได้รับการอัปเดตเป็นเงื่อนไขคีย์หลัก
ข้อมูลอ้างอิงอัปเดต
var user = User { Id : 1 }
db (). Delete ( & user )
// 等同于
db (). Table ( & user ). Where ( "id" , 1 ). Delete ()
// 要加上字段0值条件,只需要传入第二个字段,如:
// delete from users where id=1 and sex=0 and name=""
db (). Delete ( & user , "sex" , "name" ) db (). Table ( User {})
db (). Table ( "users" ) db (). Table ( User {}, "u" )
db (). Table ( "users" , "u" ) sub := db (). Table ( "users" ). Select ( "id" , "name" )
db (). Table ( sub ). Where ( "id" , ">" , 1 ). Get () type UserInfo struct {
UserId int64 `db:"user_id"`
TableName string `db:"user_info"`
} db (). Table ( "users" ). Join ( UserInfo {}, "user.id" , "=" , "user_info.user_id" ). Get () // select * from users a inner join user_info b on a.id=b.user_id
db (). Table ( "users" , "u" ). Join ( gorose . As ( UserInfo {}, "b" ), "u.id" , "=" , "b.user_id" ). Get ()
// 等同于
db (). Table ( User {}, "u" ). Join ( gorose . As ( "user_info" , "b" ), "u.id" , "=" , "b.user_id" ). Get () ใน gorose.As(UserInfo{}, "b") , user_info รับนามแฝง b
db (). Table ( "users" ). Join ( UserInfo {}, func ( wh builder. IJoinOn ) {
wh . On ( "a.id" , "b.user_id" ). OrOn ( "a.sex" , "b.sex" )
}). Get ()
// 等同于
db (). Table ( "users" ). JoinOn ( UserInfo {}, func ( wh builder. IJoinOn ) {
wh . On ( "a.id" , "b.user_id" ). OrOn ( "a.sex" , "b.sex" )
}). Get () เมื่อพารามิเตอร์ตัวที่สองของ Join คือ builder.IJoinOn จะเทียบเท่ากับการใช้งาน JoinOn (พารามิเตอร์ตัวที่สองมีตัวเตือนประเภทที่รัดกุม ซึ่งสะดวกสำหรับพร้อมท์ด่วนของ IDE)
// where id in (select user_id from user_info)
sub := db (). Table ( "user_info" ). Select ( "user_id" )
db (). Table ( User {}). Where ( "id" , "in" , sub ). Get () // where id in (select user_id from user_info)
db (). Table ( User {}). WhereSub ( "id" , "in" , func ( tx * builder. Context ) {
tx . Table ( "user_info" ). Select ( "user_id" )
}). Get () // where id in (select user_id from user_info)
sub := db (). Table ( "user_info" ). Select ( "user_id" )
db (). Table ( User {}). WhereBuilder ( "id" , "in" , sub ). Get ()ประเพณีสามประการข้างต้นเทียบเท่ากัน
// where id>1 and (sex=1 or sex=2)
db (). Table ( User {}). Where ( "id" , ">" , 1 ). Where ( func ( wh builder. IWhere ) {
wh . Where ( "sex" , 1 ). OrWhere ( "sex" , 2 )
})โดยที่ที่นี่เทียบเท่ากับ WhereNested
// where id>1 and (sex=1 or sex=2)
db (). Table ( User {}). Where ( "id" , ">" , 1 ). WhereNested ( func ( wh builder. IWhere ) {
wh . Where ( "sex" , 1 ). OrWhere ( "sex" , 2 )
})ประเพณีทั้งสองข้างต้นเทียบเท่ากัน
แบบสอบถามย่อยสามารถใช้ได้ใน Table, Where และ Join
sub := db (). Table ( "user" ). Where (). OrWhere ()
sub2 := db (). Table ( "address" ). Select ( "user_id" ). Where (). OrWhere ()
sub3 := db (). Table ( "user_info" ). Select ( "user_id" ). Where (). OrWhere ()ใช้ในตาราง ที่ไหน เข้าร่วม
db ().
Table ( sub , "a" ).
Join ( gorose . As ( sub2 , "b" ), "a.id" , "=" , "b.user_id" )).
WhereIn ( "a.id" , sub3 ).
Get ()ใช้ในยูเนี่ยน UnionAll
db ().
Table ( "users" ).
Union ( sub ).
Get () var sub2222 = db (). Table ( "user" ). Where (). OrWhere ()
var to [] User
db ().
Table ( "users" ).
UnionAll ( sub , sub2222 ).
To ( & to )ส่งกลับข้อมูลสองคอลัมน์ลงในแผนที่ คอลัมน์แรกคือค่า และคอลัมน์ที่สองคือคีย์
// select id,name from users
db (). Table ( "users" ). Pluck ( "name" , "id" )
// 返回 map[<id>]<name>, 实际得到 map[int64]string{1: "张三", 2: "李四"} ส่งกลับคอลัมน์ข้อมูลลงในอาร์เรย์
// select id,name from users
db (). Table ( "users" ). List ( "id" )
// 返回 []<id>, 实际得到 []int64{1,2,3} ใช้ฟิลด์โครงสร้างเป็นฟิลด์เลือก ใช้ค่าฟิลด์โครงสร้างเป็นเงื่อนไข โดยที่ผลลัพธ์ของการสืบค้นจะผูกไว้กับโครงสร้าง โดยรองรับหนึ่งฟิลด์ขึ้นไป
// 查询一条数据
var user User
db (). To ( & user )
// 查询条件,一条数据
// select id,name,email from users where id=1
var user = User { Id : 1 }
db (). To ( & user )
// 查询多条数据
var users [] User
db (). To ( & users )
// 查询条件,多条数据
var users [] User
db (). Where ( "id" , ">" , 1 ). To ( & users )มันถูกใช้เป็นฟิลด์โครงสร้างการโยงสำหรับผลลัพธ์การสืบค้นเท่านั้น โดยไม่ได้ใช้เป็นเขตข้อมูลและเงื่อนไขการสืบค้น มักใช้สำหรับการรวมหรือการรวมการสืบค้นเขตข้อมูลที่ระบุด้วยตนเอง
type Result struct {
Id int64 `db:"id"`
Aname string `db:"aname"`
Bname string `db:"bname"`
}
var res Result
// select a.id, a.name aname, b.name bname from a inner join b on a.id=b.aid where a.id>1
db (). Table ( "a" ). Join ( "b" , "a.id" , "b.aid" ). Select ( "a.id" , "a.name aname" , "b.name bname" ). Where ( "a.id" , ">" , 1 ). Bind ( & res )ชื่อที่แสดงของฟิลด์แบบสอบถามจะต้องเหมือนกับชื่อแท็กฟิลด์ (db) ของโครงสร้าง มิฉะนั้น จำนวนฟิลด์ที่จะไม่ได้รับมอบหมายอาจแตกต่างกัน
var list [] int
db (). Table ( "users" ). ListTo ( "age" , & list )
var pluck map [ int64 ] string
db (). Table ( "users" ). PluckTo ( "name" , "id" , & pluck )
var value int
db (). Table ( "users" ). ValueTo ( "age" , & value ) var sum int
db (). Table ( "users" ). SumTo ( "age" , & sum )
var max int
db (). Table ( "users" ). MaxTo ( "age" , & max )
var min int
db (). Table ( "users" ). MinTo ( "age" , & min )ตามค่าเริ่มต้น ระดับการแก้ไขข้อผิดพลาดของ slog ของไลบรารีอย่างเป็นทางการจะถูกใช้ หากคุณไม่ต้องการแสดงบันทึก sql คุณเพียงแค่ต้องตั้งค่าระดับการแก้ไขข้อผิดพลาดที่สูงกว่า เช่น: ข้อมูล คำเตือน ข้อผิดพลาด
type User struct {
Id int64 `db:"id,pk"`
Sex * int8 `db:"sex"` // 使用指针可以绑定 null 值
Age sql. NullInt64 `db:"age"` // 使用sql.NullInt64 可以绑定 null 值
}การกำหนดตัวชี้
var sex = int8 ( 1 )
var user = User { Id : 1 , Sex : & sex }
// 或者,快捷用法
var user = User { Id : 1 , Sex : gorose . Ptr ( int8 ( 1 ))}การมอบหมาย sql.Null*
var age = sql. NullInt64 { Int64 : 18 , Valid : true }ใช้ sql.Null*
if age . Valid {
fmt . Println ( age . Int64 )
}จะเห็นได้ว่าการจัดการกับ null ยังค่อนข้างลำบากอยู่บ้าง ดังนั้นจึงขอแนะนำว่าอย่าปล่อยให้เป็นโมฆะเมื่อออกแบบตาราง ค่าเริ่มต้นจะได้รับ และค่าเริ่มต้นส่วนใหญ่สามารถสอดคล้องกับ พิมพ์ค่าศูนย์ของ go
โต๊ะ
เลือก
เลือกดิบ
เพิ่มเลือก
เข้าร่วม
กรุ๊ปบี
มี
มีดิบ
หรือมี
หรือมีRaw
สั่งซื้อโดย
ขีดจำกัด
ออฟเซ็ต
ที่ไหน
ที่ไหนดิบ
หรือที่ไหน
หรือWhereRaw
ที่ไหนระหว่าง
หรือที่ไหนระหว่าง
ที่ไหนไม่อยู่ระหว่าง
หรือไม่อยู่ระหว่างนั้น
อยู่ที่ไหน
หรืออยู่ที่ไหน
ที่ไหนไม่อยู่
หรือWhereNotIn
โดยที่Null
หรือที่ไหนNull
โดยที่ไม่เป็นโมฆะ
หรือที่ไหนไม่Null
ชอบที่ไหน
หรือที่ไหนเหมือน
ที่ไหนไม่ชอบ
หรือที่ไหนไม่ชอบ
อยู่ที่ไหน
ที่ไม่มีอยู่
ที่ไหนไม่
รับ
อันดับแรก
หา
แทรก
อัปเดต
ลบ
สูงสุด
นาที
ผลรวม
เฉลี่ย
นับ
ใส่GetId
อัพเปอร์
แทรกหรือละเว้น
มีอยู่
ไม่มีอยู่จริง
ถอนขน
รายการ
ค่า
แบ่งหน้า
เพิ่มขึ้น
ลดลง
เพิ่มขึ้นแต่ละ
ลดลงแต่ละ
ตัด
ยูเนี่ยน
ยูเนี่ยนออล
SharedLock
ล็อคเพื่ออัปเดต
แทนที่
หน้าหนังสือ
LastSql
WhereBuilder
หรือWhereBuilder
WhereSub
หรือWhereSub
อยู่ที่ไหน
หรืออยู่ที่ไหน
ถึง
ผูก
รายการถึง
ถอนออก
ความคุ้มค่าถึง
ซัมทู
แม็กซ์ทู
ยูเนี่ยนทู
ยูเนี่ยนออลทู