Go语言开发基于SQLite数据库实现用户表新增接口(二)

背景

上一章
Go语言开发基于SQLite数据库实现用户表增删改查项目搭建(一)
这一章我们实现用户表的添加

代码实现

mapper层

type UserMapper interface {
	Insert(user *model.User) error
	}
	
type userMapper struct {
}

func (m *userMapper) Insert(u *model.User) error {
	return model.Insert(u)
}

ModelTable实现

func Insert(model interface{}) error {
	// 获取具体类型的表名
	tableName := model.(*User).TableName()

	// 使用反射获取 model 类型的字段信息
	val := reflect.ValueOf(model).Elem()
	typ := val.Type()

	// 构建 INSERT 语句的字段名和占位符部分
	var columns []string
	var placeholders []string
	var values []interface{}

	for i := 0; i < typ.NumField(); i++ {
		field := typ.Field(i)
		// 过滤掉 ModelTable 这样的嵌入结构体字段(如果有的话)
		if field.Name == "ModelTable" {
			continue
		}

		// 获取 db 标签
		dbTag := field.Tag.Get("db")
		if dbTag == "" {
			// 如果没有 db 标签,跳过该字段
			continue
		}

		// 添加字段名、占位符和字段值
		columns = append(columns, dbTag)
		placeholders = append(placeholders, "?")
		values = append(values, val.Field(i).Interface()) // 获取字段的值
	}

	// 构建最终的 INSERT SQL 语句
	insertSQL := fmt.Sprintf(
		"INSERT INTO %s (%s) VALUES (%s)",
		tableName,
		strings.Join(columns, ", "),      // 用逗号连接字段名
		strings.Join(placeholders, ", "), // 用逗号连接占位符
	)

	// 执行插入操作
	_, err := config.Db.Exec(insertSQL, values...)
	if err != nil {
		return err
	}

	return nil
}

这里我们映射的结构体中的对应db字段 , 这样的好处是我们这个方法是基础方法,其他结构体中只要有ModelTable结构体,我们就可以直接继续使用了。
在这里插入图片描述

service层

type UserService interface {
	Insert(user *model.User) error
	}

service实现层

type UserServiceImpl struct {
	m mapper.UserMapper
}

func (u UserServiceImpl) Insert(user *model.User) error {
	return u.m.Insert(user)
}

controller层

type UserController struct {
	UserService service.UserService
}

func (u *UserController) Insert(rc *req.Ctx) {
	user := new(model.User)
	req.BindJsonAndValid(rc.GinCtx, user)
	assert.IsTrue(user.Username != "" && user.PassWord != "", "账号密码为必传")
	//不加密
	//user.PassWord = utils.PwdHash(user.PassWord)
	err := u.UserService.Insert(user)
	assert.IsNil(err)
}

调用

这里我们在新增加一个application,将service初始化出来

var (
	UserService service.UserService = imp.NewUserService()
)

func GetUserService() service.UserService {
	return UserService
}

然后在路由那,进行对应的调用就可以了。

我们封装了下HandlerFunc

type HandlerFunc func(*Ctx)

type Ctx struct {
	GinCtx *gin.Context // gin context

	ReqParam any               // 请求参数,主要用于记录日志
	ResData  any               // 响应结果
	ResHead  map[string]string // 响应头
	Err      any               // 请求错误

	timed int64 // 执行时间
	NoRes bool  // 无需返回结果,即文件下载等
}

func (rc *Ctx) Handle(handler HandlerFunc) {
	ginCtx := rc.GinCtx
	defer func() {
		if err := recover(); err != nil {
			rc.Err = err
			ErrorRes(ginCtx, err)
		}
		// 应用所有请求后置处理器
		ApplyHandlerInterceptor(afterHandlers, rc)
	}()
	assert.IsTrue(ginCtx != nil, "ginContext == nil")

	// 默认为不记录请求参数,可在handler回调函数中覆盖赋值
	rc.ReqParam = nil
	// 默认响应结果为nil,可在handler中赋值
	rc.ResData = nil

	if rc.ResHead != nil {
		for key, value := range rc.ResHead {
			ginCtx.Header(key, value)
		}

	}
	// 调用请求前所有处理器
	err := ApplyHandlerInterceptor(beforeHandlers, rc)
	if err != nil {
		panic(err)
	}

	begin := time.Now()
	handler(rc)
	rc.timed = time.Since(begin).Milliseconds()
	if !rc.NoRes {
		SuccessRes(ginCtx, rc.ResData)
	}
}

func (rc *Ctx) Download(reader io.Reader, filename string) {
	rc.NoRes = true
	Download(rc.GinCtx, reader, filename)
}

func NewCtxWithGin(g *gin.Context) *Ctx {
	return &Ctx{GinCtx: g}
}

// 处理器拦截器函数
type HandlerInterceptorFunc func(*Ctx) error
type HandlerInterceptors []HandlerInterceptorFunc

var (
	beforeHandlers HandlerInterceptors
	afterHandlers  HandlerInterceptors
)

// 使用前置处理器函数
func UseBeforeHandlerInterceptor(b HandlerInterceptorFunc) {
	beforeHandlers = append(beforeHandlers, b)
}

// 使用后置处理器函数
func UseAfterHandlerInterceptor(b HandlerInterceptorFunc) {
	afterHandlers = append(afterHandlers, b)
}

// 应用指定处理器拦截器,如果有一个错误则直接返回错误
func ApplyHandlerInterceptor(his HandlerInterceptors, rc *Ctx) interface{} {
	for _, handler := range his {
		if err := handler(rc); err != nil {
			return err
		}
	}
	return nil
}

在这里插入图片描述

测试

在这里插入图片描述
我们在进行一个查询列表,就可以查询出对应的数据了(后续会写)
在这里插入图片描述

源码地址

使用Go语言开发基于SQLite数据库实现用户表相关接口项目示例,可进行扩展,拿来即用

参考

代码风格参考的mayfly-go ,SQLite这块是自己实现的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一枚开发小咸鱼

原创不宜,请作者喝杯咖啡吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值