Gorm uses specifications and best practices for reference only

Package/function management

Under the Model layer, it is recommended to use one file for each table. For example, student:

// student.go
type student struct {
    id   uint
    name string. }func.{ // the method corresponding to the student table
}
Copy the code

It is recommended that the management of methods be managed using controller:

type StudentCtl struct {}

func (s * StudentCtl) QueryStudent(a){... }Copy the code

Maintain a default private controller in each file, exposing the method of obtaining controller to other packages/files:

var sc StudentCtl
func GetStudentCtl(a) *StudentCtl {
  return &sc
}
Copy the code

Why do YOU need CTLS? Ctl is convenient to manage the methods in the table. It clearly tells its callers that this is a model layer method and a method related to database operations. It needs to consider the problems related to database operations, such as transactions, rather than a common function. CTLS also help decouple methods when thinking about implementing functionality.

Database connection

Peter Bourgon in [Translation] Some of the theories of modern GO argue that package-level variables should not be generated, but rather that variables such as database connection variables should be passed, which is in fact a necessary method for transaction control. I recommend maintaining the global variable DB under the Model layer/package, using DB directly for queries, but forbidding assignment to DB (database connection assignment can cause very serious consequences, such as DB = nil) :

/ / model under the package
var db *gorm.DB
func initDB (a){
    db,err = gorm.Open()
    ...
}
Copy the code

For specific database connections, such as transaction control TX, it can be returned to avoid overwriting the database connection, and transaction control can be performed when transactions are needed:

func getDB(dbs ... *gorm.DB) *gorm.DB { if len(dbs) > 0 { return dbs[0] } return db } func (ctl *StudentCtl) QueryStudent(dbs... *gorm.DB){ tx := getDB(dbs...) . }Copy the code

Naming conventions

It is recommended to force the use of TableName to specify the mapping between tables and structures:

func (Users) TableName(a) string {
  return "users"
}
Copy the code

For queryclass methods, use QueryXXX; For update class methods, use UpdateXXX; For delete class methods, use DeleteXXX; Create class methods using CreateXXX:

func (ctl *StudnetCtl)QueryStudent(dbs... *gorm.DB){... }func (ctl *StudnetCtl)CreateStudent(dbs... *gorm.DB){... }func (ctl *StudnetCtl)UpdateStudent(map[string]interface{},dbs... *gorm.DB){... }func (ctl *StudnetCtl)DeleteStudent(dbs... *gorm.DB){... }Copy the code