drd99007 2015-09-08 03:10
浏览 25

如何在SQL扫描功能中传递对结构属性的引用列表以使过程自动化?

I have a struct of this form which I add methods too.

type User struct {
    Id           int64
    Email        string
    Username     string
    GeonameId    int64
    Birthdate    string
    Hash         string
    ActiveImage  string
    About        string
    Verified     bool
    Notification bool
    Joined       int64
    LastActivity int64
    Ipv4         int64
    Deleted      bool
}

But everytime I do a query I am manually assigning the results of that query to these properties which is not very DRY. Every time I add a new column in the database I have to change alot of lines of code manually, which is not very desireable.

The kind of methods I have:

func ByEmail(email string) (*User, error) {

    query := `
        SELECT *
        FROM user
        WHERE
            email = ? AND
            deleted = 0
        LIMIT 1;
    `

    user := &User{}
    err := sql.DB.QueryRow(query, email).Scan(
        &user.Id,
        &user.Email,
        &user.Username,
        &user.GeonameId,
        &user.Birthdate,
        &user.Hash,
        &user.ActiveImage,
        &user.About,
        &user.Verified,
        &user.Notification,
        &user.Joined,
        &user.LastActivity,
        &user.Ipv4,
        &user.Deleted,
    )
    if err != nil {
        return nil, err
    }

    return user, nil
}

When creating a new row in the database:

func (u *User) Create() error {

    if u.Id != 0 {
        return fmt.Errorf("User.Create: Struct already has an Id.")
    }

    query := `
        INSERT INTO user
        SET
            email = ?,
            username = ?,
            geonameid = ?,
            birthdate = ?,
            hash = ?,
            active_image = ?,
            about = ?,
            verified = ?,
            notification = ?,           
            joined = ?,
            lastactivity = ?,
            ipv4 = ?,
            deleted = ?;
    `

    stmt, err := sql.DB.Prepare(query)
    if err != nil {
        return err
    }

    res, err := stmt.Exec(
        u.Email,
        u.Username,
        u.GeonameId,
        u.Birthdate,
        u.Hash,
        u.ActiveImage,
        u.About,
        u.Verified,
        u.Notification,
        u.Joined,
        u.LastActivity,
        u.Ipv4,
        u.Deleted,
    )
    if err != nil {
        return err
    }

    lastId, err := res.LastInsertId()
    if err != nil {
        return err
    }

    u.Id = lastId

    return nil
}

I have looked at some examples of reflection usage but I still don't quite grasp it. And I don't know how to do it in a simple way.

How can I automate the process of this by sending in a slice of pointers of reference to the struct properties or something similar in the Scan() and Exec() functions below to automate this process?

EDIT:

I tried to get reference to the structs properties by doing this:

user, _ := user.ById(1)
val := reflect.ValueOf(user).Elem()

fmt.Println(&user.Id)
fmt.Println(val.Field(0).Pointer())

But it panicced and gave me this error:

panic: reflect: call of reflect.Value.Pointer on int64 Value
  • 写回答

1条回答 默认 最新

  • douzhonglong3789 2015-09-08 06:25
    关注

    My suggestion, to use a ORM package.

    For your panic, refer to golang document:

    It panics if v's Kind is not Chan, Func, Map, Ptr, Slice, or UnsafePointer.

    Here is a properties copier example using reflection.

    func CopyField(dst interface{}, src interface{}) {
    dstVal := reflect.ValueOf(dst).Elem()
    srcVal := reflect.ValueOf(src).Elem()
    
    for i := 0; i < srcVal.NumField(); i++ {
        n := srcVal.Type().Field(i).Name
        dstField := dstVal.FieldByName(n)
        if dstField.IsValid() {
            dstField.Set(srcVal.Field(i))
        }
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 matlab答疑 关于海上风电的爬坡事件检测
  • ¥88 python部署量化回测异常问题
  • ¥30 酬劳2w元求合作写文章
  • ¥15 在现有系统基础上增加功能
  • ¥15 远程桌面文档内容复制粘贴,格式会变化
  • ¥15 关于#java#的问题:找一份能快速看完mooc视频的代码
  • ¥15 这种微信登录授权 谁可以做啊
  • ¥15 请问我该如何添加自己的数据去运行蚁群算法代码
  • ¥20 用HslCommunication 连接欧姆龙 plc有时会连接失败。报异常为“未知错误”
  • ¥15 网络设备配置与管理这个该怎么弄