orm初探

elvin5發表於2017-03-20

只是研究一下orm是怎麼事情而已矣

package main

import (
    "database/sql"
    "fmt"
    "log"
    "reflect"
    "strconv"

    _ "github.com/go-sql-driver/mysql"
)

var db *sql.DB

func init() {
    log.SetFlags(log.Lshortfile)
    var err error
    db, err = sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/test?charset=utf8mb4")
    if nil != err {
        log.Fatal(err)
    }

    db.SetMaxOpenConns(150)
    db.SetMaxIdleConns(100)
    err = db.Ping()
    if nil != err {
        log.Fatal(err)
    }
}

func main() {
    res, err := Query()
    if nil != err {
        log.Println(err)
        return
    }
    var t T2
    err = GetOne(res[0], &t)
    if nil != err {
        log.Println(err)
        return
    }
    log.Printf("%+v",t)
}

type T2 struct {
    Id        int    `json:"id" db:"id"`
    Name      string `json:"name" db:"name"`
    Ct        string `json:"ct" db:"ct"`
    UpdatedAt string `json:"updated_at" db:"updated_at"`
    Bt        byte   `json:"bt" db:"bt"`
}

func Query() ([]map[string]string, error) {
    rows, err := db.Query("SELECT * FROM t2")
    if nil != err {
        log.Println(err)
        return nil, err
    }

    columns, _ := rows.Columns()
    scanArgs := make([]interface{}, len(columns))
    values := make([]interface{}, len(columns))
    for j := range values {
        scanArgs[j] = &values[j]
    }

    record := make([]map[string]string, 0)
    for rows.Next() {
        //將行資料儲存到record字典
        err = rows.Scan(scanArgs...)
        m := map[string]string{}
        for i, col := range values {
            if col != nil {
                m[columns[i]] = string(col.([]byte))
            }
        }

        record = append(record, m)
    }

    fmt.Printf("%+v\n", record)

    return record, nil
}

func GetOne(m map[string]string, v interface{}) error {
    tp := reflect.TypeOf(v)
    val := reflect.ValueOf(v)

    length := tp.Elem().NumField()
    for i := 0; i < length; i++ {
        dbTag := tp.Elem().Field(i).Tag.Get("db")
        if "" == dbTag || "-" == dbTag {
            continue
        }

        val2, ok := m[dbTag]
        if !ok {
            continue
        }

        switch tp.Elem().Field(i).Type.Kind() {
        case reflect.String:
            val.Elem().Field(i).SetString(val2)
        case reflect.Int, reflect.Int32, reflect.Int64, reflect.Int16:
            val3, err := strconv.ParseInt(val2, 10, 64)
            if nil != err {
                log.Println(err)
                continue
            }
            val.Elem().Field(i).SetInt(val3)
        case reflect.Float32, reflect.Float64:
        case reflect.Bool:
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
        default:
        }
    }

    return nil
}