انتقل إلى تنفيذ PHP Laravel ORM، بما يتوافق مع وثائق Laravel الرسمية https://laravel.com/docs/10.x/queries.
وهو مقسم إلى نمط Go (استخدام ربط بنية الهيكل) ونمط 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 ,
}
},
) حاليًا، تم تنفيذ دعم قواعد البيانات الخمس المذكورة أعلاه بالنسبة لقواعد البيانات العامة، ما عليك سوى إضافة المزيد من واجهات gorose/driver/dialect.IDialect لقواعد البيانات غير العامة، طالما تم تنفيذ واجهة gorose/driver.IDriver. يمكن دعم أي قاعدة بيانات نظريًا، بما في ذلك redis وmongo وما إلى ذلك، ويمكن تنفيذ جميع عمليات سلسلة 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، إذا لم تكن قيمة المعرف 0، فسيتم إضافة المعرف سيتم تحديثه باعتباره شرط المفتاح الأساسي.
التحديث المرجعي
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 )
})الاستخدامان المذكوران أعلاه متساويان
يمكن استخدام الاستعلامات الفرعية في الجدول وأين والانضمام.
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 )بشكل افتراضي، يتم استخدام مستوى تصحيح الأخطاء للمكتبة الرسمية. إذا كنت لا ترغب في عرض سجل 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 )
}يمكن أن نرى أن التعامل مع القيم الفارغة لا يزال أمرًا صعبًا بعض الشيء، لذلك يوصى بعدم السماح بالقيم الفارغة عند تصميم الجدول، ويمكن أن تتوافق معظم القيم الافتراضية فقط اكتب قيمة الصفر من الذهاب.
طاولة
يختار
حدد الخام
أضف تحديد
ينضم
بواسطة
وجود
HaveRaw
أو وجود
OrHavingRaw
طلب حسب
حد
إزاحة
أين
WhereRaw
أو أين
OrWhereRaw
أين بين
أو أين بين
أين ليس بين
أو أين لا بين
حيث
OrWhereIn
WhereNotIn
OrWhereNotIn
حيثNull
OrWhereNull
WhereNotNull
OrWhereNotNull
أينمثل
OrWhereLike
WhereNotLike
OrWhereNotLike
أين يوجد
حيث لا يوجد
أين لا
يحصل
أولاً
يجد
إدراج
تحديث
يمسح
الأعلى
دقيقة
مجموع
متوسط
عدد
InsertGetId
منزعج
إدراجأوتجاهل
موجود
غير موجود
نتف
قائمة
قيمة
ترقيم الصفحات
زيادة
إنقاص
زيادة كل
إنقاص كل
اقتطاع
الاتحاد
UnionAll
ShareLock
LockForUpdate
يستبدل
صفحة
LastSql
com.WhereBuilder
OrWhereBuilder
WhereSub
OrWhereSub
حيثمتداخل
OrWhereNested
ل
ربط
قائمة إلى
نتف
القيمة إلى
مجموع
ماكستو
UnionTo
UnionAllTo