zoukankan      html  css  js  c++  java
  • 【转】数据库无关的GO语言ORM

    项目地址:https://github.com/eaigner/hood

    这是一个极具美感的ORM库。

    特性

    • 链式的api
    • 事务支持
    • 迁移和名字空间生成
    • 模型变量
    • 模型时间
    • 数据库方言接口
    • 没有含糊的字段
    • 干净可测试的代码

    打开数据库

    如果方言已经注册可以直接打开数据库

    hd, err := hood.Open("postgres", "user=<username> dbname=<database>")
    

    你也可以打开数据库时候指定方言

    	
    hd := hood.New(db, NewPostgres())
    

    Schemas

    你可以这样声明

    type Person struct {
      
    // Auto-incrementing int field 'id'
      Id hood.Id
     
      
    // Custom primary key field 'first_name', with presence validation
      FirstName string `sql:"pk" validate:"presence"`
     
      
    // string field 'last_name' with size 128, NOT NULL
      LastName string `sql:"size(128),notnull"`
     
      
    // string field 'tag' with size 255, default value 'customer'
      Tag string `sql:"size(255),default('customer')"`
     
      
    // You can also combine tags, default value 'orange'
      CombinedTags string `sql:"size(128),default('orange')"`
      Birthday     time.Time   
    // timestamp field 'birthday'
      Data         []byte      
    // data field 'data'
      IsAdmin      bool        
    // boolean field 'is_admin'
      Notes        string      
    // text field 'notes'
     
      
    // You can alternatively define a var char as a string field by setting a size
      Nick  string  `sql:"size(128)"`
     
      
    // Validates number range
      Balance int `validate:"range(10:20)"`
     
      
    // These fields are auto updated on save
      Created hood.Created
      Updated hood.Updated
     
      
    // ... and other built in types (int, uint, float...)
    }
     
    // Indexes are defined via the Indexed interface to avoid
    // polluting the table fields.
     
    func (table *Person) Indexes(indexes *hood.Indexes) {
      indexes.Add("tag_index", "tag")
    // params: indexName, unique, columns...
      indexes.AddUnique("name_index", "first_name", "last_name")
    }
    
    

    数据迁移

    你要先安装hood tool ,然后运行

    go get github.com/eaigner/hood
    cd $GOPATH/src/github.com/eaigner/hood
    ./install.sh<
    

    例子

    下面是一个使用例子

    package main
     
    import (
        "hood"
    )
     
    func main() {
        
    // Open a DB connection, use New() alternatively for unregistered dialects
        hd, err := hood.Open("postgres", "user=hood dbname=hood_test sslmode=disable")
        if err != nil {
            panic(err)
        }
     
        
    // Create a table
        type Fruit struct {
            Id    hood.Id
            Name  string `validate:"presence"`
            Color string
        }
     
        err = hd.CreateTable(&Fruit{})
        if err != nil {
            panic(err)
        }
     
        fruits := []Fruit{
            Fruit{Name: "banana", Color: "yellow"},
            Fruit{Name: "apple", Color: "red"},
            Fruit{Name: "grapefruit", Color: "yellow"},
            Fruit{Name: "grape", Color: "green"},
            Fruit{Name: "pear", Color: "yellow"},
        }
     
        
    // Start a transaction
        tx := hd.Begin()
     
        ids, err := tx.SaveAll(&fruits)
        if err != nil {
            panic(err)
        }
     
        fmt.Println("inserted ids:", ids)
    // [1 2 3 4 5]
     
        
    // Commit changes
        err = tx.Commit()
        if err != nil {
            panic(err)
        }
     
        
    // Ids are automatically updated
        if fruits[0].Id != 1 || fruits[1].Id != 2 || fruits[2].Id != 3 {
            panic("id not set")
        }
     
        
    // If an id is already set, a call to save will result in an update
        fruits[0].Color = "green"
     
        ids, err = hd.SaveAll(&fruits)
        if err != nil {
            panic(err)
        }
     
        fmt.Println("updated ids:", ids)
    // [1 2 3 4 5]
     
        if fruits[0].Id != 1 || fruits[1].Id != 2 || fruits[2].Id != 3 {
            panic("id not set")
        }
     
        
    // Let's try to save a row that does not satisfy the required validations
        _, err = hd.Save(&Fruit{})
        if err == nil || err.Error() != "value not set" {
            panic("does not satisfy validations, should not save")
        }
     
        
    // Find
        
    //
        
    // The markers are db agnostic, so you can always use '?'
        
    // e.g. in Postgres they are replaced with $1, $2, ...
        var results []Fruit
        err = hd.Where("color", "=", "green").OrderBy("name").Limit(1).Find(&results)
        if err != nil {
            panic(err)
        }
     
        fmt.Println("results:", results)
    // [{1 banana green}]
     
        
    // Delete
        ids, err = hd.DeleteAll(&results)
        if err != nil {
            panic(err)
        }
     
        fmt.Println("deleted ids:", ids)
    // [1]
     
        results = nil
        err = hd.Find(&results)
        if err != nil {
            panic(err)
        }
     
        fmt.Println("results:", results)
    // [{2 apple red} {3 grapefruit yellow} {4 grape green} {5 pear yellow}]
     
        
    // Drop
        hd.DropTable(&Fruit{})
    }
    
  • 相关阅读:
    HDU 3586 Information Disturbing (树形DP+二分)
    HDU 6053 TrickGCD (莫比乌斯函数)
    51Nod 1554 欧姆诺姆和项链 (KMP)
    HDU 6153 A Secret (KMP)
    HDU 6156 Palindrome Function (数位DP)
    HDU 6148 Valley Numer (数位DP)
    UVa 1513 Movie collection (树状数组)
    HDU 6125 Free from square (状压DP+背包)
    UVa 10766 Organising the Organisation (生成树计数)
    tensorflow 待阅读的资料
  • 原文地址:https://www.cnblogs.com/x3d/p/go-orm-hood.html
Copyright © 2011-2022 走看看