1337 lines
109 KiB
HTML
1337 lines
109 KiB
HTML
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
<title>Gorm by jinzhu</title>
|
|
|
|
<link rel="stylesheet" href="stylesheets/styles.css">
|
|
<link rel="stylesheet" href="stylesheets/github-light.css">
|
|
<script src="javascripts/scale.fix.js"></script>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
|
|
<!--[if lt IE 9]>
|
|
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
<![endif]-->
|
|
</head>
|
|
<body>
|
|
<div class="wrapper">
|
|
<header>
|
|
<h1 class="header">Gorm</h1>
|
|
<p class="header">The fantastic ORM library for Golang, aims to be developer friendly.</p>
|
|
|
|
<ul>
|
|
<li class="download"><a class="buttons" href="https://github.com/jinzhu/gorm/zipball/master">Download ZIP</a></li>
|
|
<li class="download"><a class="buttons" href="https://github.com/jinzhu/gorm/tarball/master">Download TAR</a></li>
|
|
<li><a class="buttons github" href="https://github.com/jinzhu/gorm">View On GitHub</a></li>
|
|
</ul>
|
|
|
|
<p class="header">This project is maintained by <a class="header name" href="https://github.com/jinzhu">jinzhu</a></p>
|
|
|
|
|
|
</header>
|
|
<section>
|
|
<h1>
|
|
<a id="gorm" class="anchor" href="#gorm" aria-hidden="true"><span class="octicon octicon-link"></span></a>GORM</h1>
|
|
|
|
<p><a href="https://gitter.im/jinzhu/gorm?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" alt="Join the chat at https://gitter.im/jinzhu/gorm"></a></p>
|
|
|
|
<p>The fantastic ORM library for Golang, aims to be developer friendly.</p>
|
|
|
|
<p><a href="https://app.wercker.com/project/bykey/0cb7bb1039e21b74f8274941428e0921"><img src="https://app.wercker.com/status/0cb7bb1039e21b74f8274941428e0921/s/master" alt="wercker status" title="wercker status"></a></p>
|
|
|
|
<h2>
|
|
<a id="overview" class="anchor" href="#overview" aria-hidden="true"><span class="octicon octicon-link"></span></a>Overview</h2>
|
|
|
|
<ul>
|
|
<li>Full-Featured ORM (almost)</li>
|
|
<li>Chainable API</li>
|
|
<li>Auto Migrations</li>
|
|
<li>Relations (Has One, Has Many, Belongs To, Many To Many, <a href="#polymorphism">Polymorphism</a>)</li>
|
|
<li>Callbacks (Before/After Create/Save/Update/Delete/Find)</li>
|
|
<li>Preloading (eager loading)</li>
|
|
<li>Transactions</li>
|
|
<li>Embed Anonymous Struct</li>
|
|
<li>Soft Deletes</li>
|
|
<li>Customizable Logger</li>
|
|
<li>Iteration Support via <a href="#row--rows">Rows</a>
|
|
</li>
|
|
<li>Every feature comes with tests</li>
|
|
<li>Developer Friendly</li>
|
|
</ul>
|
|
|
|
<h1>
|
|
<a id="getting-started" class="anchor" href="#getting-started" aria-hidden="true"><span class="octicon octicon-link"></span></a>Getting Started</h1>
|
|
|
|
<h2>
|
|
<a id="install" class="anchor" href="#install" aria-hidden="true"><span class="octicon octicon-link"></span></a>Install</h2>
|
|
|
|
<pre><code>go get -u github.com/jinzhu/gorm
|
|
</code></pre>
|
|
|
|
<h2>
|
|
<a id="documentation" class="anchor" href="#documentation" aria-hidden="true"><span class="octicon octicon-link"></span></a>Documentation</h2>
|
|
|
|
<p><a href="https://godoc.org/github.com/jinzhu/gorm"><img src="https://godoc.org/github.com/jinzhu/gorm?status.svg" alt="GoDoc"></a></p>
|
|
|
|
<p><code>go doc</code> format documentation for this project can be viewed online without
|
|
installing the package by using the GoDoc page at:
|
|
<a href="http://godoc.org/github.com/jinzhu/gorm">http://godoc.org/github.com/jinzhu/gorm</a></p>
|
|
|
|
<h2>
|
|
<a id="table-of-contents" class="anchor" href="#table-of-contents" aria-hidden="true"><span class="octicon octicon-link"></span></a>Table of Contents</h2>
|
|
|
|
<ul>
|
|
<li><a href="#define-models-structs">Define Models (Structs)</a></li>
|
|
<li><a href="#conventions">Conventions</a></li>
|
|
<li><a href="#initialize-database">Initialize Database</a></li>
|
|
<li><a href="#migration">Migration</a></li>
|
|
<li>
|
|
<a href="#basic-crud">Basic CRUD</a>
|
|
|
|
<ul>
|
|
<li><a href="#create-record">Create</a></li>
|
|
<li>
|
|
<a href="#query">Query</a>
|
|
|
|
<ul>
|
|
<li><a href="#query-with-where-plain-sql">Query With Where (Plain SQL)</a></li>
|
|
<li><a href="#query-with-where-struct--map">Query With Where (Struct & Map)</a></li>
|
|
<li><a href="#query-with-not">Query With Not</a></li>
|
|
<li><a href="#query-with-inline-condition">Query With Inline Condition</a></li>
|
|
<li><a href="#query-with-or">Query With Or</a></li>
|
|
<li><a href="#query-chains">Query Chains</a></li>
|
|
<li><a href="#preloading-eager-loading">Preloading (Eager loading)</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#update">Update</a>
|
|
|
|
<ul>
|
|
<li><a href="#update-without-callbacks">Update Without Callbacks</a></li>
|
|
<li><a href="#batch-updates">Batch Updates</a></li>
|
|
<li><a href="#update-with-sql-expression">Update with SQL Expression</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#delete">Delete</a>
|
|
|
|
<ul>
|
|
<li><a href="#batch-delete">Batch Delete</a></li>
|
|
<li><a href="#soft-delete">Soft Delete</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#associations">Associations</a>
|
|
|
|
<ul>
|
|
<li><a href="#has-one">Has One</a></li>
|
|
<li><a href="#belongs-to">Belongs To</a></li>
|
|
<li><a href="#has-many">Has Many</a></li>
|
|
<li><a href="#many-to-many">Many To Many</a></li>
|
|
<li><a href="#polymorphism">Polymorphism</a></li>
|
|
</ul>
|
|
</li>
|
|
<li>
|
|
<a href="#advanced-usage">Advanced Usage</a>
|
|
|
|
<ul>
|
|
<li><a href="#firstorinit">FirstOrInit</a></li>
|
|
<li><a href="#firstorcreate">FirstOrCreate</a></li>
|
|
<li><a href="#select">Select</a></li>
|
|
<li><a href="#order">Order</a></li>
|
|
<li><a href="#limit">Limit</a></li>
|
|
<li><a href="#offset">Offset</a></li>
|
|
<li><a href="#count">Count</a></li>
|
|
<li><a href="#pluck">Pluck</a></li>
|
|
<li><a href="#raw-sql">Raw SQL</a></li>
|
|
<li><a href="#row--rows">Row & Rows</a></li>
|
|
<li><a href="#scan">Scan</a></li>
|
|
<li><a href="#group--having">Group & Having</a></li>
|
|
<li><a href="#joins">Joins</a></li>
|
|
<li><a href="#transactions">Transactions</a></li>
|
|
<li><a href="#scopes">Scopes</a></li>
|
|
<li><a href="#callbacks">Callbacks</a></li>
|
|
<li><a href="#specifying-the-table-name">Specifying The Table Name</a></li>
|
|
<li><a href="#error-handling">Error Handling</a></li>
|
|
<li><a href="#logger">Logger</a></li>
|
|
<li><a href="#existing-schema">Existing Schema</a></li>
|
|
<li><a href="#composite-primary-key">Composite Primary Key</a></li>
|
|
<li><a href="#database-indexes--foreign-key">Database Indexes & Foreign Key</a></li>
|
|
<li><a href="#default-values">Default values</a></li>
|
|
<li><a href="#more-examples-with-query-chain">More examples with query chain</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h2>
|
|
<a id="define-models-structs" class="anchor" href="#define-models-structs" aria-hidden="true"><span class="octicon octicon-link"></span></a>Define Models (Structs)</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">User</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Birthday</span> time.<span class="pl-smi">Time</span>
|
|
<span class="pl-v">Age</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"size:255"<span class="pl-pds">`</span></span> <span class="pl-c">// Default size for string is 255, you could reset it with this tag</span>
|
|
<span class="pl-v">Num</span> <span class="pl-k">int</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"AUTO_INCREMENT"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">CreatedAt</span> time.<span class="pl-smi">Time</span>
|
|
<span class="pl-v">UpdatedAt</span> time.<span class="pl-smi">Time</span>
|
|
<span class="pl-v">DeletedAt</span> *time.<span class="pl-smi">Time</span>
|
|
|
|
<span class="pl-v">Emails</span> []<span class="pl-v">Email</span> <span class="pl-c">// One-To-Many relationship (has many)</span>
|
|
<span class="pl-v">BillingAddress</span> <span class="pl-v">Address</span> <span class="pl-c">// One-To-One relationship (has one)</span>
|
|
<span class="pl-v">BillingAddressID</span> sql.<span class="pl-smi">NullInt64</span> <span class="pl-c">// Foreign key of BillingAddress</span>
|
|
<span class="pl-v">ShippingAddress</span> <span class="pl-v">Address</span> <span class="pl-c">// One-To-One relationship (has one)</span>
|
|
<span class="pl-v">ShippingAddressID</span> <span class="pl-k">int</span> <span class="pl-c">// Foreign key of ShippingAddress</span>
|
|
<span class="pl-v">IgnoreMe</span> <span class="pl-k">int</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"-"<span class="pl-pds">`</span></span> <span class="pl-c">// Ignore this field</span>
|
|
<span class="pl-v">Languages</span> []<span class="pl-v">Language</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"many2many:user_languages;"<span class="pl-pds">`</span></span> <span class="pl-c">// Many-To-Many relationship, 'user_languages' is join table</span>
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">Email</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">UserID</span> <span class="pl-k">int</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"index"<span class="pl-pds">`</span></span> <span class="pl-c">// Foreign key (belongs to), tag `index` will create index for this field when using AutoMigrate</span>
|
|
<span class="pl-v">Email</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"type:varchar(100);unique_index"<span class="pl-pds">`</span></span> <span class="pl-c">// Set field's sql type, tag `unique_index` will create unique index</span>
|
|
<span class="pl-v">Subscribed</span> <span class="pl-k">bool</span>
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">Address</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Address1</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"not null;unique"<span class="pl-pds">`</span></span> <span class="pl-c">// Set field as not nullable and unique</span>
|
|
<span class="pl-v">Address2</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"type:varchar(100);unique"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Post</span> sql.<span class="pl-smi">NullString</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"not null"<span class="pl-pds">`</span></span>
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">Language</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"index:idx_name_code"<span class="pl-pds">`</span></span> <span class="pl-c">// Create index with name, and will create combined index if find other fields defined same name</span>
|
|
<span class="pl-v">Code</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"index:idx_name_code"<span class="pl-pds">`</span></span> <span class="pl-c">// `unique_index` also works</span>
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="conventions" class="anchor" href="#conventions" aria-hidden="true"><span class="octicon octicon-link"></span></a>Conventions</h2>
|
|
|
|
<ul>
|
|
<li>Table name is the plural of struct name's snake case, you can disable pluralization with <code>db.SingularTable(true)</code>, or <a href="#specifying-the-table-name-for-a-struct-permanently-with-tablename">Specifying The Table Name For A Struct Permanently With TableName</a>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">User</span> <span class="pl-k">struct</span>{} <span class="pl-c">// struct User's database table name is "users" by default, will be "user" if you disabled pluralisation</span></pre></div>
|
|
|
|
<ul>
|
|
<li>Column name is the snake case of field's name</li>
|
|
<li>Use <code>ID</code> field as primary key</li>
|
|
<li>Use <code>CreatedAt</code> to store record's created time if field exists</li>
|
|
<li>Use <code>UpdatedAt</code> to store record's updated time if field exists</li>
|
|
<li>Use <code>DeletedAt</code> to store record's deleted time if field exists <a href="#soft-delete">Soft Delete</a>
|
|
</li>
|
|
<li>Gorm provide a default model struct, you could embed it in your struct</li>
|
|
</ul>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Model</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">uint</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"primary_key"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">CreatedAt</span> time.<span class="pl-smi">Time</span>
|
|
<span class="pl-v">UpdatedAt</span> time.<span class="pl-smi">Time</span>
|
|
<span class="pl-v">DeletedAt</span> *time.<span class="pl-smi">Time</span>
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">User</span> <span class="pl-k">struct</span> {
|
|
gorm.<span class="pl-smi">Model</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span>
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="initialize-database" class="anchor" href="#initialize-database" aria-hidden="true"><span class="octicon octicon-link"></span></a>Initialize Database</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">import</span> (
|
|
<span class="pl-s"><span class="pl-pds">"</span>github.com/jinzhu/gorm<span class="pl-pds">"</span></span>
|
|
_ <span class="pl-s"><span class="pl-pds">"</span>github.com/lib/pq<span class="pl-pds">"</span></span>
|
|
_ <span class="pl-s"><span class="pl-pds">"</span>github.com/go-sql-driver/mysql<span class="pl-pds">"</span></span>
|
|
_ <span class="pl-s"><span class="pl-pds">"</span>github.com/mattn/go-sqlite3<span class="pl-pds">"</span></span>
|
|
)
|
|
|
|
<span class="pl-smi">db</span>, <span class="pl-smi">err</span> <span class="pl-k">:=</span> gorm.<span class="pl-c1">Open</span>(<span class="pl-s"><span class="pl-pds">"</span>postgres<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>user=gorm dbname=gorm sslmode=disable<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">// db, err := gorm.Open("foundation", "dbname=gorm") // FoundationDB.</span>
|
|
<span class="pl-c">// db, err := gorm.Open("mysql", "user:password@/dbname?charset=utf8&parseTime=True&loc=Local")</span>
|
|
<span class="pl-c">// db, err := gorm.Open("sqlite3", "/tmp/gorm.db")</span>
|
|
|
|
<span class="pl-c">// You can also use an existing database connection handle</span>
|
|
<span class="pl-c">// dbSql, _ := sql.Open("postgres", "user=gorm dbname=gorm sslmode=disable")</span>
|
|
<span class="pl-c">// db, _ := gorm.Open("postgres", dbSql)</span>
|
|
|
|
<span class="pl-c">// Get database connection handle [*sql.DB](http://golang.org/pkg/database/sql/#DB)</span>
|
|
db.<span class="pl-c1">DB</span>()
|
|
|
|
<span class="pl-c">// Then you could invoke `*sql.DB`'s functions with it</span>
|
|
db.<span class="pl-c1">DB</span>().<span class="pl-c1">Ping</span>()
|
|
db.<span class="pl-c1">DB</span>().<span class="pl-c1">SetMaxIdleConns</span>(<span class="pl-c1">10</span>)
|
|
db.<span class="pl-c1">DB</span>().<span class="pl-c1">SetMaxOpenConns</span>(<span class="pl-c1">100</span>)
|
|
|
|
<span class="pl-c">// Disable table name's pluralization</span>
|
|
db.<span class="pl-c1">SingularTable</span>(<span class="pl-c1">true</span>)</pre></div>
|
|
|
|
<h2>
|
|
<a id="migration" class="anchor" href="#migration" aria-hidden="true"><span class="octicon octicon-link"></span></a>Migration</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Create table</span>
|
|
db.<span class="pl-c1">CreateTable</span>(&User{})
|
|
db.<span class="pl-c1">Set</span>(<span class="pl-s"><span class="pl-pds">"</span>gorm:table_options<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>ENGINE=InnoDB<span class="pl-pds">"</span></span>).<span class="pl-c1">CreateTable</span>(&User{})
|
|
|
|
<span class="pl-c">// Drop table</span>
|
|
db.<span class="pl-c1">DropTable</span>(&User{})
|
|
|
|
<span class="pl-c">// ModifyColumn</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">ModifyColumn</span>(<span class="pl-s"><span class="pl-pds">"</span>description<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>text<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// DropColumn</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">DropColumn</span>(<span class="pl-s"><span class="pl-pds">"</span>description<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// Automating Migration</span>
|
|
db.<span class="pl-c1">AutoMigrate</span>(&User{})
|
|
db.<span class="pl-c1">Set</span>(<span class="pl-s"><span class="pl-pds">"</span>gorm:table_options<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>ENGINE=InnoDB<span class="pl-pds">"</span></span>).<span class="pl-c1">AutoMigrate</span>(&User{})
|
|
db.<span class="pl-c1">AutoMigrate</span>(&User{}, &Product{}, &Order{})
|
|
<span class="pl-c">// Feel free to change your struct, AutoMigrate will keep your database up-to-date.</span>
|
|
<span class="pl-c">// AutoMigrate will ONLY add *new columns* and *new indexes*,</span>
|
|
<span class="pl-c">// WON'T update current column's type or delete unused columns, to protect your data.</span>
|
|
<span class="pl-c">// If the table is not existing, AutoMigrate will create the table automatically.</span></pre></div>
|
|
|
|
<h1>
|
|
<a id="basic-crud" class="anchor" href="#basic-crud" aria-hidden="true"><span class="octicon octicon-link"></span></a>Basic CRUD</h1>
|
|
|
|
<h2>
|
|
<a id="create-record" class="anchor" href="#create-record" aria-hidden="true"><span class="octicon octicon-link"></span></a>Create Record</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-smi">user</span> <span class="pl-k">:=</span> <span class="pl-v">User</span>{Name: <span class="pl-s"><span class="pl-pds">"</span>Jinzhu<span class="pl-pds">"</span></span>, <span class="pl-v">Age</span>: <span class="pl-c1">18</span>, <span class="pl-v">Birthday</span>: time.<span class="pl-c1">Now</span>()}
|
|
|
|
db.<span class="pl-c1">NewRecord</span>(user) <span class="pl-c">// => returns `true` if primary key is blank</span>
|
|
|
|
db.<span class="pl-c1">Create</span>(&user)
|
|
|
|
db.<span class="pl-c1">NewRecord</span>(user) <span class="pl-c">// => return `false` after `user` created</span>
|
|
|
|
<span class="pl-c">// Associations will be inserted automatically when save the record</span>
|
|
<span class="pl-smi">user</span> <span class="pl-k">:=</span> <span class="pl-v">User</span>{
|
|
<span class="pl-v">Name</span>: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>,
|
|
<span class="pl-v">BillingAddress</span>: <span class="pl-v">Address</span>{Address1: <span class="pl-s"><span class="pl-pds">"</span>Billing Address - Address 1<span class="pl-pds">"</span></span>},
|
|
<span class="pl-v">ShippingAddress</span>: <span class="pl-v">Address</span>{Address1: <span class="pl-s"><span class="pl-pds">"</span>Shipping Address - Address 1<span class="pl-pds">"</span></span>},
|
|
<span class="pl-v">Emails</span>: []<span class="pl-v">Email</span>{{Email: <span class="pl-s"><span class="pl-pds">"</span>jinzhu@example.com<span class="pl-pds">"</span></span>}, {Email: <span class="pl-s"><span class="pl-pds">"</span>jinzhu-2@example@example.com<span class="pl-pds">"</span></span>}},
|
|
<span class="pl-v">Languages</span>: []<span class="pl-v">Language</span>{{Name: <span class="pl-s"><span class="pl-pds">"</span>ZH<span class="pl-pds">"</span></span>}, {Name: <span class="pl-s"><span class="pl-pds">"</span>EN<span class="pl-pds">"</span></span>}},
|
|
}
|
|
|
|
db.<span class="pl-c1">Create</span>(&user)
|
|
<span class="pl-c">//// BEGIN TRANSACTION;</span>
|
|
<span class="pl-c">//// INSERT INTO "addresses" (address1) VALUES ("Billing Address - Address 1");</span>
|
|
<span class="pl-c">//// INSERT INTO "addresses" (address1) VALUES ("Shipping Address - Address 1");</span>
|
|
<span class="pl-c">//// INSERT INTO "users" (name,billing_address_id,shipping_address_id) VALUES ("jinzhu", 1, 2);</span>
|
|
<span class="pl-c">//// INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu@example.com");</span>
|
|
<span class="pl-c">//// INSERT INTO "emails" (user_id,email) VALUES (111, "jinzhu-2@example.com");</span>
|
|
<span class="pl-c">//// INSERT INTO "languages" ("name") VALUES ('ZH');</span>
|
|
<span class="pl-c">//// INSERT INTO user_languages ("user_id","language_id") VALUES (111, 1);</span>
|
|
<span class="pl-c">//// INSERT INTO "languages" ("name") VALUES ('EN');</span>
|
|
<span class="pl-c">//// INSERT INTO user_languages ("user_id","language_id") VALUES (111, 2);</span>
|
|
<span class="pl-c">//// COMMIT;</span></pre></div>
|
|
|
|
<p>Refer <a href="#associations">Associations</a> for more details</p>
|
|
|
|
<h2>
|
|
<a id="query" class="anchor" href="#query" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Get the first record</span>
|
|
db.<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users ORDER BY id LIMIT 1;</span>
|
|
|
|
<span class="pl-c">// Get the last record</span>
|
|
db.<span class="pl-c1">Last</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users ORDER BY id DESC LIMIT 1;</span>
|
|
|
|
<span class="pl-c">// Get all records</span>
|
|
db.<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users;</span>
|
|
|
|
<span class="pl-c">// Get record with primary key</span>
|
|
db.<span class="pl-c1">First</span>(&user, <span class="pl-c1">10</span>)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE id = 10;</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="query-with-where-plain-sql" class="anchor" href="#query-with-where-plain-sql" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query With Where (Plain SQL)</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Get the first matched record</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'jinzhu' limit 1;</span>
|
|
|
|
<span class="pl-c">// Get all matched records</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'jinzhu';</span>
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name <> ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
|
|
<span class="pl-c">// IN</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name in (?)<span class="pl-pds">"</span></span>, []<span class="pl-k">string</span>{<span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu 2<span class="pl-pds">"</span></span>}).<span class="pl-c1">Find</span>(&users)
|
|
|
|
<span class="pl-c">// LIKE</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name LIKE ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-ii">%</span>jin<span class="pl-ii">%</span><span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
|
|
<span class="pl-c">// AND</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ? and age >= ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>22<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
|
|
<span class="pl-c">// Time</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>updated_at > ?<span class="pl-pds">"</span></span>, lastWeek).<span class="pl-c1">Find</span>(&users)
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>created_at BETWEEN ? AND ?<span class="pl-pds">"</span></span>, lastWeek, today).<span class="pl-c1">Find</span>(&users)</pre></div>
|
|
|
|
<h3>
|
|
<a id="query-with-where-struct--map" class="anchor" href="#query-with-where-struct--map" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query With Where (Struct & Map)</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Struct</span>
|
|
db.<span class="pl-c1">Where</span>(&User{Name: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>, <span class="pl-v">Age</span>: <span class="pl-c1">20</span>}).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20 LIMIT 1;</span>
|
|
|
|
<span class="pl-c">// Map</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>: <span class="pl-c1">20</span>}).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = "jinzhu" AND age = 20;</span>
|
|
|
|
<span class="pl-c">// Slice of primary keys</span>
|
|
db.<span class="pl-c1">Where</span>([]<span class="pl-k">int64</span>{<span class="pl-c1">20</span>, <span class="pl-c1">21</span>, <span class="pl-c1">22</span>}).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE id IN (20, 21, 22);</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="query-with-not" class="anchor" href="#query-with-not" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query With Not</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Not</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;</span>
|
|
|
|
<span class="pl-c">// Not In</span>
|
|
db.<span class="pl-c1">Not</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, []<span class="pl-k">string</span>{<span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu 2<span class="pl-pds">"</span></span>}).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");</span>
|
|
|
|
<span class="pl-c">// Not In slice of primary keys</span>
|
|
db.<span class="pl-c1">Not</span>([]<span class="pl-k">int64</span>{<span class="pl-c1">1</span>,<span class="pl-c1">2</span>,<span class="pl-c1">3</span>}).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE id NOT IN (1,2,3);</span>
|
|
|
|
db.<span class="pl-c1">Not</span>([]<span class="pl-k">int64</span>{}).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users;</span>
|
|
|
|
<span class="pl-c">// Plain SQL</span>
|
|
db.<span class="pl-c1">Not</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE NOT(name = "jinzhu");</span>
|
|
|
|
<span class="pl-c">// Struct</span>
|
|
db.<span class="pl-c1">Not</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name <> "jinzhu";</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="query-with-inline-condition" class="anchor" href="#query-with-inline-condition" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query With Inline Condition</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Get by primary key</span>
|
|
db.<span class="pl-c1">First</span>(&user, <span class="pl-c1">23</span>)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE id = 23 LIMIT 1;</span>
|
|
|
|
<span class="pl-c">// Plain SQL</span>
|
|
db.<span class="pl-c1">Find</span>(&user, <span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = "jinzhu";</span>
|
|
|
|
db.<span class="pl-c1">Find</span>(&users, <span class="pl-s"><span class="pl-pds">"</span>name <> ? AND age > ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>, <span class="pl-c1">20</span>)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name <> "jinzhu" AND age > 20;</span>
|
|
|
|
<span class="pl-c">// Struct</span>
|
|
db.<span class="pl-c1">Find</span>(&users, <span class="pl-v">User</span>{Age: <span class="pl-c1">20</span>})
|
|
<span class="pl-c">//// SELECT * FROM users WHERE age = 20;</span>
|
|
|
|
<span class="pl-c">// Map</span>
|
|
db.<span class="pl-c1">Find</span>(&users, <span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>: <span class="pl-c1">20</span>})
|
|
<span class="pl-c">//// SELECT * FROM users WHERE age = 20;</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="query-with-or" class="anchor" href="#query-with-or" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query With Or</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>role = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>admin<span class="pl-pds">"</span></span>).<span class="pl-c1">Or</span>(<span class="pl-s"><span class="pl-pds">"</span>role = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>super_admin<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';</span>
|
|
|
|
<span class="pl-c">// Struct</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = 'jinzhu'<span class="pl-pds">"</span></span>).<span class="pl-c1">Or</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>jinzhu 2<span class="pl-pds">"</span></span>}).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';</span>
|
|
|
|
<span class="pl-c">// Map</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = 'jinzhu'<span class="pl-pds">"</span></span>).<span class="pl-c1">Or</span>(<span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>jinzhu 2<span class="pl-pds">"</span></span>}).<span class="pl-c1">Find</span>(&users)</pre></div>
|
|
|
|
<h3>
|
|
<a id="query-chains" class="anchor" href="#query-chains" aria-hidden="true"><span class="octicon octicon-link"></span></a>Query Chains</h3>
|
|
|
|
<p>Gorm has a chainable API, you could use it like this</p>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name <> ?<span class="pl-pds">"</span></span>,<span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>age >= ? and role <> ?<span class="pl-pds">"</span></span>,<span class="pl-c1">20</span>,<span class="pl-s"><span class="pl-pds">"</span>admin<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name <> 'jinzhu' AND age >= 20 AND role <> 'admin';</span>
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>role = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>admin<span class="pl-pds">"</span></span>).<span class="pl-c1">Or</span>(<span class="pl-s"><span class="pl-pds">"</span>role = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>super_admin<span class="pl-pds">"</span></span>).<span class="pl-c1">Not</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)</pre></div>
|
|
|
|
<h3>
|
|
<a id="preloading-eager-loading" class="anchor" href="#preloading-eager-loading" aria-hidden="true"><span class="octicon octicon-link"></span></a>Preloading (Eager loading)</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users;</span>
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE user_id IN (1,2,3,4);</span>
|
|
|
|
db.<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>state NOT IN (?)<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>cancelled<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users;</span>
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE user_id IN (1,2,3,4) AND state NOT IN ('cancelled');</span>
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>state = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>active<span class="pl-pds">"</span></span>).<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>state NOT IN (?)<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>cancelled<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE state = 'active';</span>
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE user_id IN (1,2) AND state NOT IN ('cancelled');</span>
|
|
|
|
db.<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders<span class="pl-pds">"</span></span>).<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Profile<span class="pl-pds">"</span></span>).<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Role<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users;</span>
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE user_id IN (1,2,3,4); // has many</span>
|
|
<span class="pl-c">//// SELECT * FROM profiles WHERE user_id IN (1,2,3,4); // has one</span>
|
|
<span class="pl-c">//// SELECT * FROM roles WHERE id IN (4,5,6); // belongs to</span></pre></div>
|
|
|
|
<h4>
|
|
<a id="nested-preloading" class="anchor" href="#nested-preloading" aria-hidden="true"><span class="octicon octicon-link"></span></a>Nested Preloading</h4>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders.OrderItems<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
db.<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>state = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>paid<span class="pl-pds">"</span></span>).<span class="pl-c1">Preload</span>(<span class="pl-s"><span class="pl-pds">"</span>Orders.OrderItems<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)</pre></div>
|
|
|
|
<h2>
|
|
<a id="update" class="anchor" href="#update" aria-hidden="true"><span class="octicon octicon-link"></span></a>Update</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Update an existing struct</span>
|
|
db.<span class="pl-c1">First</span>(&user)
|
|
user.<span class="pl-smi">Name</span> = <span class="pl-s"><span class="pl-pds">"</span>jinzhu 2<span class="pl-pds">"</span></span>
|
|
user.<span class="pl-smi">Age</span> = <span class="pl-c1">100</span>
|
|
db.<span class="pl-c1">Save</span>(&user)
|
|
<span class="pl-c">//// UPDATE users SET name='jinzhu 2', age=100, updated_at = '2013-11-17 21:34:10' WHERE id=111;</span>
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>active = ?<span class="pl-pds">"</span></span>, <span class="pl-c1">true</span>).<span class="pl-c1">Save</span>(&user)
|
|
<span class="pl-c">//// UPDATE users SET name='jinzhu 2', age=100, updated_at = '2013-11-17 21:34:10' WHERE id=111 AND active = true;</span>
|
|
|
|
<span class="pl-c">// Update an attribute if it is changed</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Update</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111;</span>
|
|
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>active = ?<span class="pl-pds">"</span></span>, <span class="pl-c1">true</span>).<span class="pl-c1">Update</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111 AND active = true;</span>
|
|
|
|
db.<span class="pl-c1">First</span>(&user, <span class="pl-c1">111</span>).<span class="pl-c1">Update</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM users LIMIT 1;</span>
|
|
<span class="pl-c">//// UPDATE users SET name='hello', updated_at = '2013-11-17 21:34:10' WHERE id=111;</span>
|
|
|
|
<span class="pl-c">// Update multiple attributes if they are changed</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Updates</span>(<span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>: <span class="pl-c1">18</span>, <span class="pl-s"><span class="pl-pds">"</span>actived<span class="pl-pds">"</span></span>: <span class="pl-c1">false</span>})
|
|
|
|
<span class="pl-c">// Update multiple attributes if they are changed (update with struct only works with none zero values)</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Updates</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>, <span class="pl-v">Age</span>: <span class="pl-c1">18</span>})
|
|
<span class="pl-c">//// UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="update-without-callbacks" class="anchor" href="#update-without-callbacks" aria-hidden="true"><span class="octicon octicon-link"></span></a>Update Without Callbacks</h3>
|
|
|
|
<p>By default, update will call BeforeUpdate, AfterUpdate callbacks, if you want to update w/o callbacks and w/o saving associations:</p>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">UpdateColumn</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// UPDATE users SET name='hello' WHERE id = 111;</span>
|
|
|
|
<span class="pl-c">// Update with struct only works with none zero values, or use map[string]interface{}</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">UpdateColumns</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>, <span class="pl-v">Age</span>: <span class="pl-c1">18</span>})
|
|
<span class="pl-c">//// UPDATE users SET name='hello', age=18 WHERE id = 111;</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="batch-updates" class="anchor" href="#batch-updates" aria-hidden="true"><span class="octicon octicon-link"></span></a>Batch Updates</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>id = ?<span class="pl-pds">"</span></span>, <span class="pl-c1">10</span>).<span class="pl-c1">Updates</span>(<span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>: <span class="pl-c1">18</span>})
|
|
<span class="pl-c">//// UPDATE users SET name='hello', age=18 WHERE id = 10;</span>
|
|
|
|
<span class="pl-c">// Update with struct only works with none zero values, or use map[string]interface{}</span>
|
|
db.<span class="pl-c1">Model</span>(User{}).<span class="pl-c1">Updates</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>, <span class="pl-v">Age</span>: <span class="pl-c1">18</span>})
|
|
<span class="pl-c">//// UPDATE users SET name='hello', age=18;</span>
|
|
|
|
<span class="pl-c">// Callbacks won't run when do batch updates</span>
|
|
|
|
<span class="pl-c">// Use `RowsAffected` to get the count of affected records</span>
|
|
db.<span class="pl-c1">Model</span>(User{}).<span class="pl-c1">Updates</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>hello<span class="pl-pds">"</span></span>, <span class="pl-v">Age</span>: <span class="pl-c1">18</span>}).<span class="pl-smi">RowsAffected</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="update-with-sql-expression" class="anchor" href="#update-with-sql-expression" aria-hidden="true"><span class="octicon octicon-link"></span></a>Update with SQL Expression</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>DB.<span class="pl-c1">Model</span>(&product).<span class="pl-c1">Update</span>(<span class="pl-s"><span class="pl-pds">"</span>price<span class="pl-pds">"</span></span>, gorm.<span class="pl-c1">Expr</span>(<span class="pl-s"><span class="pl-pds">"</span>price * ? + ?<span class="pl-pds">"</span></span>, <span class="pl-c1">2</span>, <span class="pl-c1">100</span>))
|
|
<span class="pl-c">//// UPDATE "products" SET "code" = 'L1212', "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';</span>
|
|
|
|
DB.<span class="pl-c1">Model</span>(&product).<span class="pl-c1">Updates</span>(<span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>price<span class="pl-pds">"</span></span>: gorm.<span class="pl-c1">Expr</span>(<span class="pl-s"><span class="pl-pds">"</span>price * ? + ?<span class="pl-pds">"</span></span>, <span class="pl-c1">2</span>, <span class="pl-c1">100</span>)})
|
|
<span class="pl-c">//// UPDATE "products" SET "code" = 'L1212', "price" = price * '2' + '100', "updated_at" = '2013-11-17 21:34:10' WHERE "id" = '2';</span>
|
|
|
|
DB.<span class="pl-c1">Model</span>(&product).<span class="pl-c1">UpdateColumn</span>(<span class="pl-s"><span class="pl-pds">"</span>quantity<span class="pl-pds">"</span></span>, gorm.<span class="pl-c1">Expr</span>(<span class="pl-s"><span class="pl-pds">"</span>quantity - ?<span class="pl-pds">"</span></span>, <span class="pl-c1">1</span>))
|
|
<span class="pl-c">//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2';</span>
|
|
|
|
DB.<span class="pl-c1">Model</span>(&product).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>quantity > 1<span class="pl-pds">"</span></span>).<span class="pl-c1">UpdateColumn</span>(<span class="pl-s"><span class="pl-pds">"</span>quantity<span class="pl-pds">"</span></span>, gorm.<span class="pl-c1">Expr</span>(<span class="pl-s"><span class="pl-pds">"</span>quantity - ?<span class="pl-pds">"</span></span>, <span class="pl-c1">1</span>))
|
|
<span class="pl-c">//// UPDATE "products" SET "quantity" = quantity - 1 WHERE "id" = '2' AND quantity > 1;</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="delete" class="anchor" href="#delete" aria-hidden="true"><span class="octicon octicon-link"></span></a>Delete</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Delete an existing record</span>
|
|
db.<span class="pl-c1">Delete</span>(&email)
|
|
<span class="pl-c">//// DELETE from emails where id=10;</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="batch-delete" class="anchor" href="#batch-delete" aria-hidden="true"><span class="octicon octicon-link"></span></a>Batch Delete</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>email LIKE ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-ii">%</span>jinzhu<span class="pl-ii">%</span><span class="pl-pds">"</span></span>).<span class="pl-c1">Delete</span>(Email{})
|
|
<span class="pl-c">//// DELETE from emails where email LIKE "%jinhu%";</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="soft-delete" class="anchor" href="#soft-delete" aria-hidden="true"><span class="octicon octicon-link"></span></a>Soft Delete</h3>
|
|
|
|
<p>If struct has <code>DeletedAt</code> field, it will get soft delete ability automatically!
|
|
Then it won't be deleted from database permanently when call <code>Delete</code>.</p>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Delete</span>(&user)
|
|
<span class="pl-c">//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE id = 111;</span>
|
|
|
|
<span class="pl-c">// Batch Delete</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>age = ?<span class="pl-pds">"</span></span>, <span class="pl-c1">20</span>).<span class="pl-c1">Delete</span>(&User{})
|
|
<span class="pl-c">//// UPDATE users SET deleted_at="2013-10-29 10:23" WHERE age = 20;</span>
|
|
|
|
<span class="pl-c">// Soft deleted records will be ignored when query them</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>age = 20<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE age = 20 AND (deleted_at IS NULL OR deleted_at <= '0001-01-02');</span>
|
|
|
|
<span class="pl-c">// Find soft deleted records with Unscoped</span>
|
|
db.<span class="pl-c1">Unscoped</span>().<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>age = 20<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE age = 20;</span>
|
|
|
|
<span class="pl-c">// Delete record permanently with Unscoped</span>
|
|
db.<span class="pl-c1">Unscoped</span>().<span class="pl-c1">Delete</span>(&order)
|
|
<span class="pl-c">//// DELETE FROM orders WHERE id=10;</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="associations" class="anchor" href="#associations" aria-hidden="true"><span class="octicon octicon-link"></span></a>Associations</h2>
|
|
|
|
<h3>
|
|
<a id="has-one" class="anchor" href="#has-one" aria-hidden="true"><span class="octicon octicon-link"></span></a>Has One</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// User has one address</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Related</span>(&address)
|
|
<span class="pl-c">//// SELECT * FROM addresses WHERE id = 123; // 123 is user's foreign key AddressId</span>
|
|
|
|
<span class="pl-c">// Specify the foreign key</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Related</span>(&address1, <span class="pl-s"><span class="pl-pds">"</span>BillingAddressId<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM addresses WHERE id = 123; // 123 is user's foreign key BillingAddressId</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="belongs-to" class="anchor" href="#belongs-to" aria-hidden="true"><span class="octicon octicon-link"></span></a>Belongs To</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Email belongs to user</span>
|
|
db.<span class="pl-c1">Model</span>(&email).<span class="pl-c1">Related</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE id = 111; // 111 is email's foreign key UserId</span>
|
|
|
|
<span class="pl-c">// Specify the foreign key</span>
|
|
db.<span class="pl-c1">Model</span>(&email).<span class="pl-c1">Related</span>(&user, <span class="pl-s"><span class="pl-pds">"</span>ProfileId<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE id = 111; // 111 is email's foreign key ProfileId</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="has-many" class="anchor" href="#has-many" aria-hidden="true"><span class="octicon octicon-link"></span></a>Has Many</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// User has many emails</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Related</span>(&emails)
|
|
<span class="pl-c">//// SELECT * FROM emails WHERE user_id = 111;</span>
|
|
<span class="pl-c">// user_id is the foreign key, 111 is user's primary key's value</span>
|
|
|
|
<span class="pl-c">// Specify the foreign key</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Related</span>(&emails, <span class="pl-s"><span class="pl-pds">"</span>ProfileId<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM emails WHERE profile_id = 111;</span>
|
|
<span class="pl-c">// profile_id is the foreign key, 111 is user's primary key's value</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="many-to-many" class="anchor" href="#many-to-many" aria-hidden="true"><span class="octicon octicon-link"></span></a>Many To Many</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// User has many languages and belongs to many languages</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Related</span>(&languages, <span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM "languages" INNER JOIN "user_languages" ON "user_languages"."language_id" = "languages"."id" WHERE "user_languages"."user_id" = 111</span>
|
|
<span class="pl-c">// `Languages` is user's column name, this column's tag defined join table like this `gorm:"many2many:user_languages;"`</span></pre></div>
|
|
|
|
<p>There is also a mode used to handle many to many relations easily</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Query</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&languages)
|
|
<span class="pl-c">// same as `db.Model(&user).Related(&languages, "Languages")`</span>
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>ZH<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&languageZH)
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>EN<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&languageEN)
|
|
|
|
<span class="pl-c">// Append</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Append</span>([]<span class="pl-v">Language</span>{languageZH, languageEN})
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Append</span>([]<span class="pl-v">Language</span>{{Name: <span class="pl-s"><span class="pl-pds">"</span>DE<span class="pl-pds">"</span></span>}})
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Append</span>(Language{Name: <span class="pl-s"><span class="pl-pds">"</span>DE<span class="pl-pds">"</span></span>})
|
|
|
|
<span class="pl-c">// Delete</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Delete</span>([]<span class="pl-v">Language</span>{languageZH, languageEN})
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Delete</span>(languageZH, languageEN)
|
|
|
|
<span class="pl-c">// Replace</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Replace</span>([]<span class="pl-v">Language</span>{languageZH, languageEN})
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Replace</span>(Language{Name: <span class="pl-s"><span class="pl-pds">"</span>DE<span class="pl-pds">"</span></span>}, languageEN)
|
|
|
|
<span class="pl-c">// Count</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Count</span>()
|
|
<span class="pl-c">// Return the count of languages the user has</span>
|
|
|
|
<span class="pl-c">// Clear</span>
|
|
db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Association</span>(<span class="pl-s"><span class="pl-pds">"</span>Languages<span class="pl-pds">"</span></span>).<span class="pl-c1">Clear</span>()
|
|
<span class="pl-c">// Remove all relations between the user and languages</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="polymorphism" class="anchor" href="#polymorphism" aria-hidden="true"><span class="octicon octicon-link"></span></a>Polymorphism</h3>
|
|
|
|
<p>Supports polymorphic has-many and has-one associations.</p>
|
|
|
|
<div class="highlight highlight-go"><pre> <span class="pl-k">type</span> <span class="pl-v">Cat</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">Id</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span>
|
|
<span class="pl-v">Toy</span> <span class="pl-v">Toy</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"polymorphic:Owner;"<span class="pl-pds">`</span></span>
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">Dog</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">Id</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span>
|
|
<span class="pl-v">Toy</span> <span class="pl-v">Toy</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"polymorphic:Owner;"<span class="pl-pds">`</span></span>
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">Toy</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">Id</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span>
|
|
<span class="pl-v">OwnerId</span> <span class="pl-k">int</span>
|
|
<span class="pl-v">OwnerType</span> <span class="pl-k">string</span>
|
|
}</pre></div>
|
|
|
|
<p>Note: polymorphic belongs-to and many-to-many are explicitly NOT supported, and will throw errors.</p>
|
|
|
|
<h2>
|
|
<a id="advanced-usage" class="anchor" href="#advanced-usage" aria-hidden="true"><span class="octicon octicon-link"></span></a>Advanced Usage</h2>
|
|
|
|
<h2>
|
|
<a id="firstorinit" class="anchor" href="#firstorinit" aria-hidden="true"><span class="octicon octicon-link"></span></a>FirstOrInit</h2>
|
|
|
|
<p>Get the first matched record, or initialize a record with search conditions.</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Unfound</span>
|
|
db.<span class="pl-c1">FirstOrInit</span>(&user, <span class="pl-v">User</span>{Name: <span class="pl-s"><span class="pl-pds">"</span>non_existing<span class="pl-pds">"</span></span>})
|
|
<span class="pl-c">//// user -> User{Name: "non_existing"}</span>
|
|
|
|
<span class="pl-c">// Found</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>Jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">FirstOrInit</span>(&user)
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}</span>
|
|
db.<span class="pl-c1">FirstOrInit</span>(&user, <span class="pl-k">map</span>[<span class="pl-k">string</span>]<span class="pl-k">interface</span>{}{<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>})
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="attrs" class="anchor" href="#attrs" aria-hidden="true"><span class="octicon octicon-link"></span></a>Attrs</h3>
|
|
|
|
<p>Ignore some values when searching, but use them to initialize the struct if record is not found.</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Unfound</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>non_existing<span class="pl-pds">"</span></span>}).<span class="pl-c1">Attrs</span>(User{Age: <span class="pl-c1">20</span>}).<span class="pl-c1">FirstOrInit</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM USERS WHERE name = 'non_existing';</span>
|
|
<span class="pl-c">//// user -> User{Name: "non_existing", Age: 20}</span>
|
|
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>noexisting_user<span class="pl-pds">"</span></span>}).<span class="pl-c1">Attrs</span>(<span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>, <span class="pl-c1">20</span>).<span class="pl-c1">FirstOrInit</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM USERS WHERE name = 'non_existing';</span>
|
|
<span class="pl-c">//// user -> User{Name: "non_existing", Age: 20}</span>
|
|
|
|
<span class="pl-c">// Found</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>Jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">Attrs</span>(User{Age: <span class="pl-c1">30</span>}).<span class="pl-c1">FirstOrInit</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM USERS WHERE name = jinzhu';</span>
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "Jinzhu", Age: 20}</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="assign" class="anchor" href="#assign" aria-hidden="true"><span class="octicon octicon-link"></span></a>Assign</h3>
|
|
|
|
<p>Ignore some values when searching, but assign it to the result regardless it is found or not.</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Unfound</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>non_existing<span class="pl-pds">"</span></span>}).<span class="pl-c1">Assign</span>(User{Age: <span class="pl-c1">20</span>}).<span class="pl-c1">FirstOrInit</span>(&user)
|
|
<span class="pl-c">//// user -> User{Name: "non_existing", Age: 20}</span>
|
|
|
|
<span class="pl-c">// Found</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>Jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">Assign</span>(User{Age: <span class="pl-c1">30</span>}).<span class="pl-c1">FirstOrInit</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM USERS WHERE name = jinzhu';</span>
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "Jinzhu", Age: 30}</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="firstorcreate" class="anchor" href="#firstorcreate" aria-hidden="true"><span class="octicon octicon-link"></span></a>FirstOrCreate</h2>
|
|
|
|
<p>Get the first matched record, or create with search conditions.</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Unfound</span>
|
|
db.<span class="pl-c1">FirstOrCreate</span>(&user, <span class="pl-v">User</span>{Name: <span class="pl-s"><span class="pl-pds">"</span>non_existing<span class="pl-pds">"</span></span>})
|
|
<span class="pl-c">//// INSERT INTO "users" (name) VALUES ("non_existing");</span>
|
|
<span class="pl-c">//// user -> User{Id: 112, Name: "non_existing"}</span>
|
|
|
|
<span class="pl-c">// Found</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>Jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">FirstOrCreate</span>(&user)
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "Jinzhu"}</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="attrs-1" class="anchor" href="#attrs-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Attrs</h3>
|
|
|
|
<p>Ignore some values when searching, but use them to create the struct if record is not found. like <code>FirstOrInit</code></p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Unfound</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>non_existing<span class="pl-pds">"</span></span>}).<span class="pl-c1">Attrs</span>(User{Age: <span class="pl-c1">20</span>}).<span class="pl-c1">FirstOrCreate</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'non_existing';</span>
|
|
<span class="pl-c">//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);</span>
|
|
<span class="pl-c">//// user -> User{Id: 112, Name: "non_existing", Age: 20}</span>
|
|
|
|
<span class="pl-c">// Found</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">Attrs</span>(User{Age: <span class="pl-c1">30</span>}).<span class="pl-c1">FirstOrCreate</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'jinzhu';</span>
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "jinzhu", Age: 20}</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="assign-1" class="anchor" href="#assign-1" aria-hidden="true"><span class="octicon octicon-link"></span></a>Assign</h3>
|
|
|
|
<p>Ignore some values when searching, but assign it to the record regardless it is found or not, then save back to database. like <code>FirstOrInit</code></p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Unfound</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>non_existing<span class="pl-pds">"</span></span>}).<span class="pl-c1">Assign</span>(User{Age: <span class="pl-c1">20</span>}).<span class="pl-c1">FirstOrCreate</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'non_existing';</span>
|
|
<span class="pl-c">//// INSERT INTO "users" (name, age) VALUES ("non_existing", 20);</span>
|
|
<span class="pl-c">//// user -> User{Id: 112, Name: "non_existing", Age: 20}</span>
|
|
|
|
<span class="pl-c">// Found</span>
|
|
db.<span class="pl-c1">Where</span>(User{Name: <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>}).<span class="pl-c1">Assign</span>(User{Age: <span class="pl-c1">30</span>}).<span class="pl-c1">FirstOrCreate</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE name = 'jinzhu';</span>
|
|
<span class="pl-c">//// UPDATE users SET age=30 WHERE id = 111;</span>
|
|
<span class="pl-c">//// user -> User{Id: 111, Name: "jinzhu", Age: 30}</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="select" class="anchor" href="#select" aria-hidden="true"><span class="octicon octicon-link"></span></a>Select</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>name, age<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT name, age FROM users;</span>
|
|
|
|
db.<span class="pl-c1">Select</span>([]<span class="pl-k">string</span>{<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>}).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT name, age FROM users;</span>
|
|
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>COALESCE(age,?)<span class="pl-pds">"</span></span>, <span class="pl-c1">42</span>).<span class="pl-c1">Rows</span>()
|
|
<span class="pl-c">//// SELECT COALESCE(age,'42') FROM users;</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="order" class="anchor" href="#order" aria-hidden="true"><span class="octicon octicon-link"></span></a>Order</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Order</span>(<span class="pl-s"><span class="pl-pds">"</span>age desc, name<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users ORDER BY age desc, name;</span>
|
|
|
|
<span class="pl-c">// Multiple orders</span>
|
|
db.<span class="pl-c1">Order</span>(<span class="pl-s"><span class="pl-pds">"</span>age desc<span class="pl-pds">"</span></span>).<span class="pl-c1">Order</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users ORDER BY age desc, name;</span>
|
|
|
|
<span class="pl-c">// ReOrder</span>
|
|
db.<span class="pl-c1">Order</span>(<span class="pl-s"><span class="pl-pds">"</span>age desc<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users1).<span class="pl-c1">Order</span>(<span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>, <span class="pl-c1">true</span>).<span class="pl-c1">Find</span>(&users2)
|
|
<span class="pl-c">//// SELECT * FROM users ORDER BY age desc; (users1)</span>
|
|
<span class="pl-c">//// SELECT * FROM users ORDER BY age; (users2)</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="limit" class="anchor" href="#limit" aria-hidden="true"><span class="octicon octicon-link"></span></a>Limit</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Limit</span>(<span class="pl-c1">3</span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users LIMIT 3;</span>
|
|
|
|
<span class="pl-c">// Cancel limit condition with -1</span>
|
|
db.<span class="pl-c1">Limit</span>(<span class="pl-c1">10</span>).<span class="pl-c1">Find</span>(&users1).<span class="pl-c1">Limit</span>(-<span class="pl-c1">1</span>).<span class="pl-c1">Find</span>(&users2)
|
|
<span class="pl-c">//// SELECT * FROM users LIMIT 10; (users1)</span>
|
|
<span class="pl-c">//// SELECT * FROM users; (users2)</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="offset" class="anchor" href="#offset" aria-hidden="true"><span class="octicon octicon-link"></span></a>Offset</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Offset</span>(<span class="pl-c1">3</span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">//// SELECT * FROM users OFFSET 3;</span>
|
|
|
|
<span class="pl-c">// Cancel offset condition with -1</span>
|
|
db.<span class="pl-c1">Offset</span>(<span class="pl-c1">10</span>).<span class="pl-c1">Find</span>(&users1).<span class="pl-c1">Offset</span>(-<span class="pl-c1">1</span>).<span class="pl-c1">Find</span>(&users2)
|
|
<span class="pl-c">//// SELECT * FROM users OFFSET 10; (users1)</span>
|
|
<span class="pl-c">//// SELECT * FROM users; (users2)</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="count" class="anchor" href="#count" aria-hidden="true"><span class="octicon octicon-link"></span></a>Count</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Or</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu 2<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users).<span class="pl-c1">Count</span>(&count)
|
|
<span class="pl-c">//// SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)</span>
|
|
<span class="pl-c">//// SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count)</span>
|
|
|
|
db.<span class="pl-c1">Model</span>(User{}).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Count</span>(&count)
|
|
<span class="pl-c">//// SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)</span>
|
|
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>deleted_users<span class="pl-pds">"</span></span>).<span class="pl-c1">Count</span>(&count)
|
|
<span class="pl-c">//// SELECT count(*) FROM deleted_users;</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="pluck" class="anchor" href="#pluck" aria-hidden="true"><span class="octicon octicon-link"></span></a>Pluck</h2>
|
|
|
|
<p>Get selected attributes as map</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">var</span> <span class="pl-smi">ages</span> []<span class="pl-k">int64</span>
|
|
db.<span class="pl-c1">Find</span>(&users).<span class="pl-c1">Pluck</span>(<span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>, &ages)
|
|
|
|
<span class="pl-k">var</span> <span class="pl-smi">names</span> []<span class="pl-k">string</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">Pluck</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, &names)
|
|
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>deleted_users<span class="pl-pds">"</span></span>).<span class="pl-c1">Pluck</span>(<span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, &names)
|
|
|
|
<span class="pl-c">// Requesting more than one column? Do it like this:</span>
|
|
db.<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>name, age<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users)</pre></div>
|
|
|
|
<h2>
|
|
<a id="raw-sql" class="anchor" href="#raw-sql" aria-hidden="true"><span class="octicon octicon-link"></span></a>Raw SQL</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Exec</span>(<span class="pl-s"><span class="pl-pds">"</span>DROP TABLE users;<span class="pl-pds">"</span></span>)
|
|
db.<span class="pl-c1">Exec</span>(<span class="pl-s"><span class="pl-pds">"</span>UPDATE orders SET shipped_at=? WHERE id IN (?)<span class="pl-pds">"</span></span>, time.<span class="pl-smi">Now</span>, []<span class="pl-k">int64</span>{<span class="pl-c1">11</span>,<span class="pl-c1">22</span>,<span class="pl-c1">33</span>})</pre></div>
|
|
|
|
<h2>
|
|
<a id="row--rows" class="anchor" href="#row--rows" aria-hidden="true"><span class="octicon octicon-link"></span></a>Row & Rows</h2>
|
|
|
|
<p>It is even possible to get query result as <code>*sql.Row</code> or <code>*sql.Rows</code></p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-smi">row</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>name, age<span class="pl-pds">"</span></span>).<span class="pl-c1">Row</span>() <span class="pl-c">// (*sql.Row)</span>
|
|
row.<span class="pl-c1">Scan</span>(&name, &age)
|
|
|
|
<span class="pl-smi">rows</span>, <span class="pl-smi">err</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Model</span>(User{}).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>name, age, email<span class="pl-pds">"</span></span>).<span class="pl-c1">Rows</span>() <span class="pl-c">// (*sql.Rows, error)</span>
|
|
<span class="pl-k">defer</span> rows.<span class="pl-c1">Close</span>()
|
|
<span class="pl-k">for</span> rows.<span class="pl-c1">Next</span>() {
|
|
...
|
|
rows.<span class="pl-c1">Scan</span>(&name, &age, &email)
|
|
...
|
|
}
|
|
|
|
<span class="pl-c">// Raw SQL</span>
|
|
<span class="pl-smi">rows</span>, <span class="pl-smi">err</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Raw</span>(<span class="pl-s"><span class="pl-pds">"</span>select name, age, email from users where name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Rows</span>() <span class="pl-c">// (*sql.Rows, error)</span>
|
|
<span class="pl-k">defer</span> rows.<span class="pl-c1">Close</span>()
|
|
<span class="pl-k">for</span> rows.<span class="pl-c1">Next</span>() {
|
|
...
|
|
rows.<span class="pl-c1">Scan</span>(&name, &age, &email)
|
|
...
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="scan" class="anchor" href="#scan" aria-hidden="true"><span class="octicon octicon-link"></span></a>Scan</h2>
|
|
|
|
<p>Scan results into another struct.</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Result</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span>
|
|
<span class="pl-v">Age</span> <span class="pl-k">int</span>
|
|
}
|
|
|
|
<span class="pl-k">var</span> <span class="pl-smi">result</span> <span class="pl-v">Result</span>
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>name, age<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-c1">3</span>).<span class="pl-c1">Scan</span>(&result)
|
|
|
|
<span class="pl-c">// Raw SQL</span>
|
|
db.<span class="pl-c1">Raw</span>(<span class="pl-s"><span class="pl-pds">"</span>SELECT name, age FROM users WHERE name = ?<span class="pl-pds">"</span></span>, <span class="pl-c1">3</span>).<span class="pl-c1">Scan</span>(&result)</pre></div>
|
|
|
|
<h2>
|
|
<a id="group--having" class="anchor" href="#group--having" aria-hidden="true"><span class="octicon octicon-link"></span></a>Group & Having</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-smi">rows</span>, <span class="pl-smi">err</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>orders<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>date(created_at) as date, sum(amount) as total<span class="pl-pds">"</span></span>).<span class="pl-c1">Group</span>(<span class="pl-s"><span class="pl-pds">"</span>date(created_at)<span class="pl-pds">"</span></span>).<span class="pl-c1">Rows</span>()
|
|
<span class="pl-k">for</span> rows.<span class="pl-c1">Next</span>() {
|
|
...
|
|
}
|
|
|
|
<span class="pl-smi">rows</span>, <span class="pl-smi">err</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>orders<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>date(created_at) as date, sum(amount) as total<span class="pl-pds">"</span></span>).<span class="pl-c1">Group</span>(<span class="pl-s"><span class="pl-pds">"</span>date(created_at)<span class="pl-pds">"</span></span>).<span class="pl-c1">Having</span>(<span class="pl-s"><span class="pl-pds">"</span>sum(amount) > ?<span class="pl-pds">"</span></span>, <span class="pl-c1">100</span>).<span class="pl-c1">Rows</span>()
|
|
<span class="pl-k">for</span> rows.<span class="pl-c1">Next</span>() {
|
|
...
|
|
}
|
|
|
|
<span class="pl-k">type</span> <span class="pl-v">Result</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">Date</span> time.<span class="pl-smi">Time</span>
|
|
<span class="pl-v">Total</span> <span class="pl-k">int64</span>
|
|
}
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>orders<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>date(created_at) as date, sum(amount) as total<span class="pl-pds">"</span></span>).<span class="pl-c1">Group</span>(<span class="pl-s"><span class="pl-pds">"</span>date(created_at)<span class="pl-pds">"</span></span>).<span class="pl-c1">Having</span>(<span class="pl-s"><span class="pl-pds">"</span>sum(amount) > ?<span class="pl-pds">"</span></span>, <span class="pl-c1">100</span>).<span class="pl-c1">Scan</span>(&results)</pre></div>
|
|
|
|
<h2>
|
|
<a id="joins" class="anchor" href="#joins" aria-hidden="true"><span class="octicon octicon-link"></span></a>Joins</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-smi">rows</span>, <span class="pl-smi">err</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>users.name, emails.email<span class="pl-pds">"</span></span>).<span class="pl-c1">Joins</span>(<span class="pl-s"><span class="pl-pds">"</span>left join emails on emails.user_id = users.id<span class="pl-pds">"</span></span>).<span class="pl-c1">Rows</span>()
|
|
<span class="pl-k">for</span> rows.<span class="pl-c1">Next</span>() {
|
|
...
|
|
}
|
|
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>).<span class="pl-c1">Select</span>(<span class="pl-s"><span class="pl-pds">"</span>users.name, emails.email<span class="pl-pds">"</span></span>).<span class="pl-c1">Joins</span>(<span class="pl-s"><span class="pl-pds">"</span>left join emails on emails.user_id = users.id<span class="pl-pds">"</span></span>).<span class="pl-c1">Scan</span>(&results)
|
|
|
|
<span class="pl-c">// find a user by email address</span>
|
|
db.<span class="pl-c1">Joins</span>(<span class="pl-s"><span class="pl-pds">"</span>inner join emails on emails.user_id = users.id<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>emails.email = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>x@example.org<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&user)
|
|
|
|
<span class="pl-c">// find all email addresses for a user</span>
|
|
db.<span class="pl-c1">Joins</span>(<span class="pl-s"><span class="pl-pds">"</span>left join users on users.id = emails.user_id<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>users.name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&emails)</pre></div>
|
|
|
|
<h2>
|
|
<a id="transactions" class="anchor" href="#transactions" aria-hidden="true"><span class="octicon octicon-link"></span></a>Transactions</h2>
|
|
|
|
<p>To perform a set of operations within a transaction, the general flow is as below.
|
|
The database handle returned from <code>db.Begin()</code> should be used for all operations within the transaction.
|
|
(Note that all individual save and delete operations are run in a transaction by default.)</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// begin</span>
|
|
<span class="pl-smi">tx</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Begin</span>()
|
|
|
|
<span class="pl-c">// do some database operations (use 'tx' from this point, not 'db')</span>
|
|
tx.<span class="pl-c1">Create</span>(...)
|
|
...
|
|
|
|
<span class="pl-c">// rollback in case of error</span>
|
|
tx.<span class="pl-c1">Rollback</span>()
|
|
|
|
<span class="pl-c">// Or commit if all is ok</span>
|
|
tx.<span class="pl-c1">Commit</span>()</pre></div>
|
|
|
|
<h3>
|
|
<a id="a-specific-example" class="anchor" href="#a-specific-example" aria-hidden="true"><span class="octicon octicon-link"></span></a>A Specific Example</h3>
|
|
|
|
<pre><code>func CreateAnimals(db *gorm.DB) err {
|
|
tx := db.Begin()
|
|
// Note the use of tx as the database handle once you are within a transaction
|
|
|
|
if err := tx.Create(&Animal{Name: "Giraffe"}).Error; err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
|
|
if err := tx.Create(&Animal{Name: "Lion"}).Error; err != nil {
|
|
tx.Rollback()
|
|
return err
|
|
}
|
|
|
|
tx.Commit()
|
|
return nil
|
|
}
|
|
</code></pre>
|
|
|
|
<h2>
|
|
<a id="scopes" class="anchor" href="#scopes" aria-hidden="true"><span class="octicon octicon-link"></span></a>Scopes</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">func</span> <span class="pl-en">AmountGreaterThan1000</span>(<span class="pl-v">db</span> *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span>) *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span> {
|
|
<span class="pl-k">return</span> db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>amount > ?<span class="pl-pds">"</span></span>, <span class="pl-c1">1000</span>)
|
|
}
|
|
|
|
<span class="pl-k">func</span> <span class="pl-en">PaidWithCreditCard</span>(<span class="pl-v">db</span> *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span>) *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span> {
|
|
<span class="pl-k">return</span> db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>pay_mode_sign = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>)
|
|
}
|
|
|
|
<span class="pl-k">func</span> <span class="pl-en">PaidWithCod</span>(<span class="pl-v">db</span> *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span>) *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span> {
|
|
<span class="pl-k">return</span> db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>pay_mode_sign = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>C<span class="pl-pds">"</span></span>)
|
|
}
|
|
|
|
<span class="pl-k">func</span> <span class="pl-en">OrderStatus</span>(<span class="pl-v">status</span> []<span class="pl-v">string</span>) <span class="pl-v">func</span> (db *gorm.DB) *gorm.DB {
|
|
<span class="pl-k">return</span> <span class="pl-c1">func</span> (db *gorm.<span class="pl-smi">DB</span>) *gorm.<span class="pl-smi">DB</span> {
|
|
<span class="pl-k">return</span> db.<span class="pl-c1">Scopes</span>(AmountGreaterThan1000).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>status in (?)<span class="pl-pds">"</span></span>, status)
|
|
}
|
|
}
|
|
|
|
db.<span class="pl-c1">Scopes</span>(AmountGreaterThan1000, <span class="pl-v">PaidWithCreditCard</span>).<span class="pl-c1">Find</span>(&orders)
|
|
<span class="pl-c">// Find all credit card orders and amount greater than 1000</span>
|
|
|
|
db.<span class="pl-c1">Scopes</span>(AmountGreaterThan1000, <span class="pl-v">PaidWithCod</span>).<span class="pl-c1">Find</span>(&orders)
|
|
<span class="pl-c">// Find all COD orders and amount greater than 1000</span>
|
|
|
|
db.<span class="pl-c1">Scopes</span>(<span class="pl-c1">OrderStatus</span>([]<span class="pl-k">string</span>{<span class="pl-s"><span class="pl-pds">"</span>paid<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>shipped<span class="pl-pds">"</span></span>})).<span class="pl-c1">Find</span>(&orders)
|
|
<span class="pl-c">// Find all paid, shipped orders</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="callbacks" class="anchor" href="#callbacks" aria-hidden="true"><span class="octicon octicon-link"></span></a>Callbacks</h2>
|
|
|
|
<p>Callbacks are methods defined on the pointer of struct.
|
|
If any callback returns an error, gorm will stop future operations and rollback all changes.</p>
|
|
|
|
<p>Here is the list of all available callbacks:
|
|
(listed in the same order in which they will get called during the respective operations)</p>
|
|
|
|
<h3>
|
|
<a id="creating-an-object" class="anchor" href="#creating-an-object" aria-hidden="true"><span class="octicon octicon-link"></span></a>Creating An Object</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>BeforeSave
|
|
BeforeCreate
|
|
<span class="pl-c">// save before associations</span>
|
|
<span class="pl-c">// save self</span>
|
|
<span class="pl-c">// save after associations</span>
|
|
AfterCreate
|
|
AfterSave</pre></div>
|
|
|
|
<h3>
|
|
<a id="updating-an-object" class="anchor" href="#updating-an-object" aria-hidden="true"><span class="octicon octicon-link"></span></a>Updating An Object</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>BeforeSave
|
|
BeforeUpdate
|
|
<span class="pl-c">// save before associations</span>
|
|
<span class="pl-c">// save self</span>
|
|
<span class="pl-c">// save after associations</span>
|
|
AfterUpdate
|
|
AfterSave</pre></div>
|
|
|
|
<h3>
|
|
<a id="destroying-an-object" class="anchor" href="#destroying-an-object" aria-hidden="true"><span class="octicon octicon-link"></span></a>Destroying An Object</h3>
|
|
|
|
<div class="highlight highlight-go"><pre>BeforeDelete
|
|
<span class="pl-c">// delete self</span>
|
|
AfterDelete</pre></div>
|
|
|
|
<h3>
|
|
<a id="after-find" class="anchor" href="#after-find" aria-hidden="true"><span class="octicon octicon-link"></span></a>After Find</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// load data from database</span>
|
|
AfterFind</pre></div>
|
|
|
|
<h3>
|
|
<a id="example" class="anchor" href="#example" aria-hidden="true"><span class="octicon octicon-link"></span></a>Example</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">func</span> <span class="pl-en">(<span class="pl-v">u</span> *<span class="pl-v">User</span>) <span class="pl-en">BeforeUpdate</span></span>() (<span class="pl-v">err</span> <span class="pl-v">error</span>) {
|
|
<span class="pl-k">if</span> u.<span class="pl-c1">readonly</span>() {
|
|
err = errors.<span class="pl-c1">New</span>(<span class="pl-s"><span class="pl-pds">"</span>read only user<span class="pl-pds">"</span></span>)
|
|
}
|
|
<span class="pl-k">return</span>
|
|
}
|
|
|
|
<span class="pl-c">// Rollback the insertion if user's id greater than 1000</span>
|
|
<span class="pl-k">func</span> <span class="pl-en">(<span class="pl-v">u</span> *<span class="pl-v">User</span>) <span class="pl-en">AfterCreate</span></span>() (<span class="pl-v">err</span> <span class="pl-v">error</span>) {
|
|
<span class="pl-k">if</span> (u.<span class="pl-smi">Id</span> > <span class="pl-c1">1000</span>) {
|
|
err = errors.<span class="pl-c1">New</span>(<span class="pl-s"><span class="pl-pds">"</span>user id is already greater than 1000<span class="pl-pds">"</span></span>)
|
|
}
|
|
<span class="pl-k">return</span>
|
|
}</pre></div>
|
|
|
|
<p>As you know, save/delete operations in gorm are running in a transaction,
|
|
This is means if changes made in the transaction is not visiable unless it is commited,
|
|
So if you want to use those changes in your callbacks, you need to run SQL in same transaction.
|
|
Fortunately, gorm support pass transaction to callbacks as you needed, you could do it like this:</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">func</span> <span class="pl-en">(<span class="pl-v">u</span> *<span class="pl-v">User</span>) <span class="pl-en">AfterCreate</span></span>(<span class="pl-v">tx</span> *<span class="pl-v">gorm</span>.<span class="pl-v">DB</span>) (<span class="pl-v">err</span> <span class="pl-v">error</span>) {
|
|
tx.<span class="pl-c1">Model</span>(u).<span class="pl-c1">Update</span>(<span class="pl-s"><span class="pl-pds">"</span>role<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>admin<span class="pl-pds">"</span></span>)
|
|
<span class="pl-k">return</span>
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="specifying-the-table-name" class="anchor" href="#specifying-the-table-name" aria-hidden="true"><span class="octicon octicon-link"></span></a>Specifying The Table Name</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Create `deleted_users` table with struct User's definition</span>
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>deleted_users<span class="pl-pds">"</span></span>).<span class="pl-c1">CreateTable</span>(&User{})
|
|
|
|
<span class="pl-k">var</span> <span class="pl-smi">deleted_users</span> []<span class="pl-v">User</span>
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>deleted_users<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&deleted_users)
|
|
<span class="pl-c">//// SELECT * FROM deleted_users;</span>
|
|
|
|
db.<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>deleted_users<span class="pl-pds">"</span></span>).<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">Delete</span>()
|
|
<span class="pl-c">//// DELETE FROM deleted_users WHERE name = 'jinzhu';</span></pre></div>
|
|
|
|
<h3>
|
|
<a id="specifying-the-table-name-for-a-struct-permanently-with-tablename" class="anchor" href="#specifying-the-table-name-for-a-struct-permanently-with-tablename" aria-hidden="true"><span class="octicon octicon-link"></span></a>Specifying The Table Name For A Struct Permanently with TableName</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Cart</span> <span class="pl-k">struct</span> {
|
|
}
|
|
|
|
<span class="pl-k">func</span> <span class="pl-en">(<span class="pl-v">c</span> <span class="pl-v">Cart</span>) <span class="pl-en">TableName</span></span>() <span class="pl-v">string</span> {
|
|
<span class="pl-k">return</span> <span class="pl-s"><span class="pl-pds">"</span>shopping_cart<span class="pl-pds">"</span></span>
|
|
}
|
|
|
|
<span class="pl-k">func</span> <span class="pl-en">(<span class="pl-v">u</span> <span class="pl-v">User</span>) <span class="pl-en">TableName</span></span>() <span class="pl-v">string</span> {
|
|
<span class="pl-k">if</span> u.<span class="pl-smi">Role</span> == <span class="pl-s"><span class="pl-pds">"</span>admin<span class="pl-pds">"</span></span> {
|
|
<span class="pl-k">return</span> <span class="pl-s"><span class="pl-pds">"</span>admin_users<span class="pl-pds">"</span></span>
|
|
} <span class="pl-k">else</span> {
|
|
<span class="pl-k">return</span> <span class="pl-s"><span class="pl-pds">"</span>users<span class="pl-pds">"</span></span>
|
|
}
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="error-handling" class="anchor" href="#error-handling" aria-hidden="true"><span class="octicon octicon-link"></span></a>Error Handling</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-smi">query</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&user)
|
|
<span class="pl-smi">query</span> <span class="pl-k">:=</span> db.<span class="pl-c1">First</span>(&user).<span class="pl-c1">Limit</span>(<span class="pl-c1">10</span>).<span class="pl-c1">Find</span>(&users)
|
|
<span class="pl-c">// query.Error will return the last happened error</span>
|
|
|
|
<span class="pl-c">// So you could do error handing in your application like this:</span>
|
|
<span class="pl-k">if</span> <span class="pl-smi">err</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&user).<span class="pl-smi">Error</span>; err != <span class="pl-c1">nil</span> {
|
|
<span class="pl-c">// error handling...</span>
|
|
}
|
|
|
|
<span class="pl-c">// RecordNotFound</span>
|
|
<span class="pl-c">// If no record found when you query data, gorm will return RecordNotFound error, you could check it like this:</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>hello world<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&User{}).<span class="pl-smi">Error</span> == gorm.<span class="pl-smi">RecordNotFound</span>
|
|
<span class="pl-c">// Or use the shortcut method</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>hello world<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&user).<span class="pl-c1">RecordNotFound</span>()
|
|
|
|
<span class="pl-k">if</span> db.<span class="pl-c1">Model</span>(&user).<span class="pl-c1">Related</span>(&credit_card).<span class="pl-c1">RecordNotFound</span>() {
|
|
<span class="pl-c">// no credit card found error handling</span>
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="logger" class="anchor" href="#logger" aria-hidden="true"><span class="octicon octicon-link"></span></a>Logger</h2>
|
|
|
|
<p>Gorm has built-in logger support</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Enable Logger</span>
|
|
db.<span class="pl-c1">LogMode</span>(<span class="pl-c1">true</span>)
|
|
|
|
<span class="pl-c">// Diable Logger</span>
|
|
db.<span class="pl-c1">LogMode</span>(<span class="pl-c1">false</span>)
|
|
|
|
<span class="pl-c">// Debug a single operation</span>
|
|
db.<span class="pl-c1">Debug</span>().<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>jinzhu<span class="pl-pds">"</span></span>).<span class="pl-c1">First</span>(&User{})</pre></div>
|
|
|
|
<p><img src="https://raw.github.com/jinzhu/gorm/master/images/logger.png" alt="logger"></p>
|
|
|
|
<h3>
|
|
<a id="customize-logger" class="anchor" href="#customize-logger" aria-hidden="true"><span class="octicon octicon-link"></span></a>Customize Logger</h3>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Refer gorm's default logger for how to: https://github.com/jinzhu/gorm/blob/master/logger.go#files</span>
|
|
db.<span class="pl-c1">SetLogger</span>(gorm.<span class="pl-smi">Logger</span>{revel.<span class="pl-smi">TRACE</span>})
|
|
db.<span class="pl-c1">SetLogger</span>(log.<span class="pl-c1">New</span>(os.<span class="pl-smi">Stdout</span>, <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\r\n</span><span class="pl-pds">"</span></span>, <span class="pl-c1">0</span>))</pre></div>
|
|
|
|
<h2>
|
|
<a id="existing-schema" class="anchor" href="#existing-schema" aria-hidden="true"><span class="octicon octicon-link"></span></a>Existing Schema</h2>
|
|
|
|
<p>If you have an existing database schema, and the primary key field is different from <code>id</code>, you can add a tag to the field structure to specify that this field is a primary key.</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Animal</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">AnimalId</span> <span class="pl-k">int64</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"primary_key"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Birthday</span> time.<span class="pl-smi">Time</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"DEFAULT:current_timestamp"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"default:'galeone'"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Age</span> <span class="pl-k">int64</span>
|
|
}</pre></div>
|
|
|
|
<p>If your column names differ from the struct fields, you can specify them like this:</p>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Animal</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">AnimalId</span> <span class="pl-k">int64</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"column:beast_id;primary_key"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Birthday</span> time.<span class="pl-smi">Time</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"column:day_of_the_beast"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Age</span> <span class="pl-k">int64</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"column:age_of_the_beast"<span class="pl-pds">`</span></span>
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="composite-primary-key" class="anchor" href="#composite-primary-key" aria-hidden="true"><span class="octicon octicon-link"></span></a>Composite Primary Key</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Product</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"primary_key"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">LanguageCode</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>gorm:"primary_key"<span class="pl-pds">`</span></span>
|
|
}</pre></div>
|
|
|
|
<h2>
|
|
<a id="database-indexes--foreign-key" class="anchor" href="#database-indexes--foreign-key" aria-hidden="true"><span class="octicon octicon-link"></span></a>Database Indexes & Foreign Key</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-c">// Add foreign key</span>
|
|
<span class="pl-c">// 1st param : foreignkey field</span>
|
|
<span class="pl-c">// 2nd param : destination table(id)</span>
|
|
<span class="pl-c">// 3rd param : ONDELETE</span>
|
|
<span class="pl-c">// 4th param : ONUPDATE</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">AddForeignKey</span>(<span class="pl-s"><span class="pl-pds">"</span>city_id<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>cities(id)<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>RESTRICT<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>RESTRICT<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// Add index</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">AddIndex</span>(<span class="pl-s"><span class="pl-pds">"</span>idx_user_name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// Multiple column index</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">AddIndex</span>(<span class="pl-s"><span class="pl-pds">"</span>idx_user_name_age<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// Add unique index</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">AddUniqueIndex</span>(<span class="pl-s"><span class="pl-pds">"</span>idx_user_name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// Multiple column unique index</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">AddUniqueIndex</span>(<span class="pl-s"><span class="pl-pds">"</span>idx_user_name_age<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>name<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>)
|
|
|
|
<span class="pl-c">// Remove index</span>
|
|
db.<span class="pl-c1">Model</span>(&User{}).<span class="pl-c1">RemoveIndex</span>(<span class="pl-s"><span class="pl-pds">"</span>idx_user_name<span class="pl-pds">"</span></span>)</pre></div>
|
|
|
|
<h2>
|
|
<a id="default-values" class="anchor" href="#default-values" aria-hidden="true"><span class="octicon octicon-link"></span></a>Default values</h2>
|
|
|
|
<div class="highlight highlight-go"><pre><span class="pl-k">type</span> <span class="pl-v">Animal</span> <span class="pl-k">struct</span> {
|
|
<span class="pl-v">ID</span> <span class="pl-k">int64</span>
|
|
<span class="pl-v">Name</span> <span class="pl-k">string</span> <span class="pl-s"><span class="pl-pds">`</span>sql:"default:'galeone'"<span class="pl-pds">`</span></span>
|
|
<span class="pl-v">Age</span> <span class="pl-k">int64</span>
|
|
}</pre></div>
|
|
|
|
<p>If you have defined a default value in the <code>sql</code> tag, the generated create SQl will ignore these fields if it is blank.</p>
|
|
|
|
<p>Eg.</p>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">Create</span>(&Animal{Age: <span class="pl-c1">99</span>, <span class="pl-v">Name</span>: <span class="pl-s"><span class="pl-pds">"</span><span class="pl-pds">"</span></span>})</pre></div>
|
|
|
|
<p>The generated SQL will be:</p>
|
|
|
|
<div class="highlight highlight-sql"><pre><span class="pl-k">INSERT INTO</span> animals(<span class="pl-s"><span class="pl-pds">"</span>age<span class="pl-pds">"</span></span>) <span class="pl-k">values</span>(<span class="pl-s"><span class="pl-pds">'</span>99<span class="pl-pds">'</span></span>);</pre></div>
|
|
|
|
<p>The same thing occurs in update statements.</p>
|
|
|
|
<h2>
|
|
<a id="more-examples-with-query-chain" class="anchor" href="#more-examples-with-query-chain" aria-hidden="true"><span class="octicon octicon-link"></span></a>More examples with query chain</h2>
|
|
|
|
<div class="highlight highlight-go"><pre>db.<span class="pl-c1">First</span>(&first_article).<span class="pl-c1">Count</span>(&total_count).<span class="pl-c1">Limit</span>(<span class="pl-c1">10</span>).<span class="pl-c1">Find</span>(&first_page_articles).<span class="pl-c1">Offset</span>(<span class="pl-c1">10</span>).<span class="pl-c1">Find</span>(&second_page_articles)
|
|
<span class="pl-c">//// SELECT * FROM articles LIMIT 1; (first_article)</span>
|
|
<span class="pl-c">//// SELECT count(*) FROM articles; (total_count)</span>
|
|
<span class="pl-c">//// SELECT * FROM articles LIMIT 10; (first_page_articles)</span>
|
|
<span class="pl-c">//// SELECT * FROM articles LIMIT 10 OFFSET 10; (second_page_articles)</span>
|
|
|
|
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>created_at > ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>2013-10-10<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&cancelled_orders, <span class="pl-s"><span class="pl-pds">"</span>state = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>cancelled<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&shipped_orders, <span class="pl-s"><span class="pl-pds">"</span>state = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>shipped<span class="pl-pds">"</span></span>)
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE created_at > '2013/10/10' AND state = 'cancelled'; (cancelled_orders)</span>
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE created_at > '2013/10/10' AND state = 'shipped'; (shipped_orders)</span>
|
|
|
|
|
|
<span class="pl-c">// Use variables to keep query chain</span>
|
|
<span class="pl-smi">todays_orders</span> <span class="pl-k">:=</span> db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>created_at > ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>2013-10-29<span class="pl-pds">"</span></span>)
|
|
<span class="pl-smi">cancelled_orders</span> <span class="pl-k">:=</span> todays_orders.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>state = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>cancelled<span class="pl-pds">"</span></span>)
|
|
<span class="pl-smi">shipped_orders</span> <span class="pl-k">:=</span> todays_orders.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>state = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>shipped<span class="pl-pds">"</span></span>)
|
|
|
|
|
|
<span class="pl-c">// Search with shared conditions for different tables</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>product_name = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>fancy_product<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&orders).<span class="pl-c1">Find</span>(&shopping_carts)
|
|
<span class="pl-c">//// SELECT * FROM orders WHERE product_name = 'fancy_product'; (orders)</span>
|
|
<span class="pl-c">//// SELECT * FROM carts WHERE product_name = 'fancy_product'; (shopping_carts)</span>
|
|
|
|
|
|
<span class="pl-c">// Search with shared conditions from different tables with specified table</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>mail_type = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>TEXT<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users1).<span class="pl-c1">Table</span>(<span class="pl-s"><span class="pl-pds">"</span>deleted_users<span class="pl-pds">"</span></span>).<span class="pl-c1">Find</span>(&users2)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE mail_type = 'TEXT'; (users1)</span>
|
|
<span class="pl-c">//// SELECT * FROM deleted_users WHERE mail_type = 'TEXT'; (users2)</span>
|
|
|
|
|
|
<span class="pl-c">// FirstOrCreate example</span>
|
|
db.<span class="pl-c1">Where</span>(<span class="pl-s"><span class="pl-pds">"</span>email = ?<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>x@example.org<span class="pl-pds">"</span></span>).<span class="pl-c1">Attrs</span>(User{RegisteredIp: <span class="pl-s"><span class="pl-pds">"</span>111.111.111.111<span class="pl-pds">"</span></span>}).<span class="pl-c1">FirstOrCreate</span>(&user)
|
|
<span class="pl-c">//// SELECT * FROM users WHERE email = 'x@example.org';</span>
|
|
<span class="pl-c">//// INSERT INTO "users" (email,registered_ip) VALUES ("x@example.org", "111.111.111.111") // if record not found</span></pre></div>
|
|
|
|
<h2>
|
|
<a id="todo" class="anchor" href="#todo" aria-hidden="true"><span class="octicon octicon-link"></span></a>TODO</h2>
|
|
|
|
<ul>
|
|
<li>Github Pages</li>
|
|
</ul>
|
|
|
|
<h1>
|
|
<a id="author" class="anchor" href="#author" aria-hidden="true"><span class="octicon octicon-link"></span></a>Author</h1>
|
|
|
|
<p><strong>jinzhu</strong></p>
|
|
|
|
<ul>
|
|
<li><a href="http://github.com/jinzhu">http://github.com/jinzhu</a></li>
|
|
<li><a href="mailto:wosmvp@gmail.com">wosmvp@gmail.com</a></li>
|
|
<li><a href="http://twitter.com/zhangjinzhu">http://twitter.com/zhangjinzhu</a></li>
|
|
</ul>
|
|
|
|
<h2>
|
|
<a id="license" class="anchor" href="#license" aria-hidden="true"><span class="octicon octicon-link"></span></a>License</h2>
|
|
|
|
<p>Released under the <a href="https://github.com/jinzhu/gorm/blob/master/License">MIT License</a>.</p>
|
|
</section>
|
|
<footer>
|
|
<p><small>Hosted on <a href="https://pages.github.com">GitHub Pages</a> using the Dinky theme</small></p>
|
|
</footer>
|
|
</div>
|
|
<!--[if !IE]><script>fixScale(document);</script><![endif]-->
|
|
<script type="text/javascript">
|
|
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
|
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
|
</script>
|
|
<script type="text/javascript">
|
|
try {
|
|
var pageTracker = _gat._getTracker("UA-23459165-4");
|
|
pageTracker._trackPageview();
|
|
} catch(err) {}
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|