GORM

ORM

What is ORM?

Object Relational Mapping

Object relational mapping

Object: instances of structures in Go, classes in Java

Relational: Relational databases, such as mysql

ORM the pros and cons

Advantages:

Improve development efficiency

Disadvantages:

  1. Sacrificing execution performance
  2. Sacrifice flexibility
  3. Weakening SQL Performance

GORM is quick to get started

Install GORM:

go get -u github.com/jinzhu/gorm
Copy the code

Connecting to a Database

Connect different databases need to import the corresponding data driver, GORM has been intimate for us to package some drivers, just need to import the need for the database driver as follows:

import _ "github.com/jinzhu/gorm/dialects/mysql"
// import _ "github.com/jinzhu/gorm/dialects/postgres"
// import _ "github.com/jinzhu/gorm/dialects/sqlite"
// import _ "github.com/jinzhu/gorm/dialects/mssql"
Copy the code

Connect the MySQL

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/mysql"
)
​
func main() {
  db, err := gorm.Open("mysql", "user:password@(localhost)/dbname?charset=utf8mb4&parseTime=True&loc=Local")
  defer db.Close()
}
Copy the code

Connect the PostgreSQL

The basic code is the same as above, noting that the corresponding postgres driver is introduced and the gorm.open () argument is specified correctly.

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/postgres"
)
​
func main() {
  db, err := gorm.Open("postgres", "host=myhost port=myport user=gorm dbname=gorm password=mypassword")
  defer db.Close()
}
Copy the code

Connect the Sqlite3

The basic code is the same as above, note that the corresponding SQLite driver is introduced and the gorm.open () parameter is specified correctly.

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/sqlite"
)
​
func main() {
  db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
  defer db.Close()
}
Copy the code

Connect the SQL Server

The basic code is the same as above, note that the corresponding MSSQL driver is introduced and the gorm.open () parameter is specified correctly.

import (
  "github.com/jinzhu/gorm"
  _ "github.com/jinzhu/gorm/dialects/mssql"
)
​
func main() {
  db, err := gorm.Open("mssql", "sqlserver://username:password@localhost:1433?database=dbname")
  defer db.Close()
}
Copy the code

GORM operates on MySql instances

Package the main import (" FMT "" github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql") / / the UserInfo = > data table type UserInfo struct {ID uint Name string Gender string Hobby string} func main() { Err := gorm.Open("mysql","root:mysql@tcp(127.0.0.1:3306)/user? Charset = UTf8MB4&parseTime =True&loc=Local") if err! Db.automigrate (&userInfo {}) db.automigrate (&userInfo {}) // Create row U1 := UserInfo{ID: 1, Name: "Mike", Gender: "male ", Hobby: "Running", Db.model (&u1).Update("hobby"," swim "); var u = new (UserInfo) db.first (u); FMT.Println(u) // Delete db.delete (&u1)}Copy the code

GORM MODEL definition

When using ORM tools, we usually need to define Models in code to map data tables in a database. In GORM, Models are usually normally defined constructs, basic GO types, or Pointers to them. Sql. Scanner and driver.Valuer interfaces are also supported.

gorm.Model

To facilitate Model definition, GORM has a built-in gorm.model structure. Gorm.Model is a Golang structure containing four fields: ID, CreatedAt, UpdatedAt, and DeletedAt.

// gorm.Model Definition Type Model struct {ID uint 'gorm:"primary_key"' CreatedAt time. time UpdatedAt time. time DeletedAt *time.Time }Copy the code

You can embed it in your own model:

Type User struct {gorm.Model Name string} struct {gorm.Copy the code

Of course, you can completely define the model yourself:

Type User struct {ID int Name string}Copy the code

Example model definition

Type User struct {gorm.Model // nested gorm.Model Name string Age SQL.NullInt64 Birthday *time `gorm:"type:varchar(100); Unique_index "' Role string 'gorm:"size:255"' // Set the field size to 255 MemberNumber *string 'gorm:"unique; Num int 'GORm :"AUTO_INCREMENT"' // Set Num to AUTO_INCREMENT type Address string IgnoreMe int 'gorm:"-"' // Ignore this field}Copy the code

Structure markup (tags)

Tags are optional when using structures to declare models. Gorm supports the following tags:

Supported structure tags (Struct tags)

Structure Tag describe
Column Specifies the column name
Type Specifies the column data type
Size Specifies the column size. The default is 255
PRIMARY_KEY Specify the column as the primary key
UNIQUE Specify the column as unique
DEFAULT Specify column defaults
PRECISION Specify column precision
NOT NULL Specifies the column as non-NULL
AUTO_INCREMENT Specifies whether the column is an increment type
INDEX Create indexes with or without names, or create composite indexes if multiple indexes have the same name
UNIQUE_INDEX andINDEXSimilar, except that a unique index is created
EMBEDDED Set the structure to embed
EMBEDDED_PREFIX Sets the prefix of the embedded structure
Ignore this field

Associate related tags (tags)

Structure Tag describe
MANY2MANY Specify join table
FOREIGNKEY Set up a foreign key
ASSOCIATION_FOREIGNKEY Set the associated foreign key
POLYMORPHIC Specifies the polymorphic type
POLYMORPHIC_VALUE Specify polymorphic values
JOINTABLE_FOREIGNKEY Specifies the foreign key for the join table
ASSOCIATION_JOINTABLE_FOREIGNKEY Specifies the associated foreign key for the join table
SAVE_ASSOCIATIONS Whether the save operation is automatically completed
ASSOCIATION_AUTOUPDATE Whether update operations are automatically completed
ASSOCIATION_AUTOCREATE Whether create operations are automatically completed
ASSOCIATION_SAVE_REFERENCE Whether operations related to the referenced save are automatically completed
PRELOAD Whether preloading operations are automatically completed

Conventions for primary keys, table names, and column names

Primary Key

By default, GORM uses a field named ID as the primary key of the table.

Animal struct {AnimalID int64} type Animal struct {AnimalID int64  `gorm:"primary_key"` Name string Age int64 }Copy the code

Table Name

The default table name is the plural of the structure name, for example:

Type User struct {} // default TableName is' users' // set User TableName to 'profiles' func (User) TableName() string {return "profiles"} func (u User) TableName() string { if u.Role == "admin" { return "admin_users" } else { return "users" } } // Disable the plural form of the default table name. If true, the default table name of 'User' is' User 'db.singularTable (true).Copy the code

You can also specify the Table name by using Table() :

Db.table ("deleted_users").createTable (&user {}) var deleted_users []User db.Table("deleted_users").Find(&deleted_users) //// SELECT * FROM deleted_users; db.Table("deleted_users").Where("name = ?" , "jinzhu").Delete() //// DELETE FROM deleted_users WHERE name = 'jinzhu';Copy the code

GORM also supports changing the default table name rule:

gorm.DefaultTableNameHandler = func (db *gorm.DB, defaultTableName string) string  {
  return "prefix_" + defaultTableName;
}
Copy the code

Column Name

Column names are generated by underlining the field names

type User struct { ID uint // column name is `id` Name string // column name is `name` Birthday time.Time // column name  is `birthday` CreatedAt time.Time // column name is `created_at` }Copy the code

Column names can be specified using the structure tag:

type Animal struct {
  AnimalId    int64     `gorm:"column:beast_id"`         // set column name to `beast_id`
  Birthday    time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
  Age         int64     `gorm:"column:age_of_the_beast"` // set column name to `age_of_the_beast`
}
Copy the code

Timestamp tracking

CreatedAt

If the model has a CreatedAt field, the value of that field will be when the record was first created.

Db.create (&user) // 'CreatedAt' will be the current time // The 'Update' method can be used to change the value of 'CreateAt' db.model (&user).update ("CreatedAt", time.now ())Copy the code

UpdatedAt

If the model has an UpdatedAt field, the value of that field will be the time each record is updated.

Db.save (&user) // 'UpdatedAt' will be the current time db.model (&user).Update("name", "Jinzhu ") // 'UpdatedAt' will be the current timeCopy the code

DeletedAt

If the model has a DeletedAt field, calling Delete to Delete the record sets the DeletedAt field to the current time rather than directly deleting the record from the database.