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