Update Documents
This commit is contained in:
parent
772cd8814c
commit
45cfaf3466
@ -2,62 +2,70 @@
|
|||||||
|
|
||||||
The fantastic ORM library for Golang, aims to be developer friendly.
|
The fantastic ORM library for Golang, aims to be developer friendly.
|
||||||
|
|
||||||
|
[](https://gitter.im/jinzhu/gorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[](https://app.wercker.com/project/bykey/0cb7bb1039e21b74f8274941428e0921)
|
[](https://app.wercker.com/project/bykey/0cb7bb1039e21b74f8274941428e0921)
|
||||||
[](https://godoc.org/github.com/jinzhu/gorm)
|
[](https://godoc.org/github.com/jinzhu/gorm)
|
||||||
[](https://gitter.im/jinzhu/gorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
* Full-Featured ORM (almost)
|
* Full-Featured ORM (almost)
|
||||||
* Chainable API
|
* Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)
|
||||||
* Auto Migrations
|
|
||||||
* Relations (Has One, Has Many, Belongs To, Many To Many, Polymorphism)
|
|
||||||
* Callbacks (Before/After Create/Save/Update/Delete/Find)
|
* Callbacks (Before/After Create/Save/Update/Delete/Find)
|
||||||
* Preloading (eager loading)
|
* Preloading (eager loading)
|
||||||
* Transactions
|
* Transactions
|
||||||
* Embed Anonymous Struct
|
* Composite Primary Key
|
||||||
* Soft Deletes
|
* SQL Builder
|
||||||
* Customizable Logger
|
* Auto Migrations
|
||||||
* Iteration Support via Rows
|
* Logger
|
||||||
|
* Extendable, write Plugins based on GORM callbacks
|
||||||
* Every feature comes with tests
|
* Every feature comes with tests
|
||||||
* Developer Friendly
|
* Developer Friendly
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
```
|
```sh
|
||||||
go get -u github.com/jinzhu/gorm
|
go get -u github.com/jinzhu/gorm
|
||||||
```
|
```
|
||||||
|
|
||||||
## Upgrading
|
## Upgrading To V1.0
|
||||||
|
|
||||||
[Change Log](changelog.html)
|
* [CHANGELOG](changelog.html)
|
||||||
|
|
||||||
## Basic Usage
|
## Quick Start
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jinzhu/gorm"
|
||||||
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
|
)
|
||||||
|
|
||||||
type Product struct {
|
type Product struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
Code string
|
Code string
|
||||||
Price uint
|
Price uint
|
||||||
}
|
}
|
||||||
|
|
||||||
var db *gorm.DB
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
var err error
|
|
||||||
db, err = gorm.Open("sqlite", "test.db")
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
db, err := gorm.Open("sqlite", "test.db")
|
||||||
|
if err != nil {
|
||||||
|
panic("faield to connect database")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create
|
||||||
db.Create(&Product{Code: "L1212", Price: 1000})
|
db.Create(&Product{Code: "L1212", Price: 1000})
|
||||||
|
|
||||||
|
// Read
|
||||||
var product Product
|
var product Product
|
||||||
db.First(&product, 1) // find product with id 1
|
db.First(&product, 1) // find product with id 1
|
||||||
db.First(&product, "code = ?", "L1212") // find product with code l1212
|
db.First(&product, "code = ?", "L1212") // find product with code l1212
|
||||||
|
|
||||||
db.Model(&product).Update("Price", 2000) // update product's price to 2000
|
// Update - update product's price to 2000
|
||||||
|
db.Model(&product).Update("Price", 2000)
|
||||||
|
|
||||||
db.Delete(&product) // delete product
|
// Delete - delete product
|
||||||
|
db.Delete(&product)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
* [Migration](database.md#migration)
|
* [Migration](database.md#migration)
|
||||||
* [Models](models.md)
|
* [Models](models.md)
|
||||||
* [Model Defination](models.md#model-defination),
|
* [Model Defination](models.md#model-defination),
|
||||||
* [Naming Conventions & Overriding](models.md#conventions-overriding-conventions),
|
* [Conventions & Overriding](models.md#conventions),
|
||||||
* [Associations](associations.md)
|
* [Associations](associations.md)
|
||||||
* [Belongs To](associations.md#belongs-to)
|
* [Belongs To](associations.md#belongs-to)
|
||||||
* [Has One](associations.md#has-one)
|
* [Has One](associations.md#has-one)
|
||||||
@ -25,6 +25,7 @@
|
|||||||
* [Error Handling](advanced.md#error-handling)
|
* [Error Handling](advanced.md#error-handling)
|
||||||
* [Transactions](advanced.md#transactions)
|
* [Transactions](advanced.md#transactions)
|
||||||
* [Raw SQL & SQL Builder](advanced.md#sql-builder)
|
* [Raw SQL & SQL Builder](advanced.md#sql-builder)
|
||||||
|
* [Generic database interface sql.DB](advanced.md#generic-database-interface-sqldb)
|
||||||
* [Composite Primary Key](advanced.md#compose-primary-key)
|
* [Composite Primary Key](advanced.md#compose-primary-key)
|
||||||
* [Overriding Logger](advanced.md#logger)
|
* [Overriding Logger](advanced.md#logger)
|
||||||
* [Development](development.md)
|
* [Development](development.md)
|
||||||
|
@ -114,6 +114,22 @@ for rows.Next() {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Generic database interface sql.DB
|
||||||
|
|
||||||
|
Get generic database interface from `*gorm.DB` connection [*sql.DB](http://golang.org/pkg/database/sql/#DB)
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Get generic database object *sql.DB to use its functions
|
||||||
|
db.DB()
|
||||||
|
|
||||||
|
// Connection Pool
|
||||||
|
db.DB().SetMaxIdleConns(10)
|
||||||
|
db.DB().SetMaxOpenConns(100)
|
||||||
|
|
||||||
|
// Ping
|
||||||
|
db.DB().Ping()
|
||||||
|
```
|
||||||
|
|
||||||
## Composite Primary Key
|
## Composite Primary Key
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
@ -4,15 +4,31 @@
|
|||||||
|
|
||||||
## Connecting to a database
|
## Connecting to a database
|
||||||
|
|
||||||
|
When connect to a database, you need to import the database's driver first, for example:
|
||||||
|
|
||||||
|
```go
|
||||||
|
import _ "github.com/go-sql-driver/mysql"
|
||||||
|
```
|
||||||
|
|
||||||
|
GORM has wrapped some drivers, for easier to remember the import path, so you could import the mysql driver with
|
||||||
|
|
||||||
|
```go
|
||||||
|
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"
|
||||||
|
```
|
||||||
|
|
||||||
#### MySQL
|
#### MySQL
|
||||||
|
|
||||||
**NOTE** don't forgot params `parseTime` to handle data type `time.Time`, [more support parameters](https://github.com/go-sql-driver/mysql#parameters)
|
**NOTE** in order to handle `time.Time` you need to include `parseTime` as param [more supported parameters](https://github.com/go-sql-driver/mysql#parameters)
|
||||||
|
|
||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
_ "github.com/go-sql-driver/mysql"
|
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
|
db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")
|
||||||
}
|
}
|
||||||
@ -23,8 +39,9 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")
|
db, err := gorm.Open("postgres", "user=gorm dbname=gorm sslmode=disable")
|
||||||
}
|
}
|
||||||
@ -35,8 +52,9 @@ func main() {
|
|||||||
```go
|
```go
|
||||||
import (
|
import (
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
|
db, err := gorm.Open("sqlite3", "/tmp/gorm.db")
|
||||||
}
|
}
|
||||||
@ -44,37 +62,17 @@ func main() {
|
|||||||
|
|
||||||
#### Write Dialect for unsupported databases
|
#### Write Dialect for unsupported databases
|
||||||
|
|
||||||
GORM officially support above databases, for unsupported databaes, you could write a dialect for that.
|
GORM officially support above databases, but you could write a dialect for those unsupported databaes,
|
||||||
|
|
||||||
Refer: https://github.com/jinzhu/gorm/blob/master/dialect.go
|
Refer: [https://github.com/jinzhu/gorm/blob/master/dialect.go](https://github.com/jinzhu/gorm/blob/master/dialect.go)
|
||||||
|
|
||||||
|
|
||||||
## Generic database object *sql.DB
|
|
||||||
|
|
||||||
[*sql.DB](http://golang.org/pkg/database/sql/#DB)
|
|
||||||
|
|
||||||
```go
|
|
||||||
// Get generic database object *sql.DB to use its functions
|
|
||||||
db.DB()
|
|
||||||
|
|
||||||
// Connection Pool
|
|
||||||
db.DB().SetMaxIdleConns(10)
|
|
||||||
db.DB().SetMaxOpenConns(100)
|
|
||||||
|
|
||||||
// Ping
|
|
||||||
db.DB().Ping()
|
|
||||||
```
|
|
||||||
|
|
||||||
## Migration
|
## Migration
|
||||||
|
|
||||||
<!-- toc -->
|
|
||||||
|
|
||||||
### Auto Migration
|
### Auto Migration
|
||||||
|
|
||||||
Automatically migrate your schema, to keep your schema update to date
|
Automatically migrate your schema, to keep your schema update to date
|
||||||
|
|
||||||
**WARNING** AutoMigrate will ONLY create tables, columns and indexes if doesn't exist,
|
**WARNING** AutoMigrate will ONLY create tables, missing columns and missing indexes, **WON'T** change existing column's type or delete unused columns to protect your data
|
||||||
WON'T change existing column's type or delete unused columns to protect your data
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
db.AutoMigrate(&User{})
|
db.AutoMigrate(&User{})
|
||||||
@ -88,7 +86,7 @@ db.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&User{})
|
|||||||
### Has Table
|
### Has Table
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Check if model `User`'s table has been created or not
|
// Check model `User`'s table exists or not
|
||||||
db.HasTable(&User{})
|
db.HasTable(&User{})
|
||||||
|
|
||||||
// Check table `users` exists or not
|
// Check table `users` exists or not
|
||||||
@ -98,30 +96,39 @@ db.HasTable("users")
|
|||||||
### Create Table
|
### Create Table
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
// Create table for model `User`
|
||||||
db.CreateTable(&User{})
|
db.CreateTable(&User{})
|
||||||
|
|
||||||
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
|
|
||||||
// will append "ENGINE=InnoDB" to the SQL statement when creating table `users`
|
// will append "ENGINE=InnoDB" to the SQL statement when creating table `users`
|
||||||
|
db.Set("gorm:table_options", "ENGINE=InnoDB").CreateTable(&User{})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Drop table
|
### Drop table
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
// Drop model `User`'s table
|
||||||
db.DropTable(&User{})
|
db.DropTable(&User{})
|
||||||
|
|
||||||
|
// Drop table `users
|
||||||
|
db.DropTable("users")
|
||||||
|
|
||||||
|
// Drop model's `User`'s table and table `products`
|
||||||
|
db.DropTableIfExists(&User{}, "products")
|
||||||
```
|
```
|
||||||
|
|
||||||
### ModifyColumn
|
### ModifyColumn
|
||||||
|
|
||||||
Change column's type
|
Modify column's type to given value
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// change column description's data type to `text` for model `User`'s table
|
// change column description's data type to `text` for model `User`
|
||||||
db.Model(&User{}).ModifyColumn("description", "text")
|
db.Model(&User{}).ModifyColumn("description", "text")
|
||||||
```
|
```
|
||||||
|
|
||||||
### DropColumn
|
### DropColumn
|
||||||
|
|
||||||
```go
|
```go
|
||||||
|
// Drop column description from model `User`
|
||||||
db.Model(&User{}).DropColumn("description")
|
db.Model(&User{}).DropColumn("description")
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -139,16 +146,16 @@ db.Model(&User{}).AddForeignKey("city_id", "cities(id)", "RESTRICT", "RESTRICT")
|
|||||||
### Indexes
|
### Indexes
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Add index
|
// Add index for columns `name` with given name `idx_user_name`
|
||||||
db.Model(&User{}).AddIndex("idx_user_name", "name")
|
db.Model(&User{}).AddIndex("idx_user_name", "name")
|
||||||
|
|
||||||
// Multiple column index
|
// Add index for columns `name`, `age` with given name `idx_user_name_age`
|
||||||
db.Model(&User{}).AddIndex("idx_user_name_age", "name", "age")
|
db.Model(&User{}).AddIndex("idx_user_name_age", "name", "age")
|
||||||
|
|
||||||
// Add unique index
|
// Add unique index
|
||||||
db.Model(&User{}).AddUniqueIndex("idx_user_name", "name")
|
db.Model(&User{}).AddUniqueIndex("idx_user_name", "name")
|
||||||
|
|
||||||
// Multiple column unique index
|
// Add unique index for multiple columns
|
||||||
db.Model(&User{}).AddUniqueIndex("idx_user_name_age", "name", "age")
|
db.Model(&User{}).AddUniqueIndex("idx_user_name_age", "name", "age")
|
||||||
|
|
||||||
// Remove index
|
// Remove index
|
||||||
|
@ -9,26 +9,76 @@ type User struct {
|
|||||||
gorm.Model
|
gorm.Model
|
||||||
Birthday time.Time
|
Birthday time.Time
|
||||||
Age int
|
Age int
|
||||||
Name string `sql:"size:255"` // Default size for string is 255, you could reset it with this tag
|
Name string `gorm:"size:255"` // Default size for string is 255, reset it with this tag
|
||||||
Num int `sql:"AUTO_INCREMENT"`
|
Num int `gorm:"AUTO_INCREMENT"`
|
||||||
IgnoreMe int `sql:"-"` // Ignore this field
|
|
||||||
|
CreditCard CreditCard // One-To-One relationship (has one - use CreditCard's UserID as foreign key)
|
||||||
|
Emails []Email // One-To-Many relationship (has many - use Email's UserID as foreign key)
|
||||||
|
|
||||||
|
BillingAddress Address // One-To-One relationship (belongs to - use BillingAddressID as foreign key)
|
||||||
|
BillingAddressID sql.NullInt64
|
||||||
|
|
||||||
|
ShippingAddress Address // One-To-One relationship (belongs to - use ShippingAddressID as foreign key)
|
||||||
|
ShippingAddressID int
|
||||||
|
|
||||||
|
IgnoreMe int `gorm:"-"` // Ignore this field
|
||||||
|
Languages []Language `gorm:"many2many:user_languages;"` // Many-To-Many relationship, 'user_languages' is join table
|
||||||
|
}
|
||||||
|
|
||||||
|
type Email struct {
|
||||||
|
ID int
|
||||||
|
UserID int `gorm:"index"` // Foreign key (belongs to), tag `index` will create index for this column
|
||||||
|
Email string `gorm:"type:varchar(100);unique_index"` // `type` set sql type, `unique_index` will create unique index for this column
|
||||||
|
Subscribed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type Address struct {
|
||||||
|
ID int
|
||||||
|
Address1 string `gorm:"not null;unique"` // Set field as not nullable and unique
|
||||||
|
Address2 string `gorm:"type:varchar(100);unique"`
|
||||||
|
Post sql.NullString `gorm:"not null"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Language struct {
|
||||||
|
ID int
|
||||||
|
Name string `gorm:"index:idx_name_code"` // Create index with name, and will create combined index if find other fields defined same name
|
||||||
|
Code string `gorm:"index:idx_name_code"` // `unique_index` also works
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreditCard struct {
|
||||||
|
gorm.Model
|
||||||
|
UserID uint
|
||||||
|
Number string
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Conventions & Overriding Conventions
|
## Conventions
|
||||||
|
|
||||||
### `gorm.Model` struct
|
### `gorm.Model` struct
|
||||||
|
|
||||||
Gorm has defined struct `gorm.Model`, which could be embeded in your models, it will add fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt` to your model
|
Base model definition `gorm.Model`, including fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`, you could embed it in your model, or only write those fields you want
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// Model's definition
|
// Base Model's definition
|
||||||
type Model struct {
|
type Model struct {
|
||||||
ID uint `gorm:"primary_key"`
|
ID uint `gorm:"primary_key"`
|
||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
DeletedAt *time.Time
|
DeletedAt *time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add fields `ID`, `CreatedAt`, `UpdatedAt`, `DeletedAt`
|
||||||
|
type User struct {
|
||||||
|
gorm.Model
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only need field `ID`, `CreatedAt`
|
||||||
|
type User struct {
|
||||||
|
ID uint
|
||||||
|
CreatedAt time.Time
|
||||||
|
Name string
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Table name is the pluralized version of struct name
|
### Table name is the pluralized version of struct name
|
||||||
@ -63,6 +113,7 @@ type User struct {
|
|||||||
CreatedAt time.Time // column name will be `created_at`
|
CreatedAt time.Time // column name will be `created_at`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Overriding Column Name
|
||||||
type Animal struct {
|
type Animal struct {
|
||||||
AnimalId int64 `gorm:"column:beast_id"` // set column name to `beast_id`
|
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`
|
Birthday time.Time `gorm:"column:day_of_the_beast"` // set column name to `day_of_the_beast`
|
||||||
@ -74,11 +125,11 @@ type Animal struct {
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type User struct {
|
type User struct {
|
||||||
ID uint // field named `ID` is the default primary key for `User`
|
ID uint // field named `ID` will be the default primary field
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// your could also use tag `primary_key` to set other field as primary key
|
// Set a field to be primary field with tag `primary_key`
|
||||||
type Animal struct {
|
type Animal struct {
|
||||||
AnimalId int64 `gorm:"primary_key"` // set AnimalId to be primary key
|
AnimalId int64 `gorm:"primary_key"` // set AnimalId to be primary key
|
||||||
Name string
|
Name string
|
||||||
@ -108,4 +159,4 @@ db.Model(&user).Update("name", "jinzhu") // will set `UpdatedAt` to current time
|
|||||||
|
|
||||||
### Use `DeletedAt` to store record's deleted time if field exists
|
### Use `DeletedAt` to store record's deleted time if field exists
|
||||||
|
|
||||||
Delete records having `DeletedAt` field, it won't delete the record from database, but will set field `DeletedAt`'s value to current time.
|
Delete records having `DeletedAt` field, it won't be deleted from database, but only set field `DeletedAt`'s value to current time, and the record is not findable when querying, refer [Soft Delete](curd.html#soft-delete)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user