🐥The very simple ORM library for Golang
Alternatives To Gosql
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
9 days ago224otherJava
🏆 零代码、全功能、强安全 ORM 库 🚀 后端接口和文档零代码,前端(客户端) 定制返回 JSON 的数据和结构。 🏆 A JSON Transmission Protocol and an ORM Library 🚀 provides APIs and Docs without writing any code.
Drizzle Orm13,733352 days ago407July 27, 2023489apache-2.0TypeScript
TypeScript ORM that feels like writing SQL.
Sqlc9,1561613 hours ago140July 31, 2023232mitGo
Generate type-safe code from SQL
Sqlalchemy7,80741,8535,3399 hours ago289July 15, 2023183mitPython
The Database Toolkit for Python
Exposed7,4842121 hours ago17July 28, 2023254apache-2.0Kotlin
Kotlin SQL Framework
Objection.js7,087707405a day ago202July 22, 202377mitJavaScript
An SQL-friendly ORM for Node.js
Records6,956150276 months ago11September 02, 201764iscPython
SQL for Humans™
Mikro Orm6,51315715 hours ago2,010August 07, 202366mitTypeScript
TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, PostgreSQL and SQLite databases.
Sqlboiler6,037124a day ago98March 21, 202390bsd-3-clauseGo
Generate a Go ORM tailored to your database schema.
Jooq5,6531,1753179 hours ago204June 23, 20231,924otherJava
jOOQ is the best way to write SQL in Java
Alternatives To Gosql
Select To Compare

Alternative Project Comparisons


The package based on sqlx, It's simple and keep simple

Build Status codecov Go Report Card

⚠️ Because of some disruptive changes, The current major version is upgraded to V2,If you continue with V1, you can check out the v1 branches https://github.com/ilibs/gosql/tree/v1

V2 ChangeLog

  • Remove the second argument to the Model() and Table() functions and replace it with WithTx(tx)
  • Remove Model interface DbName() function,use the Use() function
  • Uniform API design specification, see APIDESIGN
  • Relation add connection:"db2" struct tag, Solve the cross-library connection problem caused by deleting DbName()
  • Discard the WithTx function


Connection database and use sqlx original function,See the jmoiron/sqlx

import (
    _ "github.com/go-sql-driver/mysql" //mysql driver

func main(){
    configs := make(map[string]*gosql.Config)

    configs["default"] = &gosql.Config{
        Enable:  true,
        Driver:  "mysql",
        Dsn:     "root:123456@tcp(",
        ShowSql: true,

    //connection database
    gosql.QueryRowx("select * from users where id = 1")

Use default database, So you can use wrapper function

gosql.Exec("insert into users(name,email,created_at,updated_at) value(?,?,?,?)","test","[email protected]",time.Now(),time.Now())

rows,err := gosql.Queryx("select * from users")
for rows.Next() {
    user := &Users{}
    err = rows.StructScan(user)

user := &Users{}
err := gosql.QueryRowx("select * from users where id = ?",1).StructScan(user)

user := &Users{}
err := gosql.Get(user,"select * from users where id = ?",1)

users := make([]Users)
err := gosql.Select(&users,"select * from users")

//Change database
db := gosql.Use("test")
db.Queryx("select * from tests")

You can also set the default database connection name


gosql.Get etc., will use the configuration with the connection name log

Using struct

type Users struct {
	Id        int       `db:"id"`
	Name      string    `db:"name"`
	Email     string    `db:"email"`
	Status    int       `db:"status"`
	CreatedAt time.Time `db:"created_at"`
	UpdatedAt time.Time `db:"updated_at"`

func (u *Users) TableName() string {
	return "users"

func (u *Users) PK() string {
	return "id"

user := &Users{}

user := make([]Users,0)

//Create and auto set CreatedAt
gosql.Model(&User{Name:"test",Email:"[email protected]"}).Create()

gosql.Model(&User{Name:"test2",Email:"[email protected]"}).Where("id=?",1).Update()
//If you need to update the zero value, you can do so


If you use struct to generate where conditions

//Get where id = 1 and name = "test1"
user := &Users{Id:1,Name:"test1"}

//Update default use primary key as the condition
//Use custom conditions
//Builder => UPDATE users SET `id`=?,`name`=?,`updated_at`=? WHERE (status = ?)
gosql.Model(&User{Id:1,Name:"test2"}).Where("status = ?",1).Update()


But the zero value is filtered by default, you can specify fields that are not filtered. For example

user := &Users{Id:1,Status:0}

You can use the genstruct tool to quickly generate database structs


The Tx function has a callback function, if an error is returned, the transaction rollback

gosql.Tx(func(tx *gosql.DB) error {
    for id := 1; id < 10; id++ {
        user := &Users{
            Id:    id,
            Name:  "test" + strconv.Itoa(id),
            Email: "test" + strconv.Itoa(id) + "@test.com",
		//v2 support, do some database operations in the transaction (use 'tx' from this point, not 'gosql')

        if id == 8 {
            return errors.New("interrupt the transaction")

    //query with transaction
    var num int
    err := tx.QueryRowx("select count(*) from user_id = 1").Scan(&num)

    if err != nil {
        return err

    return nil

If you need to invoke context, you can use gosql.Txx

Now support gosql.Begin() or gosql.Use("other").Begin() for example:

tx, err := gosql.Begin()
if err != nil {
    return err

for id := 1; id < 10; id++ {
    _, err := tx.Exec("INSERT INTO users(id,name,status,created_at,updated_at) VALUES(?,?,?,?,?)", id, "test"+strconv.Itoa(id), 1, time.Now(), time.Now())
    if err != nil {
        return tx.Rollback()

return tx.Commit()

Automatic time

If your fields contain the following field names, they will be updated automatically


Using Map

Create Update Delete Count support map[string]interface,For example:

    "id":         1,
    "name":       "test",
    "email":      "[email protected]",
    "created_at": "2018-07-11 11:58:21",
    "updated_at": "2018-07-11 11:58:21",

gosql.Table("users").Where("id = ?", 1).Update(map[string]interface{}{
    "name":  "fifsky",
    "email": "[email protected]",

gosql.Table("users").Where("id = ?", 1).Delete()

gosql.Table("users").Where("id = ?", 1).Count()

//Change database
gosql.Use("db2").Table("users").Where("id = ?", 1).Count()

//Transaction `tx`
tx.Table("users").Where("id = ?", 1}).Count()


Now Model support sql.Null* field's, Note, however, that if sql.Null* is also filtered by zero values,For example

type Users struct {
	Id          int            `db:"id"`
	Name        string         `db:"name"`
	Email       string         `db:"email"`
	Status      int            `db:"status"`
	SuccessTime sql.NullString `db:"success_time" json:"success_time"`
	CreatedAt   time.Time      `db:"created_at" json:"created_at"`
	UpdatedAt   time.Time      `db:"updated_at" json:"updated_at"`

user := &Users{
    Id: 1,
    SuccessTime: sql.NullString{
        String: "2018-09-03 00:00:00",
        Valid:  false,

err := gosql.Model(user).Get()

Builder SQL:

Query: SELECT * FROM users WHERE (id=?);
Args:  []interface {}{1}
Time:  0.00082s

If sql.NullString of Valid attribute is false, SQL builder will ignore this zero value


Reference GORM Expr, Resolve update field self-update problem

//Builder SQL
//UPDATE `users` SET `count`=count + ?,`id`=?; [1 2]

"In" Queries

Because database/sql does not inspect your query and it passes your arguments directly to the driver, it makes dealing with queries with IN clauses difficult:

SELECT * FROM users WHERE level IN (?);

sqlx.In is encapsulated In gosql and can be queried using the following schema

var levels = []int{4, 6, 7}
rows, err := gosql.Queryx("SELECT * FROM users WHERE level IN (?);", levels)


user := make([]Users, 0)
err := gosql.Select(&user, "select * from users where id in(?)",[]int{1,2,3})


gosql used the golang structure to express the relationships between tables,You only need to use the relation Tag to specify the associated field, see example

⚠️ Since version v2, the relation query across library connections needs to be specified using connection tag

type MomentList struct {
	User   *models.Users    `json:"user" db:"-" relation:"user_id,id"`         //one-to-one
	Photos []models.Photos `json:"photos" db:"-" relation:"id,moment_id" connection:"db2"`     //one-to-many

Get single result

moment := &MomentList{}
err := gosql.Model(moment).Where("status = 1 and id = ?",14).Get()
//output User and Photos and you get the result


2018/12/06 13:27:54
	Query: SELECT * FROM `moments` WHERE (status = 1 and id = ?);
	Args:  []interface {}{14}
	Time:  0.00300s

2018/12/06 13:27:54
	Query: SELECT * FROM `moment_users` WHERE (id=?);
	Args:  []interface {}{5}
	Time:  0.00081s

2018/12/06 13:27:54
	Query: SELECT * FROM `photos` WHERE (moment_id=?);
	Args:  []interface {}{14}
	Time:  0.00093s

Get list result, many-to-many

var moments = make([]MomentList, 0)
err := gosql.Model(&moments).Where("status = 1").Limit(10).All()
//You get the total result  for *UserMoment slice


2018/12/06 13:50:59
	Query: SELECT * FROM `moments` WHERE (status = 1) LIMIT 10;
	Time:  0.00319s

2018/12/06 13:50:59
	Query: SELECT * FROM `moment_users` WHERE (id in(?));
	Args:  []interface {}{[]interface {}{5}}
	Time:  0.00094s

2018/12/06 13:50:59
	Query: SELECT * FROM `photos` WHERE (moment_id in(?, ?, ?, ?, ?, ?, ?, ?, ?, ?));
	Args:  []interface {}{[]interface {}{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}
	Time:  0.00087s

Relation Where:

moment := &MomentList{}
err := gosql.Relation("User" , func(b *gosql.Builder) {
    //this is builder instance,
    b.Where("gender = 0")
}).Get(moment , "select * from moments")


Hooks are functions that are called before or after creation/querying/updating/deletion.

If you have defiend specified methods for a model, it will be called automatically when creating, updating, querying, deleting, and if any callback returns an error, gosql will stop future operations and rollback current transaction.

// begin transaction
// update timestamp `CreatedAt`, `UpdatedAt`
// save
// commit or rollback transaction


func (u *Users) BeforeCreate(ctx context.Context) (err error) {
  if u.IsValid() {
    err = errors.New("can't save invalid data")

func (u *Users) AfterCreate(ctx context.Context, tx *gosql.DB) (err error) {
  if u.Id == 1 {
    u.Email = ctx.Value("email")

BeforeChange and AfterChange only used in create/update/delete

All Hooks:


Hook func type supports multiple ways:

func (u *Users) BeforeCreate()
func (u *Users) BeforeCreate() (err error)
func (u *Users) BeforeCreate(tx *gosql.DB)
func (u *Users) BeforeCreate(tx *gosql.DB) (err error)
func (u *Users) BeforeCreate(ctx context.Context)
func (u *Users) BeforeCreate(ctx context.Context) (err error)
func (u *Users) BeforeCreate(ctx context.Context, tx *rsql.DB)
func (u *Users) BeforeCreate(ctx context.Context, tx *rsql.DB) (err error)

If you want to use context feature, you need to use below function while start a sql, or the context in callback will be nil:

  1. gosql.WithContext(ctx).Model(...)
  2. gosql.Use("xxx").WithContext(ctx).Model(...)


sqlx jmoiron/sqlx

Popular Orm Projects
Popular Sql Projects
Popular Data Processing Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.