Compartilhamento de prática de uso do GoFrame ORM

Crie o hábito de escrever juntos! Este é o terceiro dia da minha participação no "Nuggets Daily New Plan · April Update Challenge", clique para ver os detalhes do evento .

prefácio

Este mês, continuarei atualizando artigos relacionados ao idioma Go, especialmente GoFrame. Os alunos interessados ​​podem me seguir e ir juntos.

Ao mesmo tempo, vou resumir e resumir: "Prática de Desenvolvimento China-Taiwan", "Prática de Implantação Privada", "Compreensão Aprofundada de Goroutine e Prática de Uso", "Como Refletir o Valor da Linguagem GO no Processo de Desenvolvimento ".

Determinado a precipitar algum conteúdo de alta qualidade.

Hoje, este artigo GoFrame ORMcompartilha os pontos de conhecimento relevantes que considero valiosos, possíveis armadilhas e melhores práticas no processo de usá-lo.

Tipos de valor e tipos de ponteiro

Quando aprendi a ir, eu estava emaranhado com tipos de valor e tipos de ponteiro. Mais tarde, no processo de usá-lo, descobri que não há necessidade de emaranhar.

A vantagem do tipo de ponteiro é que ele economiza espaço de memória. Várias variáveis ​​apontam para o mesmo endereço de memória, e cada uma é próspera. Uma modificação pode ser modificada em todos os lugares.

O tipo de valor pode ser entendido simplesmente como: para evitar esse problema de modificar um local e modificar em todos os lugares, em alguns cenários, não podemos simplesmente considerar o desempenho, e não podemos apenas considerá-lo 复用.

Também somos incentivados a usar tipos de ponteiro no GoFrame, por exemplo:

ScanConverta os resultados da consulta em structobjetos usando

ScanSuporta a conversão do resultado da consulta em um structobjeto, o resultado da consulta deve ser um registro específico, e o pointerparâmetro deve ser structo endereço do ponteiro ( *structou **struct) do objeto, por exemplo:

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

ou

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

As duas primeiras maneiras são pré-inicializar o objeto (alocar memória com antecedência)

O método recomendado é o seguinte, este método só realizará a inicialização e alocação de memória quando os dados forem consultados:

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

Preste atenção à diferença de uso, especialmente a diferença no tipo de parâmetro passado (o tipo de parâmetro passado nas duas primeiras maneiras é *User, o tipo de parâmetro passado aqui é na verdade **User).

inserir dados

Inserir Ignorar

这个函数需要重点和大家说一下,因为我之前有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语言学习专栏

最后

Obrigado por ler, e bem-vindos a todos: like, favorito,moeda(focar em)! ! !

8e95dac1fd0b2b1ff51c08757667c47a.gif

Acho que você gosta

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