🔥 Go 轻量级开发通用库 🚀🚀🚀

2021-04-21 14:56:12 +08:00
 IIInsomnia

yiigo

Go 轻量级开发通用库

Features

Requirements

Go1.15+

Installation

go get -u github.com/shenghui0779/yiigo

Usage

Config

[app]
env = "dev" # dev | beta | prod
debug = true

[db]

    [db.default]
    driver = "mysql" # mysql | postgres | sqlite3
    dsn = "username:password@tcp(localhost:3306)/dbname?timeout=10s&charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&loc=Local" # mysql
    # dsn = "host=localhost port=5432 user=root password=secret dbname=test connect_timeout=10 sslmode=disable" # postgres
    # dsn = "file::memory:?cache=shared" # sqlite3
    max_open_conns = 20
    max_idle_conns = 10
    conn_max_idle_time = 60 # 秒
    conn_max_lifetime = 60 # 秒

[mongo]

    [mongo.default]
    # 参考: https://docs.mongodb.com/manual/reference/connection-string
    dsn = "mongodb://localhost:27017/?connectTimeoutMS=10000&minPoolSize=10&maxPoolSize=20&maxIdleTimeMS=60000&readPreference=primary"

[redis]

    [redis.default]
    address = "127.0.0.1:6379"
    password = ""
    database = 0
    connect_timeout = 10 # 秒
    read_timeout = 10 # 秒
    write_timeout = 10 # 秒
    pool_size = 10
    pool_limit = 20
    idle_timeout = 60 # 秒
    wait_timeout = 10 # 秒
    prefill_parallelism = 0 # 预填充连接数

[nsq]
lookupd = ["127.0.0.1:4161"]
nsqd = "127.0.0.1:4150"

[email]

    [email.default]
    host = "smtp.exmail.qq.com"
    port = 25
    username = ""
    password = ""

[log]

    [log.default]
    path = "app.log"
    max_size = 500
    max_age = 0
    max_backups = 0
    compress = true

# 自定义配置

[foo]
amount = 100
ports = [80, 81, 82]
weight = 50.6
prices = [23.5, 46.7, 45.9]
hosts = ["127.0.0.1", "192.168.1.1", "192.168.1.80"]
birthday = "2019-07-12 13:03:19"
yiigo.Env("app.env").String()
yiigo.Env("app.debug").Bool()
yiigo.Env("foo.amount").Int()
yiigo.Env("foo.ports").Ints()
yiigo.Env("foo.weight").Float()
yiigo.Env("foo.price").Floats()
yiigo.Env("foo.hosts").Strings()
yiigo.Env("foo.birthday").Time("2006-01-02 15:04:05")

MySQL

// default db
yiigo.DB().Get(&User{}, "SELECT * FROM user WHERE id = ?", 1)

// other db
yiigo.DB("other").Get(&User{}, "SELECT * FROM user WHERE id = ?", 1)

ORM(ent)

import "<your_project>/ent"

// default driver
client := ent.NewClient(ent.Driver(yiigo.EntDriver()))

// other driver
client := ent.NewClient(ent.Driver(yiigo.EntDriver("other")))

MongoDB

// default mongodb
yiigo.Mongo().Database("test").Collection("numbers").InsertOne(context.Background(), bson.M{"name": "pi", "value": 3.14159})

// other mongodb
yiigo.Mongo("other").Database("test").Collection("numbers").InsertOne(context.Background(), bson.M{"name": "pi", "value": 3.14159})

Redis

// default redis
conn, err := yiigo.Redis().Get(context.Background())

if err != nil {
    log.Fatal(err)
}

defer yiigo.Redis().Put(conn)

conn.Do("SET", "test_key", "hello world")

// other redis
conn, err := yiigo.Redis("other").Get(context.Background())

if err != nil {
    log.Fatal(err)
}

defer yiigo.Redis("other").Put(conn)

conn.Do("SET", "test_key", "hello world")

HTTP

// default client
yiigo.HTTPGet(context.Background(), "URL", yiigo.WithHTTPTimeout(5*time.Second))

// new client
c := yiigo.NewHTTPClient(*http.Client)
c.Get(context.Background(), "URL", yiigo.WithHTTPTimeout(5*time.Second))

Logger

// default logger
yiigo.Logger().Info("hello world")

// other logger
yiigo.Logger("other").Info("hello world")

SQL Builder

😊 为不想手写 SQL 的你生成 SQL 语句,用于 sqlx 的相关方法;

⚠️ 作为辅助方法,目前支持的特性有限,复杂的 SQL (如:子查询等)还需自己手写

builder := yiigo.NewSQLBuilder(yiigo.MySQL)
builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).ToQuery()
// SELECT * FROM user WHERE id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("name = ? AND age > ?", "shenghui0779", 20),
).ToQuery()
// SELECT * FROM user WHERE name = ? AND age > ?
// [shenghui0779 20]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.WhereIn("age IN (?)", []int{20, 30}),
).ToQuery()
// SELECT * FROM user WHERE age IN (?, ?)
// [20 30]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Select("id", "name", "age"),
    yiigo.Where("id = ?", 1),
).ToQuery()
// SELECT id, name, age FROM user WHERE id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Distinct("name"),
    yiigo.Where("id = ?", 1),
).ToQuery()
// SELECT DISTINCT name FROM user WHERE id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.LeftJoin("address", "user.id = address.user_id"),
    yiigo.Where("user.id = ?", 1),
).ToQuery()
// SELECT * FROM user LEFT JOIN address ON user.id = address.user_id WHERE user.id = ?
// [1]

builder.Wrap(
    yiigo.Table("address"),
    yiigo.Select("user_id", "COUNT(*) AS total"),
    yiigo.GroupBy("user_id"),
    yiigo.Having("user_id = ?", 1),
).ToQuery()
// SELECT user_id, COUNT(*) AS total FROM address GROUP BY user_id HAVING user_id = ?
// [1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("age > ?", 20),
    yiigo.OrderBy("age ASC", "id DESC"),
    yiigo.Offset(5),
    yiigo.Limit(10),
).ToQuery()
// SELECT * FROM user WHERE age > ? ORDER BY age ASC, id DESC OFFSET 5 LIMIT 10
// [20]

wrap1 := builder.Wrap(
    Table("user_1"),
    Where("id = ?", 2),
)

builder.Wrap(
    Table("user_0"),
    Where("id = ?", 1),
    Union(wrap1),
).ToQuery()
// (SELECT * FROM user_0 WHERE id = ?) UNION (SELECT * FROM user_1 WHERE id = ?)
// [1, 2]

builder.Wrap(
    Table("user_0"),
    Where("id = ?", 1),
    UnionAll(wrap1),
).ToQuery()
// (SELECT * FROM user_0 WHERE id = ?) UNION ALL (SELECT * FROM user_1 WHERE id = ?)
// [1, 2]

builder.Wrap(
    Table("user_0"),
    WhereIn("age IN (?)", []int{10, 20}),
    Limit(5),
    Union(
        builder.Wrap(
            Table("user_1"),
            Where("age IN (?)", []int{30, 40}),
            Limit(5),
        ),
    ),
).ToQuery()
// (SELECT * FROM user_0 WHERE age IN (?, ?) LIMIT ?) UNION (SELECT * FROM user_1 WHERE age IN (?, ?) LIMIT ?)
// [10, 20, 5, 30, 40, 5]

builder.Wrap(Table("user")).ToTruncate()
// TRUNCATE user
type User struct {
    ID     int    `db:"-"`
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

builder.Wrap(Table("user")).ToInsert(&User{
    Name: "yiigo",
    Age:  29,
})
// INSERT INTO user (name, age) VALUES (?, ?)
// [yiigo 29]

builder.Wrap(yiigo.Table("user")).ToInsert(yiigo.X{
    "name": "yiigo",
    "age":  29,
})
// INSERT INTO user (name, age) VALUES (?, ?)
// [yiigo 29]
type User struct {
    ID     int    `db:"-"`
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

builder.Wrap(Table("user")).ToBatchInsert([]*User{
    {
        Name: "shenghui0779",
        Age:  20,
    },
    {
        Name: "yiigo",
        Age:  29,
    },
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [shenghui0779 20 yiigo 29]

builder.Wrap(yiigo.Table("user")).ToBatchInsert([]yiigo.X{
    {
        "name": "shenghui0779",
        "age":  20,
    },
    {
        "name": "yiigo",
        "age":  29,
    },
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [shenghui0779 20 yiigo 29]
type User struct {
    Name   string `db:"name"`
    Age    int    `db:"age"`
    Phone  string `db:"phone,omitempty"`
}

builder.Wrap(
    Table("user"),
    Where("id = ?", 1),
).ToUpdate(&User{
    Name: "yiigo",
    Age:  29,
})
// "UPDATE user SET name = ?, age = ? WHERE id = ?"
// [yiigo 29 1]

builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).ToUpdate(yiigo.X{
    "name": "yiigo",
    "age":  29,
})
// UPDATE user SET name = ?, age = ? WHERE id = ?
// [yiigo 29 1]

builder.Wrap(
    yiigo.Table("product"),
    yiigo.Where("id = ?", 1),
).ToUpdate(yiigo.X{
    "price": yiigo.Clause("price * ? + ?", 2, 100),
})
// UPDATE product SET price = price * ? + ? WHERE id = ?
// [2 100 1]
builder.Wrap(
    yiigo.Table("user"),
    yiigo.Where("id = ?", 1),
).ToDelete()
// DELETE FROM user WHERE id = ?
// [1]

Documentation

Enjoy 😊

3087 次点击
所在节点    Go 编程语言
5 条回复
betteron
2021-04-21 15:19:21 +08:00
ORM 推荐 ent 的理由是啥, 我们现在在用 gorm,与之比较呢?
masterclock
2021-04-21 15:44:25 +08:00
gorm:
db.Where("name = ?", 1).Find(&users)

ent:
client.User.Query(user.Name("xyz")).All(ctx)

以前也用 gorm,类型信息全没了,实在不爽。
FightPig
2021-04-21 22:58:11 +08:00
我习惯用 gorm,看个人习惯了
alinwu05
2021-04-22 21:24:37 +08:00
yiigo,和 yii 什么关系?
IIInsomnia
2021-04-23 08:00:48 +08:00
@alinwu05 没啥关系,就是用的他的谐音和通“易”的说法,旨在对新手来说,让 Go 开发更容易

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/772191

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX