Project Name | Stars | Downloads | Repos Using This | Packages Using This | Most Recent Commit | Total Releases | Latest Release | Open Issues | License | Language |
---|---|---|---|---|---|---|---|---|---|---|
Mall | 64,399 | 11 hours ago | 32 | apache-2.0 | Java | |||||
mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现,采用Docker容器化部署。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。 后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。 | ||||||||||
Strapi | 52,681 | 221 | 113 | 5 hours ago | 281 | May 11, 2022 | 352 | other | JavaScript | |
🚀 Strapi is the leading open-source headless CMS. It’s 100% JavaScript, fully customizable and developer-first. | ||||||||||
Interview_internal_reference | 34,630 | 10 days ago | 30 | Python | ||||||
2021年最新总结,阿里,腾讯,百度,美团,头条等技术面试题目,以及答案,专家出题人分析汇总。 | ||||||||||
Prisma | 30,048 | 442 | 6 hours ago | 4,993 | September 24, 2022 | 2,796 | apache-2.0 | TypeScript | ||
Next-generation ORM for Node.js & TypeScript | PostgreSQL, MySQL, MariaDB, SQL Server, SQLite, MongoDB and CockroachDB | ||||||||||
Mall Learning | 11,780 | a month ago | 24 | apache-2.0 | Java | |||||
mall学习教程,架构、业务、技术要点全方位解析。mall项目(50k+star)是一套电商系统,使用现阶段主流技术实现。涵盖了SpringBoot 2.3.0、MyBatis 3.4.6、Elasticsearch 7.6.2、RabbitMQ 3.7.15、Redis 5.0、MongoDB 4.2.5、Mysql5.7等技术,采用Docker容器化部署。 | ||||||||||
Migrate | 11,081 | 594 | a day ago | 129 | March 17, 2022 | 260 | other | Go | ||
Database migrations. CLI and Golang library. | ||||||||||
Mall Swarm | 9,716 | 3 months ago | 35 | apache-2.0 | Java | |||||
mall-swarm是一套微服务商城系统,采用了 Spring Cloud 2021 & Alibaba、Spring Boot 2.7、Oauth2、MyBatis、Docker、Elasticsearch、Kubernetes等核心技术,同时提供了基于Vue的管理后台方便快速搭建系统。mall-swarm在电商业务的基础集成了注册中心、配置中心、监控中心、网关等系统功能。文档齐全,附带全套Spring Cloud教程。 | ||||||||||
Blog | 7,293 | 3 days ago | 30 | gpl-2.0 | PLpgSQL | |||||
Everything about database,business.(Most for PostgreSQL). | ||||||||||
Coolify | 7,290 | 8 hours ago | 230 | apache-2.0 | Svelte | |||||
An open-source & self-hostable Heroku / Netlify alternative. | ||||||||||
Newsblur | 6,260 | 5 days ago | 135 | mit | Objective-C | |||||
NewsBlur is a personal news reader that brings people together to talk about the world. A new sound of an old instrument. |
一个好用的轻量级 Go 开发通用库。如果你不喜欢过度封装的重量级框架,这个库可能是个不错的选择 😊
go get -u github.com/shenghui0779/yiigo
// 默认加载当前目录下的`.env`文件
yiigo.LoadEnv()
// 加载指定配置文件
yiigo.LoadEnv(yiigo.WithEnvFile("mycfg.env"))
// 热加载
yiigo.LoadEnv(yiigo.WithEnvWatcher(func(e fsnotify.Event) {
fmt.Println(e.String())
}))
.env
ENV=dev
fmt.Println(os.Getenv("ENV"))
// output: dev
yiigo.Init(
yiigo.WithMySQL(yiigo.Default, &yiigo.DBConfig{
DSN: "dsn",
Options: &yiigo.DBOptions{
MaxOpenConns: 20,
MaxIdleConns: 10,
ConnMaxLifetime: 10 * time.Minute,
ConnMaxIdleTime: 5 * time.Minute,
},
}),
yiigo.WithMySQL("other", &yiigo.DBConfig{
DSN: "dsn",
Options: &yiigo.DBOptions{
MaxOpenConns: 20,
MaxIdleConns: 10,
ConnMaxLifetime: 10 * time.Minute,
ConnMaxIdleTime: 5 * time.Minute,
},
}),
)
// 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)
import "<your_project>/ent"
// default driver
client := ent.NewClient(ent.Driver(yiigo.EntDriver()))
// other driver
client := ent.NewClient(ent.Driver(yiigo.EntDriver("other")))
// register
yiigo.Init(
yiigo.WithMongo(yiigo.Default, "dsn"),
yiigo.WithMongo("other", "dsn"),
)
// 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})
// register
yiigo.Init(
yiigo.WithRedis(yiigo.Default, &yiigo.RedisConfig{
Addr: "addr",
Options: &yiigo.RedisOptions{
ConnTimeout: 10 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
PoolSize: 10,
IdleTimeout: 5 * time.Minute,
},
}),
yiigo.WithRedis("other", &yiigo.RedisConfig{
Addr: "addr",
Options: &yiigo.RedisOptions{
ConnTimeout: 10 * time.Second,
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
PoolSize: 10,
IdleTimeout: 5 * time.Minute,
},
}),
)
// default redis
yiigo.Redis().Do(context.Background(), "SET", "test_key", "hello world")
yiigo.Redis().DoFunc(context.Background(), func(ctx context.Context, conn *RedisConn) error {
if _, err := conn.Do("SET", "key1", "hello"); err != nil {
return err
}
if _, err := conn.Do("SET", "key2", "world"); err != nil {
return err
}
return nil
})
// other redis
yiigo.Redis("other").Do(context.Background(), "SET", "test_key", "hello world")
yiigo.Redis("other").DoFunc(context.Background(), func(ctx context.Context, conn *RedisConn) error {
if _, err := conn.Do("SET", "key1", "hello"); err != nil {
return err
}
if _, err := conn.Do("SET", "key2", "world"); err != nil {
return err
}
return nil
})
// register
yiigo.Init(
yiigo.WithLogger(yiigo.Default, yiigo.LoggerConfig{
Filename: "filename",
Options: &yiigo.LoggerOptions{
Stderr: true,
},
}),
yiigo.WithLogger("other", yiigo.LoggerConfig{
Filename: "filename",
Options: &yiigo.LoggerOptions{
Stderr: true,
},
}),
)
// default logger
yiigo.Logger().Info("hello world")
// other logger
yiigo.Logger("other").Info("hello world")
// default client
yiigo.HTTPGet(context.Background(), "URL")
// new client
client := yiigo.NewHTTPClient(*http.Client)
client.Do(context.Background(), http.MethodGet, "URL", nil)
// upload
form := yiigo.NewUploadForm(
yiigo.WithFormField("title", "TITLE"),
yiigo.WithFormField("description", "DESCRIPTION"),
yiigo.WithFormFile("media", "demo.mp4", func(w io.Writer) error {
f, err := os.Open("demo.mp4")
if err != nil {
return err
}
defer f.Close()
if _, err = io.Copy(w, f); err != nil {
return err
}
return nil
}),
)
yiigo.HTTPUpload(context.Background(), "URL", form)
😊 为不想手写SQL的你生成SQL语句,用于
sqlx
的相关方法;⚠️ 作为辅助方法,目前支持的特性有限,复杂的SQL(如:子查询等)还需自己手写
builder := yiigo.NewMySQLBuilder()
// builder := yiigo.NewSQLBuilder(yiigo.MySQL)
ctx := context.Background()
builder.Wrap(
yiigo.Table("user"),
yiigo.Where("id = ?", 1),
).ToQuery(ctx)
// SELECT * FROM user WHERE id = ?
// [1]
builder.Wrap(
yiigo.Table("user"),
yiigo.Where("name = ? AND age > ?", "shenghui0779", 20),
).ToQuery(ctx)
// SELECT * FROM user WHERE name = ? AND age > ?
// [shenghui0779 20]
builder.Wrap(
yiigo.Table("user"),
yiigo.WhereIn("age IN (?)", []int{20, 30}),
).ToQuery(ctx)
// SELECT * FROM user WHERE age IN (?, ?)
// [20 30]
builder.Wrap(
yiigo.Table("user"),
yiigo.Select("id", "name", "age"),
yiigo.Where("id = ?", 1),
).ToQuery(ctx)
// SELECT id, name, age FROM user WHERE id = ?
// [1]
builder.Wrap(
yiigo.Table("user"),
yiigo.Distinct("name"),
yiigo.Where("id = ?", 1),
).ToQuery(ctx)
// 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(ctx)
// 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(ctx)
// 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(ctx)
// SELECT * FROM user WHERE age > ? ORDER BY age ASC, id DESC LIMIT ? OFFSET ?
// [20, 10, 5]
wrap1 := builder.Wrap(
Table("user_1"),
Where("id = ?", 2),
)
builder.Wrap(
Table("user_0"),
Where("id = ?", 1),
Union(wrap1),
).ToQuery(ctx)
// (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(ctx)
// (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(ctx)
// (SELECT * FROM user_0 WHERE age IN (?, ?) LIMIT ?) UNION (SELECT * FROM user_1 WHERE age IN (?, ?) LIMIT ?)
// [10, 20, 5, 30, 40, 5]
ctx := context.Background()
type User struct {
ID int `db:"-"`
Name string `db:"name"`
Age int `db:"age"`
Phone string `db:"phone,omitempty"`
}
builder.Wrap(Table("user")).ToInsert(ctx, &User{
Name: "yiigo",
Age: 29,
})
// INSERT INTO user (name, age) VALUES (?, ?)
// [yiigo 29]
builder.Wrap(yiigo.Table("user")).ToInsert(ctx, yiigo.X{
"name": "yiigo",
"age": 29,
})
// INSERT INTO user (name, age) VALUES (?, ?)
// [yiigo 29]
ctx := context.Background()
type User struct {
ID int `db:"-"`
Name string `db:"name"`
Age int `db:"age"`
Phone string `db:"phone,omitempty"`
}
builder.Wrap(Table("user")).ToBatchInsert(ctx, []*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(ctx, []yiigo.X{
{
"name": "shenghui0779",
"age": 20,
},
{
"name": "yiigo",
"age": 29,
},
})
// INSERT INTO user (name, age) VALUES (?, ?), (?, ?)
// [shenghui0779 20 yiigo 29]
ctx := context.Background()
type User struct {
Name string `db:"name"`
Age int `db:"age"`
Phone string `db:"phone,omitempty"`
}
builder.Wrap(
Table("user"),
Where("id = ?", 1),
).ToUpdate(ctx, &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(ctx, 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(ctx, yiigo.X{
"price": yiigo.Clause("price * ? + ?", 2, 100),
})
// UPDATE product SET price = price * ? + ? WHERE id = ?
// [2 100 1]
ctx := context.Background()
builder.Wrap(
yiigo.Table("user"),
yiigo.Where("id = ?", 1),
).ToDelete(ctx)
// DELETE FROM user WHERE id = ?
// [1]
builder.Wrap(Table("user")).ToTruncate(ctx)
// TRUNCATE user
Enjoy 😊