【转】数据库无关的GO语言ORM - hood

简介: 项目地址:https://github.com/eaigner/hood这是一个极具美感的ORM库。特性链式的api事务支持迁移和名字空间生成模型变量模型时间数据库方言接口没有含糊的字段干净可测试的代码打开数据库如果方言已经注册可以直接打开数据库hd, err := hood.

项目地址: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{})
}
目录
相关文章
|
2天前
|
JavaScript Java Go
探索Go语言在微服务架构中的优势
在微服务架构的浪潮中,Go语言以其简洁、高效和并发处理能力脱颖而出。本文将深入探讨Go语言在构建微服务时的性能优势,包括其在内存管理、网络编程、并发模型以及工具链支持方面的特点。通过对比其他流行语言,我们将揭示Go语言如何成为微服务架构中的一股清流。
|
1天前
|
Ubuntu 编译器 Linux
go语言中SQLite3驱动安装
【11月更文挑战第2天】
16 7
|
1天前
|
关系型数据库 Go 网络安全
go语言中PostgreSQL驱动安装
【11月更文挑战第2天】
15 5
|
1天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
13 4
|
1天前
|
存储 设计模式 安全
Go语言中的并发编程:从入门到精通###
本文深入探讨了Go语言中并发编程的核心概念与实践技巧,旨在帮助读者从理论到实战全面掌握Go的并发机制。不同于传统的技术文章摘要,本部分将通过一系列生动的案例和代码示例,直观展示Go语言如何优雅地处理并发任务,提升程序性能与响应速度。无论你是Go语言初学者还是有一定经验的开发者,都能在本文中找到实用的知识与灵感。 ###
|
2天前
|
编译器 Go 开发者
go语言中导入相关包
【11月更文挑战第1天】
11 3
|
1天前
|
安全 Go
用 Zap 轻松搞定 Go 语言中的结构化日志
在现代应用程序开发中,日志记录至关重要。Go 语言中有许多日志库,而 Zap 因其高性能和灵活性脱颖而出。本文详细介绍如何在 Go 项目中使用 Zap 进行结构化日志记录,并展示如何定制日志输出,满足生产环境需求。通过基础示例、SugaredLogger 的便捷使用以及自定义日志配置,帮助你在实际开发中高效管理日志。
9 1
|
2天前
|
关系型数据库 MySQL 数据库连接
go语言中打开数据库连接
【11月更文挑战第1天】
13 2
|
25天前
|
存储 关系型数据库 MySQL
Mysql(4)—数据库索引
数据库索引是用于提高数据检索效率的数据结构,类似于书籍中的索引。它允许用户快速找到数据,而无需扫描整个表。MySQL中的索引可以显著提升查询速度,使数据库操作更加高效。索引的发展经历了从无索引、简单索引到B-树、哈希索引、位图索引、全文索引等多个阶段。
58 3
Mysql(4)—数据库索引
|
10天前
|
关系型数据库 MySQL Linux
在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。
本文介绍了在 CentOS 7 中通过编译源码方式安装 MySQL 数据库的详细步骤,包括准备工作、下载源码、编译安装、配置 MySQL 服务、登录设置等。同时,文章还对比了编译源码安装与使用 RPM 包安装的优缺点,帮助读者根据需求选择最合适的方法。通过具体案例,展示了编译源码安装的灵活性和定制性。
49 2