Go语言开发基于SQLite数据库实现用户表查询详情接口(三)

背景

上一章
Go语言开发基于SQLite数据库实现用户表新增接口(二)
这一章我们实现用户表的查询详情接口

代码实现

mapper层

type UserMapper interface {
	GetById(id uint64) (*model.User, error)
	}
	
type userMapper struct {
}

func (m *userMapper) GetById(id uint64) (*model.User, error) {
	// 创建 model.User 的指针实例
	user := &model.User{}
	result, err := model.GetById(user.TableName(), id, user)
	if err != nil {
		return nil, err
	}

	// 确保返回的结果是 *model.User 类型
	user, ok := result.(*model.User)
	if !ok {
		return nil, fmt.Errorf("expected *model.User, but got %T", result)
	}
	return user, nil
}

ModelTable实现

func GetById(tableName string, id uint64, dest interface{}) (interface{}, error) {
	// 确保 dest 是指针类型
	val := reflect.ValueOf(dest)
	if val.Kind() != reflect.Ptr || val.IsNil() {
		return nil, fmt.Errorf("dest must be a non-nil pointer")
	}

	// 构造 SQL 查询
	query := fmt.Sprintf("SELECT * FROM %s WHERE id = ? LIMIT 1", tableName)

	// 执行查询
	row := config.Db.QueryRow(query, id)

	// 获取结构体的字段
	fieldPointers, err := getFieldPointers(reflect.TypeOf(dest).Elem(), reflect.ValueOf(dest).Elem())
	if err != nil {
		return nil, err
	}

	// 使用 Scan 将查询结果映射到结构体
	err = row.Scan(fieldPointers...)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, fmt.Errorf("No rows found with id %d", id)
		}
		return nil, err
	}

	return dest, nil
}

// 递归地获取结构体字段的指针(支持嵌套结构体)
func getFieldPointers(t reflect.Type, v reflect.Value) ([]interface{}, error) {
	var fieldPointers []interface{}

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		fieldValue := v.Field(i)

		// 如果字段是结构体类型,递归进入
		if fieldValue.Kind() == reflect.Struct {
			// 递归处理嵌套的结构体字段
			nestedPointers, err := getFieldPointers(field.Type, fieldValue)
			if err != nil {
				return nil, err
			}
			fieldPointers = append(fieldPointers, nestedPointers...)
		} else {
			// 否则将字段的指针添加到字段指针数组
			fieldPointers = append(fieldPointers, fieldValue.Addr().Interface())
		}
	}

	return fieldPointers, nil
}

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

service层

type UserService interface {
	GetById(id uint64) (*model.User, error)
	}

service实现层

type UserServiceImpl struct {
	m mapper.UserMapper
}


func (u UserServiceImpl) GetById(id uint64) (*model.User, error) {
	return u.m.GetById(id)
}

controller层

type UserController struct {
	UserService service.UserService
}

func (u *UserController) GetById(rc *req.Ctx) {
	id := uint64(req.PathParamInt(rc.GinCtx, "id"))
	user, err := u.UserService.GetById(id)
	assert.IsNil(err)
	rc.ResData = user
}

这里有个PathParamInt方法 获取路径上面的参数

func PathParamInt(g *gin.Context, pm string) int {
	value, _ := strconv.Atoi(g.Param(pm))
	return value
}

接口

在这里插入图片描述

测试

在这里插入图片描述

源码地址

使用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、付费专栏及课程。

余额充值