One of Beego Models

Source: Internet
Author: User
Tags db2 local time manage connection

Model (Models)-Beego ORM

Original

Beego ORM is a powerful Go language ORM framework. Her inspiration comes mainly from Django ORM and SQLAlchemy.

Currently, the framework is still in development and any changes that could lead to incompatibilities may occur.

Database drivers are supported:

    • Mysql:github.com/go-sql-driver/mysql
    • Postgresql:github.com/lib/pq
    • Sqlite3:github.com/mattn/go-sqlite3

The above database drivers all pass the basic test, but we still need your feedback.

ORM Features:

    • Supports all types of Go storage
    • Easy to use with a simple CRUD style
    • Auto Join Association Table
    • Cross-Database compatible queries
    • Allow direct use of SQL queries/mappings
    • Rigorous and complete testing to ensure the stability and robustness of ORM

Install ORM:

go get github.com/astaxie/beego/orm

How to use ORM

Compared to the standard, now the Models folder to create the model of the object, all about the database operations are in the models, controller calls the method in models.

Models.go:

package mainimport (    "github.com/astaxie/beego/orm" //导入包)//定义 struct和数据表进行映射的type User struct {    Id          int    Name        string    Profile     *Profile   `orm:"rel(one)"` // OneToOne relation    Post        []*Post `orm:"reverse(many)"` // 设置一对多的反向关系}type Profile struct {    Id          int    Age         int16    User        *User   `orm:"reverse(one)"` // 设置一对一反向关系(可选)}type Post struct {    Id    int    Title string    User  *User  `orm:"rel(fk)"`    //设置一对多关系    Tags  []*Tag `orm:"rel(m2m)"`}type Tag struct {    Id    int    Name  string    Posts []*Post `orm:"reverse(many)"`}func init() {    // 需要在init中注册定义的model    orm.RegisterModel(new(User), new(Post), new(Profile), new(Tag))}

Main.go

package mainimport (    "fmt"    "github.com/astaxie/beego/orm"    _ "github.com/go-sql-driver/mysql" // 只是调用init方法)func init() {    orm.RegisterDriver("mysql", orm.DRMySQL)    orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8")}func main() {    o := orm.NewOrm()    o.Using("default") // 默认使用 default,你可以指定为其他数据库    profile := new(Profile)    profile.Age = 30    user := new(User)    user.Profile = profile    user.Name = "slene"    fmt.Println(o.Insert(profile))    fmt.Println(o.Insert(user))}

Settings for the database

Currently ORM supports three types of databases, the following are tested driver

Add the driver you need to use in import

import (    _ "github.com/go-sql-driver/mysql"    _ "github.com/lib/pq"    _ "github.com/mattn/go-sqlite3")

Registerdriver

Three default types of databases

// For version 1.6orm.DRMySQLorm.DRSqliteorm.DRPostgres// < 1.6orm.DR_MySQLorm.DR_Sqliteorm.DR_Postgres
// 参数1   driverName// 参数2   数据库类型// 这个用来设置 driverName 对应的数据库类型// mysql / sqlite3 / postgres 这三种是默认已经注册过的,所以可以无需设置orm.RegisterDriver("mysql", orm.DRMySQL)

RegisterDatabase

The ORM must register an alias for default the database as the default usage.

ORM uses Golang's own connection pool

 //registerdatabase Setting the database connect params. Use the database driver self dataSource args.func registerdatabase (aliasname, drivername, dataSource string, params ... int ) Error {var (err Error DB *sql. DB al *alias) db, err = sql. Open (drivername, DataSource) if err! = Nil {err = FMT. Errorf ("Register db '%s ',%s ', aliasname, err.    Error ()) Goto end} al, err = Addaliaswthdb (aliasname, drivername, db) if err! = Nil {goto END } al. DataSource = DataSource Detecttz (AL) for I, V: = range params {switch I {case 0:SETMAXID Leconns (al. Name, V) Case 1:setmaxopenconns (al. Name, v)}}end:if err! = nil {if db! = Nil {db. Close ()} debuglog.println (err. Error ())} return err}  
// 参数1        数据库的别名,用来在 ORM 中切换数据库使用// 参数2        driverName// 参数3        对应的链接字符串orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8")// 参数4(可选)  设置最大空闲连接// 参数5(可选)  设置最大数据库连接 (go >= 1.2)maxIdle := 30maxConn := 30orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8", maxIdle, maxConn)

Setmaxidleconns

Set the maximum idle connection for the database based on the alias of the database

orm.SetMaxIdleConns("default", 30)

Setmaxopenconns

Set the maximum database connection for the database based on the alias of the database (Go >= 1.2)

orm.SetMaxOpenConns("default", 30)

Time zone settings

The ORM uses time by default. local time zone

    • The time it takes to automatically create an ORM
    • Time retrieved from the database converted to ORM local time

You can also make changes if you want.

// 设置为 UTC 时间orm.DefaultTimeLoc = time.UTC

While the ORM is registerdatabase, it gets the time zone used by the database, and then time. Time type access is converted to match the time system to ensure that no error occurs.

Attention:

    • Due to the Sqlite3 design, access defaults to UTC time
    • When using the Go-sql-driver driver, be aware of the parameter settings
      Starting with a version, the drive defaults to UTC time instead of local time, so specify the time zone parameter or all in UTC time
      For example:root:root@/orm_test?charset=utf8&loc=Asia%2FShanghai
      See Loc/parsetime

Registering the Model

If you use ORM. Queryseter for advanced queries, this is a must.

Conversely, this step is not required if you are using only RAW queries and map structs. You can go to view Raw SQL queries

Registermodel

To register your defined Model, the best design is to have a separate models.go file, which is registered in his init function.

Mini version Models.go

package mainimport "github.com/astaxie/beego/orm"type User struct {    Id   int    Name string}func init(){    orm.RegisterModel(new(User))}

Registermodel can also register multiple model

orm.RegisterModel(new(User), new(Profile), new(Post))

For a detailed struct definition, see the document model definition

Registermodelwithprefix

Use table name prefixes

orm.RegisterModelWithPrefix("prefix_", new(User))

The table name after creation is Prefix_user

Newormwithdb

Sometimes it is necessary to manage connection pooling and database links (e.g., the link pool of Go does not allow two queries to use the same link)

But also want to use ORM query function

var driverName, aliasName string// driverName 是驱动的名称// aliasName 是当前 db 的自定义别名var db *sql.DB...o := orm.NewOrmWithDB(driverName, aliasName, db)

Getdb

Returns *SQL from the registered database. DB object, by default returns the database that is aliased to default.

db, err := orm.GetDB()if err != nil {    fmt.Println("get default DataBase")}db, err := orm.GetDB("alias")if err != nil {    fmt.Println("get alias DataBase")}

Resetmodelcache

Resets a registered model struct, typically used to write test cases

orm.ResetModelCache()

ORM interface uses

Using ORM's inevitable contact with the Ormer interface, let's familiarize ourselves with

var o Ormero = orm.NewOrm() // 创建一个 Ormer// NewOrm 的同时会执行 orm.BootStrap (整个 app 只执行一次),用以验证模型之间的定义并缓存。

Switching the database, or, for transactional processing, will act on the Ormer object and any queries it makes.

So if you need to switch databases and transactions , do not use globally saved Ormer objects.

Ormer define the ORM InterfaceType Ormer Interface {//read data to model//For example://This would find User by Id Field//U = &user{id:user. ID}//err = Ormer.read (u)//This would find User by UserName field//U = &user{username: "Astaxie", Pass Word: "Pass"}//Err = Ormer.read (U, "UserName") Read (MD interface{}, cols ... string) error//Like Read (), but    With ' for UPDATE ' clause, useful in transaction.    Some databases is not a support for this feature.  Readforupdate (MD interface{}, cols ... string) error//Try to read a row from the database, or insert one if it doesn ' t exist Readorcreate (MD interface{}, col1 string, cols ... string) (bool, int64, error)//INSERT model data to Databa SE//For example://User: = new (user)//id, err = ormer.insert (user)//user must a pointer and Insert W Ill set user ' s PK field Insert (interface{}) (Int64, error)//mysql:insertorupdate (model) or insertorupdate (modeL, "colu=colu+value")//If Colu type is Integer:can use (+-*/), String:convert (Colu, "value")//Postgres:inserto Rupdate (model, "Conflictcolumnname") or insertorupdate (model, "Conflictcolumnname", "colu=colu+value")//if Colu type is Integer:can use (+-*/), String:colu | |     "Value" Insertorupdate (MD interface{}, Colconflitandargs ... string) (Int64, error)//insert some models to database    Insertmulti (bulk int, MDS interface{}) (Int64, error)//update model to database.    Cols set the columns those want to update. Find model by Id (PK) field and update columns specified by fields, if cols was null then update all columns//for EX Ample://User: = User{id:2}//user. Langs = append (user. Langs, "Zh-cn", "en-us")//user. Extra.name = "Beego"//user. Extra.data = "ORM"//num, err = ormer.update (&user, "Langs", "Extra") Update (MD interface{}, cols ... string) ( Int64, error)//delete model in database Delete (MD interface{},cols. String) (Int64, error)//load related models to MD model.    Args is limit, offset int and order string. Example://ormer.loadrelated (post, "Tags")//For _,tag: = Range post.    Tags{...} ARGS[0] bool true usedefaultrelsdepth; False depth 0//args[0] int loadrelationdepth//args[1] int limit default limit//args[2] int offset Defau    Lt offset 0//args[3] String order for example: "-id"//Make sure the relation are defined in model struct tags.    Loadrelated (MD interface{}, name string, args ... interface{}) (Int64, error)//create a models to models Queryer For example://Post: = Post{id:4}//ATM: = ORMER.QUERYM2M (&post, "Tags") querym2m (MD interface{}, NA    Me string) Querym2mer//Return a queryseter for table operations.    Table name can be string or struct. e.g. querytable ("user"), QueryTable (&user{}) or QueryTable ((*user) (nil)), QueryTable (ptrstructortablename interface{}) QueRyseter//Switch to another registered database driver by given name. Using (name string) error//BEGIN TRANSACTION//For example://O: = Neworm ()//ERR: = O.begin ()//.    . Err = O.rollback () Begin () error//COMMIT TRANSACTION commit () error//Rollback transaction Rollback (    Error//Return a raw query seter for RAW SQL string. For example://Ormer. Raw ("UPDATE ' user ' SET ' user_name ' =?") WHERE ' user_name ' =? "," Slene "," testing "). Exec ()////Update user testing ' s name to Slene Raw (query string, args ... interface{}) rawseter Driver () Driver }

QueryTable

Incoming table name, or Model object, returns a Queryseter

o := orm.NewOrm()var qs QuerySeterqs = o.QueryTable("user")// 如果表没有定义过,会立刻 panic

Using

Switch to a different database

orm.RegisterDataBase("db1", "mysql", "root:root@/orm_db2?charset=utf8")orm.RegisterDataBase("db2", "sqlite3", "data.db")o1 := orm.NewOrm()o1.Using("db1")o2 := orm.NewOrm()o2.Using("db2")// 切换为其他数据库以后// 这个 Ormer 对象的其下的 api 调用都将使用这个数据库

defaultthe database is used by default without calling the Using

Raw

Working directly with SQL statements

The Raw function returns a rawseter to manipulate the set SQL statements and parameters

o := NewOrm()var r RawSeterr = o.Raw("UPDATE user SET name = ? WHERE name = ?", "testing", "slene")

Driver

Returns the DB information used by the current ORM

type Driver interface {    Name() string    Type() DriverType}
orm.RegisterDataBase("db1", "mysql", "root:root@/orm_db2?charset=utf8")orm.RegisterDataBase("db2", "sqlite3", "data.db")o1 := orm.NewOrm()o1.Using("db1")dr := o1.Driver()fmt.Println(dr.Name() == "db1") // truefmt.Println(dr.Type() == orm.DRMySQL) // trueo2 := orm.NewOrm()o2.Using("db2")dr = o2.Driver()fmt.Println(dr.Name() == "db2") // truefmt.Println(dr.Type() == orm.DRSqlite) // true

Debug Mode Print query statement

Simple set Debug to True to print the query statement

There may be performance issues that are not recommended for use in production mode

func main() {    orm.Debug = true...

The OS is used by default. Stderr Output Log Information

Change the output to your own IO. Writer

var w io.Writer...// 设置为你的 io.Writer...orm.DebugLog = orm.NewLog(w)
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.