Golangå¾®æÂÂæ¡Âæ¶Kratosä¸Âå®ÂçÂÂå°Âä¼Â伴系堖 ORMæ¡Âæ¶ – GORM
ä»Âä¹Âæ¯ORMï¼Â
é¢åÂÂ对象ç¼Âç¨ÂÃ¥ÂÂ堳系åÂÂæ°æ®åºÂï¼Âé½æ¯ç®åÂÂæÂÂæµÂè¡ÂçÂÂæÂÂæ¯ï¼Âä½Âæ¯å®Â们çÂÂ模åÂÂæ¯ä¸Âä¸Âæ ·çÂÂãÂÂ
é¢åÂÂ对象ç¼Âç¨ÂæÂÂæÂÂæÂÂå®Âä½ÂçÂÂæÂÂ对象ï¼Âobjectï¼Âï¼Â堳系åÂÂæ°æ®åºÂÃ¥ÂÂæ¯éÂÂç¨å®Âä½Âä¹Âé´çÂÂ堳系ï¼Ârelationï¼Âè¿ÂæÂ¥æ°æ®ãÂÂå¾Âæ©就æÂÂ人æÂÂåºï¼Â堳系ä¹Âå¯以ç¨对象表达ï¼Âè¿Âæ ·çÂÂè¯Âï¼Âå°±è½使ç¨é¢åÂÂ对象ç¼Âç¨Âï¼ÂæÂ¥æÂÂä½Â堳系åÂÂæ°æ®åºÂãÂÂ
ç®ÂÃ¥ÂÂ说ï¼ÂORM å°±æ¯éÂÂè¿Âå®Âä¾Â对象çÂÂè¯Âæ³Âï¼Âå®ÂæÂÂ堳系åÂÂæ°æ®åºÂçÂÂæÂÂä½ÂçÂÂæÂÂæ¯ï¼Â比对象-堳系æ 尔ï¼ÂObject/Relational Mappingï¼ çÂÂ缩åÂÂãÂÂ
ORM æÂÂæ°æ®åºÂæ å°ÂæÂÂ对象ãÂÂ
- æ°æ®åºÂçÂÂ表ï¼Âtableï¼ –> ç±»ï¼Âclassï¼Â
- è®°å½Âï¼Ârecordï¼Âè¡Âæ°æ®6> 对象ï¼Âobjectï¼Â
- Ã¥ÂÂ段ï¼Âfield6> 对象çÂÂå±Âæ§ï¼Âattributeï¼Â
举ä¾Âæ¥说ï¼Âä¸Âé¢æ¯ä¸Âè¡ SQL è¯Âå¥ãÂÂ
SELECT id, first_name, last_name, phone, birth_date, sex
FROM persons
WHERE id = 10
ç¨ÂåºÂç´æÂ¥è¿Âè¡ SQLï¼ÂæÂÂä½Âæ°æ®åºÂçÂÂÃ¥ÂÂæ³Âå¦Âä¸ÂãÂÂ
res = db.execSql(sql);
name = res[0]["FIRST_NAME"];
æ¹æ ORM çÂÂÃ¥ÂÂæ³Âå¦Âä¸ÂãÂÂ
p = Person.get(10);
name = p.first_name;
ä¸Âæ¯Âè¾Âå°±å¯以åÂÂç°ï¼ÂORM 使ç¨对象ï¼Âå°Â裠äºÂæ°æ®åºÂæÂÂä½Âï¼Âå æ¤å¯以ä¸Â碰 SQL è¯Âè¨ÂãÂÂå¼ÂÃ¥ÂÂè åª使ç¨é¢åÂÂ对象ç¼Âç¨Âï¼Âä¸Âæ°æ®对象ç´æ¥交äºÂï¼Âä¸Âç¨堳å¿ÂåºÂå±Âæ°æ®åºÂãÂÂ
ORM æÂÂä¸Âé¢è¿ÂäºÂä¼Âç¹:
- æ°æ®模åÂÂé½å¨ä¸Â个å°æ¹å®Âä¹Âï¼Âæ´容æÂÂæ´æ°åÂÂç»´æ¤ï¼Âä¹Âå©äºÂéÂÂç¨代ç ÂãÂÂ
- ORM æÂÂç°æÂÂçÂÂ工堷ï¼Âå¾Âå¤ÂÃ¥ÂÂè½é½å¯以èªå¨å®ÂæÂÂï¼Âæ¯Âå¦Âæ°æ®æ¶Âæ¯ÂãÂÂé¢Âå¤ÂçÂÂãÂÂäºÂå¡çÂÂçÂÂãÂÂ
- å®Â迫使你使ç¨ MVC æ¶æÂÂï¼ÂORM å°±æ¯天ç¶ç Modelï¼ÂæÂÂç»Â使代ç Âæ´渠æ°ãÂÂ
- åº亠ORM çÂÂä¸Âå¡代ç Âæ¯Âè¾Âç®ÂÃ¥ÂÂï¼Â代ç ÂéÂÂå°Âï¼Âè¯Âä¹Âæ§好ï¼Â容æÂÂçÂÂ解ãÂÂ
- ä½ ä¸Âå¿ ç¼ÂÃ¥ÂÂæ§è½ä¸Âä½³ç SQLãÂÂ
ORM ä¹ÂæÂÂå¾ÂçªÂåºçÂÂ缺ç¹ï¼Â
- ORM åºÂä¸Âæ¯轻éÂÂ级工堷ï¼ÂéÂÂè¦Âè±å¾Âå¤Âç²¾åÂÂå¦习åÂÂ设置ãÂÂ
- 对äºÂå¤ÂæÂÂçÂÂæ¥询ï¼ÂORM è¦Âä¹Âæ¯æ æ³Â表达ï¼Âè¦Âä¹Âæ¯æ§è½ä¸Âå¦ÂÃ¥ÂÂçÂÂç SQLãÂÂ
- ORM æ½象æÂÂäºÂæ°æ®åºÂå±Âï¼Âå¼ÂÃ¥ÂÂè æ æ³ÂäºÂ解åºÂå±ÂçÂÂæ°æ®åºÂæÂÂä½Âï¼Âä¹Âæ æ³Âå®Âå¶ä¸ÂäºÂç¹æ®Âç SQLãÂÂ
ä»Âä¹Âæ¯GORMï¼Â
GORM æ¯åºäºÂGoè¯Âè¨Âå®Âç°çÂÂORMåºÂï¼Âå®Âæ¯Golangç®åÂÂæ¯Âè¾ÂçÂÂé¨çÂÂæ°æ®åºÂORMæÂÂä½ÂåºÂï¼Â对å¼ÂÃ¥ÂÂè ä¹Âæ¯Âè¾ÂÃ¥ÂÂ好ï¼Â使ç¨éÂÂ常æ¹便ç®ÂÃ¥ÂÂãÂÂ
æÂÂéÂÂè¦ÂçÂÂæ¯ï¼Âå®Âæ¯ä¸Â个æ£ç»ÂçÂÂå½产å¼ÂæºÂåºÂãÂÂæ¯æÂÂå½产ï¼Â
ç¹æ§
- å ¨åÂÂè½ ORM
- å ³è (Has Oneï¼ÂHas Manyï¼ÂBelongs Toï¼ÂMany To Manyï¼Âå¤ÂæÂÂï¼ÂÃ¥ÂÂ表继æ¿)
- Createï¼ÂSaveï¼ÂUpdateï¼ÂDeleteï¼ÂFind ä¸Âé©åÂÂæ¹æ³Â
- æ¯æ PreloadãÂÂJoins çÂÂé¢Âå 载
- äºÂå¡ï¼ÂåµÂå¥ÂäºÂå¡ï¼ÂSave Pointï¼ÂRollback To Saved Point
- ContextãÂÂé¢Âç¼Âè¯Â模å¼ÂãÂÂDryRun 模å¼Â
- æ¹éÂÂæÂÂå ¥ï¼ÂFindInBatchesï¼ÂFind/Create with Mapï¼Â使ç¨ SQL 表达å¼ÂãÂÂContext Valuer è¿Âè¡ CRUD
- SQL æÂÂ建å¨ï¼ÂUpsertï¼Âæ°æ®åºÂéÂÂï¼ÂOptimizer/Index/Comment Hintï¼Âå½åÂÂÃ¥ÂÂæ°ï¼ÂÃ¥ÂÂæ¥询
- å¤ÂÃ¥ÂÂ主é®ï¼Âç´¢å¼Âï¼Â约æÂÂ
- Auto Migration
- èªå®Âä¹ Logger
- çµ活çÂÂå¯æ©å±ÂæÂÂ件 APIï¼ÂDatabase Resolverï¼Âå¤Âæ°æ®åºÂï¼Â读åÂÂÃ¥ÂÂ离ï¼ÂãÂÂPrometheusâ¦
- æ¯Â个ç¹æ§é½ç»Âè¿ÂäºÂæµÂè¯ÂçÂÂéÂÂéÂÂèÂÂéªÂ
- å¼ÂÃ¥ÂÂè åÂÂ好
å®Â裠åºÂ
go get -u gorm.io/gorm
é¤æ¤以å¤Âï¼Âè¿ÂéÂÂè¦Âå®Â裠æ°æ®åºÂçÂÂ驱å¨ï¼Â
# å®Âè£Â
SQLite驱å¨
go get -u gorm.io/driver/sqlite
# å®Âè£Â
MySQL驱å¨
go get -u gorm.io/driver/mysql
# å®Âè£Â
PostgreSQL驱å¨
go get -u gorm.io/driver/postgres
# å®Âè£Â
SQL Server驱å¨
go get -u gorm.io/driver/sqlserver
# å®Âè£Â
Clickhouse驱å¨ï¼ÂClickhouseÃ¥Â
¼å®¹MySQLçÂÂÃ¥ÂÂè®®ï¼ÂæÂÂ以ç´æÂ¥ç¨MySQL驱å¨è¿ÂæÂ¥ä¹Âæ¯ä¸Âæ ·çÂÂï¼Â
go get -u gorm.io/driver/clickhouse
GORMçÂÂä¸ÂäºÂæ°æ®åºÂåºæ¾ÂÂä½Â
å 为æ°æ®åºÂæ¯å¤ÂæÂÂçÂÂï¼ÂSQLæ¯å¤ÂæÂÂçÂÂï¼Âå¤ÂæÂÂå°è½å¤Âåº好å æ¬书ï¼ÂæÂÂ以æ¯ç»Âä¸Âå¯è½å¨ç®ÂÃ¥ÂÂçÂÂç¯Âå¹ éÂÂé¢讲å®Âæ´ï¼Âåªè½å¤Âå°Â常ç¨çÂÂä¸ÂäºÂæÂÂä½Âï¼Âè¿ÂæÂ¥æ°æ®åºÂãÂÂCURDï¼Âæ¿æ¥举ä¾Â讲讲ãÂÂ
è¿ÂæÂ¥æ°æ®åºÂ
MySQL
import (
"gorm.io/gorm"
"gorm.io/driver/mysql"
)
dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
PostgreSQL
import (
"gorm.io/gorm"
"gorm.io/driver/postgres"
)
dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
SQLite
import (
"gorm.io/gorm"
"gorm.io/driver/sqlite"
)
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{})
SQL Server
import (
"gorm.io/gorm"
"gorm.io/driver/sqlserver"
)
dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"
db, err := gorm.Open(sqlserver.Open(dsn), &gorm.Config{})
Clickhouse
import (
"gorm.io/gorm"
"gorm.io/driver/clickhouse"
)
dsn := "tcp://localhost:9000?database=gorm&username=gorm&password=gorm&read_timeout=10&write_timeout=20"
db, err := gorm.Open(clickhouse.Open(dsn), &gorm.Config{})
èªå¨è¿Â移 Automatic Migration
db.AutoMigrate(&User{})
èªå¨è¿Â移åÂÂè½ï¼Âä¼ÂÃ¥ÂÂ建表ãÂÂ缺失çÂÂå¤Âé®ãÂÂ约æÂÂãÂÂÃ¥ÂÂÃ¥ÂÂç´¢å¼ÂãÂÂ
å®Âä¹Â模åÂÂ
type User struct {
gorm.Model
UserName string
NickName string
}
gorm.Model
Ã¥ÂÂæ¯åÂÂ
å«äºÂéÂÂç¨çÂÂä¸ÂäºÂÃ¥ÂÂ段ï¼Âæ¯Âå¦Âï¼ÂidãÂÂÃ¥ÂÂ建æ¶é´ãÂÂæ´æ°æ¶é´ãÂÂå é¤æ¶é´çÂÂâ¦â¦
// gorm.Model definition
type Model struct {
ID uint `gorm:"primaryKey"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt gorm.DeletedAt `gorm:"index"`
}
å¨é»Â认çÂÂæ åµä¸Âï¼Â
- 表åÂÂï¼Âå°Âä¼Â被转æ¢为 å¤Âæ°形张以å èÂÂå½¢å½åÂÂæ³Âï¼Âsnake_caseï¼Âï¼Âæ¯Âå¦Âï¼Â
User
转æ¢为users
ã - Ã¥ÂÂ段åÂÂï¼Âå°Â被转æ¢为 èÂÂå½¢å½åÂÂæ³Âï¼Âsnake_caseï¼ åÂÂ符串ï¼Âæ¯Âå¦Âï¼Â
UserName
被转æ¢为user_name
ãÂÂ
å½Âç¶ï¼Âä½ ä¹Âå¯以ç¨column
æ ÂæÂÂÃ¥ÂÂ段åÂÂçÂÂè¾Âåºï¼Â
type User struct {
gorm.Model
UserName string `gorm:"column:username"`
NickName string `gorm:"column:nickname"`
}
å®Âä¹ÂTableName()
æ¹æ³Âæ§å¶表åÂÂçÂÂè¾Âåº:
func (u User) TableName() string {
return "users"
}
墠Create
db.Create(&User{UserName: "TestUserName", NickName: "TestNickName"})
å Delete
// 软å é¤
// UPDATE users SET deleted_at="2020-03-13 10:23" WHERE id = user.id;
db.Delete(&user, 1)
db.Delete(&user)
// æ¹éÂÂ软å é¤
db.Where("age = ?", 20).Delete(&User{})
// ç©çÂÂå é¤
// DELETE FROM users WHERE id=10;
db.Unscoped().Delete(&user)
æ¹ Update
db.Model(&user).Update("nick_name", "NewNickName")
// Update - æ´æ°å¤Â个åÂÂ段
db.Model(&user).Updates(User{UserName: "NewUserName", NickName: "NewNickName"})
db.Model(&user).Updates(map[string]interface{}{"user_name": "NewUserName", "nick_name": "NewNickName"})
æÂÂ¥ Read
var user User
// è·åÂÂ第ä¸Âæ¡记å½Âï¼Â主é®åÂÂåºÂï¼Â
// SELECT * FROM users ORDER BY id LIMIT 1;
db.First(&user)
// æ ¹æ®æ´åÂÂ主é®æÂ¥æ¾
// SELECT * FROM users WHERE id = 10;
db.First(&user, 10)
db.First(&user, "10")
// æ ¹æ®主é®è·åÂÂè®°å½Âï¼Âå¦ÂæÂÂæ¯éÂÂæ´åÂÂ主é®
// SELECT * FROM users WHERE user_name = 'TestUserName';
db.First(&user, "user_name = ?", "TestUserName")
// SELECT * FROM users WHERE id IN (1,2,3);
db.Find(&users, []int{1,2,3})
// è·åÂÂä¸Âæ¡记å½Âï¼Â没æÂÂæÂÂå®ÂæÂÂåºÂÃ¥ÂÂ段
// SELECT * FROM users LIMIT 1;
db.Take(&user)
// è·åÂÂæÂÂÃ¥ÂÂä¸Âæ¡记å½Âï¼Â主é®éÂÂåºÂï¼Â
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
db.Last(&user)
ä¸ÂKratosæº起æÂÂæÂÂ¥
å®Âæ¹æ¨èÂÂçÂÂå ç»ÂæÂÂæ¯è¿Âæ ·çÂÂï¼Â
|- data
|- biz
|- service
|- server
é£ä¹Âï¼ÂæÂÂ们å¯以æÂÂ模åÂÂå®Âä¹ÂÃ¥ÂÂæÂÂä¸Â个packageï¼Âæ¾å°dataæÂÂ件夹ä¸Âé¢å»ï¼Â
|- data
| |- modal
|- biz
|- service
|- server
Ã¥ÂÂ建æ°æ®åºÂ客æ·端
å¨data/data.go
æÂÂ件ä¸Âæ·»å åÂÂ建Gormæ°æ®åºÂ客æ·端çÂÂæ¹æ³ÂNewGormClient
ï¼Â
import (
"gorm.io/driver/clickhouse"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/driver/sqlserver"
"gorm.io/gorm"
)
// Data .
type Data struct {
db *gorm.Client
}
// NewGormClient Ã¥ÂÂ建æ°æ®åºÂ客æ·端
func NewGormClient(cfg *conf.Bootstrap, logger log.Logger) *gorm.DB {
l := log.NewHelper(log.With(logger, "module", "ent/data/user-service"))
var driver gorm.Dialector
switch cfg.Data.Database.Driver {
default:
fallthrough
case "mysql":
driver = mysql.Open(cfg.Data.Database.Source)
break
case "postgres":
driver = postgres.Open(cfg.Data.Database.Source)
break
case "clickhouse":
driver = clickhouse.Open(cfg.Data.Database.Source)
break
case "sqlite":
driver = sqlite.Open(cfg.Data.Database.Source)
break
case "sqlserver":
driver = sqlserver.Open(cfg.Data.Database.Source)
break
}
client, err := gorm.Open(driver, &gorm.Config{})
if err != nil {
l.Fatalf("failed opening connection to db: %v", err)
}
// è¿Âè¡Âæ°æ®åºÂè¿Â移工åÂ
·
if cfg.Data.Database.Migrate {
if err := client.AutoMigrate(
&models.User{},
); err != nil {
l.Fatalf("failed creating schema resources: %v", err)
}
}
return client
}
并å°Âä¹Â注åÂ
¥å°ProviderSet
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(
NewGormClient,
...
)
éÂÂè¦Â说æÂÂçÂÂæ¯æ°æ®åºÂè¿Â移工堷ï¼Âå¦ÂæÂÂæ°æ®åºÂä¸Âä¸ÂÃ¥ÂÂå¨表ï¼Âè¿Â移工堷ä¼ÂÃ¥ÂÂ建ä¸Â个ï¼Âå¦ÂæÂÂÃ¥ÂÂ段åÂÂå¨æ¹åÂÂï¼Âè¿Â移工堷ä¼Â对åÂÂ段è¿Âè¡Âä¿®æ¹ãÂÂ
Ã¥ÂÂ建UseCase
å¨bizæÂÂ件夹ä¸ÂÃ¥ÂÂ建user.go
ï¼Â
package biz
type UserRepo interface {
ListUser(ctx context.Context, req *pagination.PagingRequest) (*v1.ListUserResponse, error)
GetUser(ctx context.Context, req *v1.GetUserRequest) (*v1.User, error)
CreateUser(ctx context.Context, req *v1.CreateUserRequest) (*v1.User, error)
UpdateUser(ctx context.Context, req *v1.UpdateUserRequest) (*v1.User, error)
DeleteUser(ctx context.Context, req *v1.DeleteUserRequest) (bool, error)
}
type UserUseCase struct {
repo UserRepo
log *log.Helper
}
func NewUserUseCase(repo UserRepo, logger log.Logger) *UserUseCase {
l := log.NewHelper(log.With(logger, "module", "user/usecase"))
return &UserUseCase{repo: repo, log: l}
}
func (uc *UserUseCase) ListUser(ctx context.Context, req *pagination.PagingRequest) (*v1.ListUserResponse, error) {
return uc.repo.ListUser(ctx, req)
}
func (uc *UserUseCase) GetUser(ctx context.Context, req *v1.GetUserRequest) (*v1.User, error) {
return uc.repo.GetUser(ctx, req)
}
func (uc *UserUseCase) CreateUser(ctx context.Context, req *v1.CreateUserRequest) (*v1.User, error) {
return uc.repo.CreateUser(ctx, req)
}
func (uc *UserUseCase) UpdateUser(ctx context.Context, req *v1.UpdateUserRequest) (*v1.User, error) {
return uc.repo.UpdateUser(ctx, req)
}
func (uc *UserUseCase) DeleteUser(ctx context.Context, req *v1.DeleteUserRequest) (bool, error) {
return uc.repo.DeleteUser(ctx, req)
}
注åÂ
¥å°biz.ProviderSet
package biz
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(
NewUserUseCase,
...
)
Ã¥ÂÂ建Repo
å¨data
æÂÂ件夹ä¸ÂÃ¥ÂÂ建user.go
æÂÂ件ï¼Âå®ÂéÂÂ
æÂÂä½Âæ°æ®åºÂçÂÂæÂÂä½Âé½å¨æ¤å¤ÂãÂÂ
package data
var _ biz.UserRepo = (*UserRepo)(nil)
type UserRepo struct {
data *Data
log *log.Helper
}
func NewUserRepo(data *Data, logger log.Logger) biz.UserRepo {
l := log.NewHelper(log.With(logger, "module", "User/repo"))
return &UserRepo{
data: data,
log: l,
}
}
func (r *UserRepo) convertModelToProto(in *models.User) *v1.User {
if in == nil {
return nil
}
return &v1.User{
Id: uint32(in.ID),
UserName: &in.UserName,
NickName: &in.NickName,
Password: &in.Password,
CreateTime: util.TimeToTimeString(&in.CreatedAt),
UpdateTime: util.TimeToTimeString(&in.UpdatedAt),
}
}
func (r *UserRepo) List(_ context.Context, req *pagination.PagingRequest) (*v1.ListUserResponse, error) {
var results []models.User
result := r.data.db.
Limit(int(req.GetPageSize())).
Offset(int(req.GetPageSize() * (req.GetPage() - 1))).
Find(&results)
if result.Error != nil {
return nil, result.Error
}
items := make([]*v1.User, 0, len(results))
for _, res := range results {
item := r.convertModelToProto(&res)
items = append(items, item)
}
var count int64
result = r.data.db.Model(&models.User{}).
Count(&count)
if result.Error != nil {
return nil, result.Error
}
return &v1.ListUserResponse{
Total: int32(count),
Items: items,
}, nil
}
func (r *UserRepo) Get(_ context.Context, req *v1.GetUserRequest) (*v1.User, error) {
res := &models.User{}
r.data.db.First(res, "id = ?", req.GetId())
return r.convertModelToProto(res), nil
}
func (r *UserRepo) Create(_ context.Context, req *v1.CreateUserRequest) (*v1.User, error) {
cryptoPassword, err := crypto.HashPassword(req.User.GetPassword())
if err != nil {
return nil, err
}
res := &models.User{
UserName: req.User.GetUserName(),
NickName: req.User.GetNickName(),
Password: cryptoPassword,
}
result := r.data.db.Create(res)
if result.Error != nil {
return nil, result.Error
}
return r.convertModelToProto(res), err
}
func (r *UserRepo) Update(_ context.Context, req *v1.UpdateUserRequest) (*v1.User, error) {
var cryptoPassword string
var err error
if req.User.Password != nil {
cryptoPassword, err = crypto.HashPassword(req.User.GetPassword())
if err != nil {
return nil, err
}
}
res := &models.User{
UserName: req.User.GetUserName(),
NickName: req.User.GetNickName(),
Password: cryptoPassword,
}
result := r.data.db.Model(res).Updates(res)
if result.Error != nil {
return nil, result.Error
}
return r.convertModelToProto(res), err
}
func (r *UserRepo) Delete(_ context.Context, req *v1.DeleteUserRequest) (bool, error) {
result := r.data.db.Delete(&models.User{}, req.GetId())
if result.Error != nil {
return false, result.Error
}
return true, nil
}
注åÂ
¥å°data.ProviderSet
package data
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(
NewUserRepo,
...
)
å¨Serviceä¸Âè°Âç¨
package service
type UserService struct {
v1.UnimplementedUserServiceServer
uc *biz.UserUseCase
log *log.Helper
}
func NewUserService(logger log.Logger, uc *biz.UserUseCase) *UserService {
l := log.NewHelper(log.With(logger, "module", "service/user"))
return &UserService{
log: l,
uc: uc,
}
}
// ListUser è·åÂÂç¨æ·åÂÂ表
func (s *UserService) ListUser(ctx context.Context, req *pagination.PagingRequest) (*v1.ListUserResponse, error) {
return s.uc.ListUser(ctx, req)
}
// GetUser è·åÂÂä¸Â个ç¨æ·
func (s *UserService) GetUser(ctx context.Context, req *v1.GetUserRequest) (*v1.User, error) {
return s.uc.GetUser(ctx, req)
}
// CreateUser Ã¥ÂÂ建ä¸Â个ç¨æ·
func (s *UserService) CreateUser(ctx context.Context, req *v1.CreateUserRequest) (*v1.User, error) {
return s.uc.CreateUser(ctx, req)
}
// UpdateUser æ´æ°ä¸Â个ç¨æ·
func (s *UserService) UpdateUser(ctx context.Context, req *v1.UpdateUserRequest) (*v1.User, error) {
return s.uc.UpdateUser(ctx, req)
}
// DeleteUser å é¤ä¸Â个ç¨æ·
func (s *UserService) DeleteUser(ctx context.Context, req *v1.DeleteUserRequest) (*emptypb.Empty, error) {
_, err := s.uc.DeleteUser(ctx, req)
if err != nil {
return nil, err
}
return &emptypb.Empty{}, nil
}
注åÂ
¥å°service.ProviderSet
package service
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(
NewUserService,
...
)
å°ÂæÂÂå¡注åÂÂå°gRPCæÂÂå¡å¨å½Âä¸Âå»ï¼Â
package server
// NewGRPCServer new a gRPC server.
func NewGRPCServer(cfg *conf.Bootstrap, logger log.Logger,
userSvc *service.UserService,
) *grpc.Server {
srv := bootstrap.CreateGrpcServer(cfg, logging.Server(logger))
userV1.RegisterUserServiceServer(srv, userSvc)
return srv
}
è¿Âæ ·ï¼ÂæÂÂ们就æÂÂäºÂä¸Â个å®Âæ´çÂÂç¨æ·æÂÂå¡
ãÂÂ