• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

go-kratosv2+gorm实现增删改查demo

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

由于正在学习Bilibili的go开源框架 go-kratos,简单学习的过程中有一些摸索过程,现在根据go-kratos v2 + gorm 实现增删改查demo实现用户的增删改查

mysql用户表

#sql

CREATE TABLE `user` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` char(20) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '名称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用户表';

项目初始化

0.文档地址

1.创建项目模板

kratos new user

cd user

2.拉取项目依赖

go mod download

3.生成proto模板

kratos proto add api/user/user.proto

这个时候我们去修改api/user/user.proto, 先仅仅实现用户新增功能,代码如下

syntax = "proto3";

package api.user.v1;

option go_package = "users/api/user/v1;v1";
option java_multiple_files = true;
option java_package = "api.user.v1";

import "google/api/annotations.proto";
// the validate rules:
// https://github.com/envoyproxy/protoc-gen-validate
import "validate/validate.proto";

service user {
  
    // 用户创建
    rpc CreateUser(CreateUserRequest) returns (CreateUserReply){
        option (google.api.http) = {
            post: "/v1/user"
            body: "*"
        };
    }


message User {
    int64 id = 1;
    string name = 2;
}

message CreateUserRequest {
    string name = 1 [(validate.rules).string = {min_len : 5, max_len: 50}];
}

message CreateUserReply {
    User User = 1;
}

proro文件中有参数校验,使用 proto-gen-validate 文档地址

4.生成proto源码 文档地址

kratos proto client api/user/user.proto

5.生成server模板

kratos proto server api/user/user.proto -t internal/service

coding阶段

打开 internal/service/user.go,代码如下:

package service

import (
	"context"
	"github.com/go-kratos/kratos/v2/log"
	"users/internal/biz"

	pb "users/api/user/v1"
)

type UserService struct {
	pb.UnimplementedUserServer
	uc *biz.UserUseCase
	log *log.Helper
}

func NewUserService(uc *biz.UserUseCase, logger log.Logger) *UserService {
	return &UserService{uc:uc, log: log.NewHelper(logger)}
}

// 用户创建
func (s *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserReply, error) {
	s.log.WithContext(ctx).Infof("CreateUser Received: %v", req)
	user := biz.User{
		Id:   0,
		Name: req.Name,
	}
	return &pb.CreateUserReply{}, s.uc.Create(ctx, &user)
}

打开 internal/service/service.go,代码如下:

package service

import "github.com/google/wire"

// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewUserService)

代码中引入了biz.User, 建立 ./internal/biz/user.go

package biz

import (
	"context"
	"github.com/go-kratos/kratos/v2/log"
)

type User struct {
	Id int64
	Name string
}

type UserRepo interface{
	CreateUser(ctx context.Context, user *User) error
}

type UserUseCase struct{
	repo UserRepo
	log *log.Helper
}

func NewUserUseCase(repo UserRepo, logger log.Logger) *UserUseCase {
	return &UserUseCase{repo:repo, log: log.NewHelper(logger)}
}
// 创建
func (uc *UserUseCase) Create(ctx context.Context, user *User) error {
	return uc.repo.CreateUser(ctx, user)
}

修改 ./internal/biz/biz.go

package biz

import "github.com/google/wire"

// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewUserUseCase)

打开 ./internal/data/data.go

package data

import (
	"users/internal/conf"

	"github.com/go-kratos/kratos/v2/log"
	"github.com/google/wire"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewUserRepo)

// Data .
type Data struct {
	db *gorm.DB
}

// NewData .
func NewData(conf *conf.Data, logger log.Logger) (*Data, func(), error) {
	log :=  log.NewHelper(logger)
	// mysql数据库连接
	db, err := gorm.Open(mysql.Open(conf.Database.Source), &gorm.Config{});
	if err != nil {
		return nil, nil, err
	}

	d := &Data{
		db: db,
	}

	return d, func() {
		log.Info("message", "closing the data resources")
	}, nil
}

建立 ./internal/data/user.go

package data

import (
	"context"
	"errors"
	"github.com/go-kratos/kratos/v2/log"
	"gorm.io/gorm"
	"users/internal/biz"
	"users/internal/data/model"
)

type userRepo struct {
	data *Data
	log  *log.Helper
}


func (u userRepo) CreateUser(ctx context.Context, user *biz.User) error {
	// 判断名称是否存在,存在则返回错误
	record := u.GetUserByName(user.Name)
	if record.Id != 0 {
		return errors.New("用户名已存在")
	}
	return u.data.db.Model(&model.User{}).Create(&model.User{
		Id:   0,
		Name: user.Name,
	}).Error
}

func NewUserRepo(data *Data, logger log.Logger) biz.UserRepo {
	return &userRepo{
		data: data,
		log:  log.NewHelper(logger),
	}
}


建立 ./internal/data/model/user.go

package model

type User struct{
	Id int64 `json:"id"`
	Name string `json:"name"`
}


func (User) TableName() string {
	return "user"
}

修改./internal/server/http.go

package server

import (
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/logging"
	"github.com/go-kratos/kratos/v2/middleware/metrics"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/go-kratos/kratos/v2/middleware/validate"
	"github.com/go-kratos/kratos/v2/transport/http"

	v1 "users/api/user/v1"
	"users/internal/conf"
	"users/internal/service"
)

// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, user *service.UserService, logger log.Logger) *http.Server {
	var opts = []http.ServerOption{
		http.Middleware(
			recovery.Recovery(),
			tracing.Server(),
			logging.Server(logger),
			metrics.Server(),
			validate.Validator(),
		),
	}
	if c.Http.Network != "" {
		opts = append(opts, http.Network(c.Http.Network))
	}
	if c.Http.Addr != "" {
		opts = append(opts, http.Address(c.Http.Addr))
	}
	if c.Http.Timeout != nil {
		opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))
	}
	srv := http.NewServer(opts...)
	v1.RegisterUserHTTPServer(srv, user)
	return srv
}

修改./internal/server/grpc.go

package server

import (
	"github.com/go-kratos/kratos/v2/log"
	"github.com/go-kratos/kratos/v2/middleware/logging"
	"github.com/go-kratos/kratos/v2/middleware/metrics"
	"github.com/go-kratos/kratos/v2/middleware/recovery"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/go-kratos/kratos/v2/middleware/validate"
	"github.com/go-kratos/kratos/v2/transport/grpc"

	v1 "users/api/user/v1"
	"users/internal/conf"
	"users/internal/service"
)

// NewGRPCServer new a gRPC server.
func NewGRPCServer(c *conf.Server, user *service.UserService, logger log.Logger) *grpc.Server {
	var opts = []grpc.ServerOption{
		grpc.Middleware(
			recovery.Recovery(),
			tracing.Server(),
			logging.Server(logger),
			metrics.Server(),
			validate.Validator(),
		),
	}
	if c.Grpc.Network != "" {
		opts = append(opts, grpc.Network(c.Grpc.Network))
	}
	if c.Grpc.Addr != "" {
		opts = append(opts, grpc.Address(c.Grpc.Addr))
	}
	if c.Grpc.Timeout != nil {
		opts = append(opts, grpc.Timeout(c.Grpc.Timeout.AsDuration()))
	}
	srv := grpc.NewServer(opts...)
	v1.RegisterUserServer(srv, user)
	return srv
}

修改配置文件

打开 ./configs/config.yaml,修改成自己的数据库

server:
  http:
    addr: 0.0.0.0:8000
    timeout: 1s
  grpc:
    addr: 0.0.0.0:9000
    timeout: 1s
data:
  database:
    driver: mysql
    source: root: root@tcp(127.0.0.1:3306)/kratos_user?charset=utf8&parseTime=True&loc=Local
  redis:
    addr: 127.0.0.1:6379
    read_timeout: 0.2s
    write_timeout: 0.2s

项目编译

生成所有proto源码、wire等等

go generate ./...

运行项目

kratos run

发起请求 (postman)

POST localhost:8000/v1/user

{
    "name":"周周周周周"
}

以上是单个http接口请求,完整的增删改查自行下载

链接: https://pan.baidu.com/s/1mfUGAFr4YA3GtQUJ9Gd6TQ  密码: 2cma

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
go & flag发布时间:2022-07-10
下一篇:
使用goprotoc--go_out输出的*.pb.go文件时报undefined:proto.ProtoPackageIsVersion3 ...发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap