Реализация PHP Laravel ORM Go в соответствии с официальной документацией laravel https://laravel.com/docs/10.x/queries.
Он разделен на стиль Go (использование привязки структуры структуры) и стиль PHP (использование структуры карты).
Для использования стиля PHP вы можете использовать документацию построителя запросов laravel в качестве справочника и попытаться добиться восстановления 1:1.
Он все еще находится на стадии бета-тестирования, поэтому используйте его с осторожностью. Поскольку он не помечен, его можно внедрить только с помощью мода Go.
# go.mod
require github.com/gohouse/gorose/v3 master
использование стиля go
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 могут быть реализованы через этот интерфейс. Все операции цепочки 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 }))
Если условиеwhere отсутствует, поле с указанным в теге pk будет автоматически добавлено в качестве условия, например: db:"id,pk"
. Поскольку указано pk, если значение id не равно 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 ()
Используется в Union, 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 )
}
Видно, что с нулевым значением все еще немного хлопотно, поэтому при проектировании таблицы рекомендуется не допускать значение нуля. Значения по умолчанию могут просто соответствовать значениям по умолчанию. введите нулевое значение go.
Стол
Выбирать
ВыберитеRaw
ДобавитьВыбрать
Присоединиться
ГруппаПо
Имея
Имея сырой
ИлиИмея
ИлиИмеяСырье
Заказ по
Лимит
Компенсировать
Где
ГдеRaw
ИлиГде
ИлиГдеRaw
Где между
ИлиГдеМежду
ГдеНеМежду
ИлиГдеНеМежду
ГдеВ
ИлиГдеВ
ГдеНеВ
ИлиГдеНеВ
ГдеNull
ИлиГдеNull
ГдеNotNull
ИлиГдеNotNull
ГдеНравится
ИлиГдеНравится
ГдеNotLike
ИлиГдеНе Нравится
ГдеСуществует
ГдеНеСуществует
ГдеНе
Получать
Первый
Находить
Вставлять
Обновлять
Удалить
Макс
Мин
Сумма
Среднее
Считать
ВставкаGetId
Upsert
Вставитьилиигнорировать
Существует
Не существует
Срывать
Список
Ценить
Разбивать на страницы
Приращение
Декремент
ИнкрементКаждый
ДекрементКаждый
Усечь
Союз
СоюзВсе
SharedLock
Локфорапдате
Заменять
Страница
ЛастСкл
Гдестроитель
ИлиWhereBuilder
ГдеSub
ИлиГдеSub
Где вложен
ИлиГдеВложенный
К
Связывать
СписокTo
ВырватьTo
ЗначениеTo
СуммаТо
МаксТо
ЮнионТо
СоюзAllTo