Intercambio de prácticas de uso de GoFrame ORM

¡Acostúmbrate a escribir juntos! Este es el tercer día de mi participación en el "Nuggets Daily New Plan · April Update Challenge", haz clic para ver los detalles del evento .

prefacio

Este mes continuaré actualizando los artículos relacionados con el lenguaje Go, especialmente GoFrame. Los estudiantes interesados ​​pueden seguirme e ir juntos.

Al mismo tiempo, resumiré y resumiré: "Práctica de desarrollo de China-Taiwán", "Práctica de implementación privada", "Comprensión profunda de Goroutine y práctica de uso", "Cómo reflejar el valor del lenguaje GO en el proceso de desarrollo ".

Decidido a precipitar algún contenido de alta calidad.

Hoy, este artículo GoFrame ORMcomparte los puntos de conocimiento relevantes que creo que son valiosos, posibles dificultades y mejores prácticas en el proceso de usarlo.

Tipos de valor y tipos de puntero

Cuando aprendí go por primera vez, estaba enredado con los tipos de valor y los tipos de puntero. Más tarde, en el proceso de usarlo, descubrí que no hay necesidad de enredar.

La ventaja del tipo puntero es que ahorra espacio de memoria. Múltiples variables apuntan a la misma dirección de memoria, y cada una es próspera. Una modificación se puede modificar en todas partes.

El tipo de valor puede entenderse simplemente como: para evitar este problema de modificar un lugar y modificar en todas partes, en algunos escenarios, no podemos simplemente considerar el rendimiento, y no podemos simplemente considerarlo 复用.

También se nos anima a usar tipos de punteros en GoFrame, por ejemplo:

ScanConvierta los resultados de la consulta en structobjetos usando

ScanAdmite la conversión del resultado de la consulta en un structobjeto, el resultado de la consulta debe ser un registro específico y el pointerparámetro debe ser structla dirección del puntero ( *structo **struct) del objeto, por ejemplo:

type User struct {
    Id         int
    Passport   string
    Password   string
    NickName   string
    CreateTime *gtime.Time
}
user := User{}
g.Model("user").Where("id", 1).Scan(&user)
复制代码

o

var user = User{}
g.Model("user").Where("id", 1).Scan(&user)
复制代码

Las dos primeras formas son preinicializar el objeto (asignar memoria por adelantado)

El método recomendado es el siguiente, este método solo realizará la inicialización y la asignación de memoria cuando se consultan los datos:

var user *User
g.Model("user").Where("id", 1).Scan(&user)
复制代码

Preste atención a la diferencia en el uso, especialmente la diferencia en el tipo de parámetros pasados ​​(el tipo de parámetro pasado en las dos primeras formas es *User, el tipo de parámetro pasado aquí es en realidad **User).

insertar datos

InsertarIgnorar

这个函数需要重点和大家说一下,因为我之前有Laravel的使用经验,Laravel中的InsertIgnore是配合唯一索引使用,意思是如果存在唯一主键或者唯一索引就忽略掉,不重复插入。

在GoFrame中是相反的:

GoFrame中默认的insert函数,就会根据唯一索引(或主键)执行,如果有存在的数据返回失败,不重复插入。

而GoFrame中的InsertIgnore是忽略错误继续插入,而不是存在就不插入。

大家在使用中要注意。

灵活执行SQL

我们要拼接自定义的sql参数怎么办法呢?

gdb.Raw()

示例如下:

OnDuplicate(g.Map{
    "nickname": gdb.Raw("CONCAT('name_', VALUES(`nickname`))"),
})
复制代码

gdb.Raw() 中的参数将作为sql执行的语句,不会自动转换成字符串类型,也不会作为预处理参数。

示例如下:

// INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES(id+2,'80','123456','wzy',now())
g.Model("user").Data(g.Map{
	"id":          gdb.Raw("id+2"),
	"passport":    "80",
	"password":    "123456",
	"nickname":    "wzy",
	"create_time": gdb.Raw("now()"),
}).Insert()
复制代码

链式安全

我们首先要有这个概念:什么是链式安全?

其实很简单:链式安全就是操作model模型时不会改变当前model对象,模型属性修改/条件叠加需要使用赋值来操作。

链式非安全或者非链式安全就是:操作model模型时会改变当前model对象的属性。

在GoFrame开发过程中,强烈建议使用gf gen dao生成的model和dao文件!!!

通过gf gen dao生成的model和dao文件默认是链式安全的。

举例如下:

func NewGomeStockDao() *GomeStockDao {
   return &GomeStockDao{
      M:     g.DB("default").Model("gome_stock").Safe(), //注意看这里
      DB:    g.DB("default"),
      Table: "gome_stock",
      Columns: gomeStockColumns{
         Id:            "id",
         MchWhseCode:   "mch_whse_code",
         MchWhseName:   "mch_whse_name",
         IsNationWide:  "is_nation_wide",
         Status:        "status",
         LastUpateTime: "last_upate_time",
      },
   }
}
复制代码

链式安全时我们如何叠加条件改变呢?

答案就是:通过赋值。

链式安全时通过 m = m.xxx 方式赋值实现链式调用

举例如下:

m := user.Where("status IN(?)", g.Slice{1,2,3})
if vip {
    // 查询条件通过赋值叠加
    m = m.And("money>=?", 1000000)
} else {
    // 查询条件通过赋值叠加
    m = m.And("money<?",  1000000)
}
//  vip: SELECT * FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT * FROM user WHERE status IN(1,2,3) AND money < 1000000
r, err := m.All()
//  vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money >= 1000000
// !vip: SELECT COUNT(1) FROM user WHERE status IN(1,2,3) AND money < 1000000
n, err := m.Count()
复制代码

总结

碰到好的东西就忍不住分享,我现在可以说是Go语言的忠实拥趸。

对GO感兴趣的朋友可以查看我之前写的文章,了解一下Go的魅力:

Go语言为什么值得学习?

我的PHP转Go之旅

回顾一下我的Go学习之旅

非常适合PHP和Java转Go学习的框架:GoFrame

欢迎大家关注我的Go语言学习专栏,我会持续更新在Go学习和使用过程中的干货分享。

Go语言学习专栏

最后

Gracias por leer y bienvenidos a todos: me gusta, favorito,moneda(concentrarse en)! ! !

8e95dac1fd0b2b1ff51c08757667c47a.gif

Supongo que te gusta

Origin juejin.im/post/7082278651681013773
Recomendado
Clasificación