mirror of
https://gitee.com/johng/gf
synced 2026-06-28 10:16:09 +08:00
gconv包增加按照类型名称字符串进行类型转换,gutil增加MapToStruct方法,gjson/gparser改进ToStruct方法实现,gdb.Map类型增加ToStruct方法
This commit is contained in:
@ -13,6 +13,7 @@ import (
|
||||
"database/sql"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g/util/grand"
|
||||
"gitee.com/johng/gf/g/util/gutil"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
@ -201,10 +202,15 @@ func newDb (masterNode *ConfigNode, slaveNode *ConfigNode) (*Db, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 将Map变量映射到指定的struct对象中,注意参数应当是一个对象的指针
|
||||
func (m Map) ToStruct(obj interface{}) error {
|
||||
return gutil.MapToStruct(m, obj)
|
||||
}
|
||||
|
||||
// 将结果列表按照指定的字段值做map[string]Map
|
||||
func (list List) ToStringMap(key string) map[string]Map {
|
||||
func (l List) ToStringMap(key string) map[string]Map {
|
||||
m := make(map[string]Map)
|
||||
for _, item := range list {
|
||||
for _, item := range l {
|
||||
if v, ok := item[key]; ok {
|
||||
m[gconv.String(v)] = item
|
||||
}
|
||||
@ -213,9 +219,9 @@ func (list List) ToStringMap(key string) map[string]Map {
|
||||
}
|
||||
|
||||
// 将结果列表按照指定的字段值做map[int]Map
|
||||
func (list List) ToIntMap(key string) map[int]Map {
|
||||
func (l List) ToIntMap(key string) map[int]Map {
|
||||
m := make(map[int]Map)
|
||||
for _, item := range list {
|
||||
for _, item := range l {
|
||||
if v, ok := item[key]; ok {
|
||||
m[gconv.Int(v)] = item
|
||||
}
|
||||
@ -224,9 +230,9 @@ func (list List) ToIntMap(key string) map[int]Map {
|
||||
}
|
||||
|
||||
// 将结果列表按照指定的字段值做map[uint]Map
|
||||
func (list List) ToUintMap(key string) map[uint]Map {
|
||||
func (l List) ToUintMap(key string) map[uint]Map {
|
||||
m := make(map[uint]Map)
|
||||
for _, item := range list {
|
||||
for _, item := range l {
|
||||
if v, ok := item[key]; ok {
|
||||
m[gconv.Uint(v)] = item
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"encoding/json"
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"gitee.com/johng/gf/g/util/gutil"
|
||||
"gitee.com/johng/gf/g/encoding/gxml"
|
||||
"gitee.com/johng/gf/g/encoding/gyaml"
|
||||
"gitee.com/johng/gf/g/encoding/gtoml"
|
||||
@ -240,7 +241,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
value = j.convertValue(value)
|
||||
// 初始化判断
|
||||
if *j.p == nil {
|
||||
if isNumeric(array[0]) {
|
||||
if gutil.IsNumeric(array[0]) {
|
||||
*j.p = make([]interface{}, 0)
|
||||
} else {
|
||||
*j.p = make(map[string]interface{})
|
||||
@ -267,7 +268,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
goto done
|
||||
}
|
||||
// 创建新节点
|
||||
if isNumeric(array[i + 1]) {
|
||||
if gutil.IsNumeric(array[i + 1]) {
|
||||
// 创建array节点
|
||||
n, _ := strconv.Atoi(array[i + 1])
|
||||
var v interface{} = make([]interface{}, n + 1)
|
||||
@ -287,7 +288,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
|
||||
case []interface{}:
|
||||
// 键名与当前指针类型不符合,需要执行**覆盖操作**
|
||||
if !isNumeric(array[i]) {
|
||||
if !gutil.IsNumeric(array[i]) {
|
||||
if i == length - 1 {
|
||||
*pointer = map[string]interface{}{ array[i] : value }
|
||||
} else {
|
||||
@ -319,7 +320,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
j.setPointerWithValue(pointer, array[i], value)
|
||||
}
|
||||
} else {
|
||||
if isNumeric(array[i + 1]) {
|
||||
if gutil.IsNumeric(array[i + 1]) {
|
||||
n, _ := strconv.Atoi(array[i + 1])
|
||||
if len((*pointer).([]interface{})) > valn {
|
||||
(*pointer).([]interface{})[valn] = make([]interface{}, n + 1)
|
||||
@ -346,7 +347,7 @@ func (j *Json) setValue(pattern string, value interface{}, removed bool) error {
|
||||
if removed && value == nil {
|
||||
goto done
|
||||
}
|
||||
if isNumeric(array[i]) {
|
||||
if gutil.IsNumeric(array[i]) {
|
||||
n, _ := strconv.Atoi(array[i])
|
||||
s := make([]interface{}, n + 1)
|
||||
if i == length - 1 {
|
||||
@ -518,7 +519,7 @@ func (j *Json) checkPatternByPointer(key string, pointer *interface{}) *interfac
|
||||
return &v
|
||||
}
|
||||
case []interface{}:
|
||||
if isNumeric(key) {
|
||||
if gutil.IsNumeric(key) {
|
||||
n, err := strconv.Atoi(key)
|
||||
if err == nil && len((*pointer).([]interface{})) > n {
|
||||
return &(*pointer).([]interface{})[n]
|
||||
@ -584,12 +585,9 @@ func (j *Json) ToToml() ([]byte, error) {
|
||||
return gtoml.Encode(*(j.p))
|
||||
}
|
||||
|
||||
// 判断所给字符串是否为数字
|
||||
func isNumeric(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] < byte('0') || s[i] > byte('9') {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
// 转换为指定的struct对象
|
||||
func (j *Json) ToStruct(o interface{}) error {
|
||||
j.mu.RLock()
|
||||
defer j.mu.RUnlock()
|
||||
return gutil.MapToStruct(j.ToMap(), o)
|
||||
}
|
||||
@ -9,7 +9,6 @@ package gparser
|
||||
|
||||
import (
|
||||
"gitee.com/johng/gf/g/encoding/gjson"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
type Parser struct {
|
||||
@ -151,12 +150,8 @@ func (p *Parser) ToToml() ([]byte, error) {
|
||||
}
|
||||
|
||||
// 将变量解析为对应的struct对象,注意传递的参数为struct对象指针
|
||||
func (p *Parser) ToStruct(v interface{}) error {
|
||||
if c, e := p.ToJson(); e == nil {
|
||||
return json.Unmarshal(c, v)
|
||||
} else {
|
||||
return e
|
||||
}
|
||||
func (p *Parser) ToStruct(o interface{}) error {
|
||||
return p.json.ToStruct(o)
|
||||
}
|
||||
|
||||
func VarToXml(value interface{}, rootTag...string) ([]byte, error) {
|
||||
|
||||
@ -14,6 +14,29 @@ import (
|
||||
"gitee.com/johng/gf/g/encoding/gbinary"
|
||||
)
|
||||
|
||||
// 将变量i转换为字符串指定的类型t
|
||||
func Convert(i interface{}, t string) interface{} {
|
||||
switch t {
|
||||
case "int": return Int(i)
|
||||
case "int8": return Int8(i)
|
||||
case "int16": return Int16(i)
|
||||
case "int32": return Int32(i)
|
||||
case "int64": return Int64(i)
|
||||
case "uint": return Uint(i)
|
||||
case "uint8": return Uint8(i)
|
||||
case "uint16": return Uint16(i)
|
||||
case "uint32": return Uint32(i)
|
||||
case "uint64": return Uint64(i)
|
||||
case "float32": return Float32(i)
|
||||
case "float64": return Float64(i)
|
||||
case "bool": return Bool(i)
|
||||
case "string": return String(i)
|
||||
case "[]byte": return Bytes(i)
|
||||
default:
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
||||
func Bytes(i interface{}) []byte {
|
||||
if i == nil {
|
||||
return nil
|
||||
@ -233,3 +256,4 @@ func Float64 (i interface{}) float64 {
|
||||
return v
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -7,6 +7,33 @@
|
||||
// 其他工具包
|
||||
package gutil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
)
|
||||
|
||||
// 字符串首字母转换为大写
|
||||
func UcFirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
return s
|
||||
}
|
||||
if IsLetterLower(s[0]) {
|
||||
return string(s[0] - 32) + s[1 :]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// 字符串首字母转换为小写
|
||||
func LcFirst(s string) string {
|
||||
if len(s) == 0 {
|
||||
return s
|
||||
}
|
||||
if IsLetterUpper(s[0]) {
|
||||
return string(s[0] + 32) + s[1 :]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// 便利数组查找字符串索引位置,如果不存在则返回-1,使用完整遍历查找
|
||||
func StringSearch (a []string, s string) int {
|
||||
for i, v := range a {
|
||||
@ -47,3 +74,30 @@ func IsNumeric(s string) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// 将map键值对映射到对应的struct对象属性上,需要注意:
|
||||
// 1、第二个参数为struct对象指针;
|
||||
// 2、struct对象的公开属性才能被映射赋值;
|
||||
// 3、map中的键名可以为小写,映射转换时会自动将键名首字母转为大写做匹配映射,如果无法匹配则忽略;
|
||||
func MapToStruct(m map[string]interface{}, o interface{}) error {
|
||||
for k, v := range m {
|
||||
_MapToStructSetField(o, k, v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func _MapToStructSetField(obj interface{}, name string, value interface{}) {
|
||||
structValue := reflect.ValueOf(obj).Elem()
|
||||
structFieldValue := structValue.FieldByName(UcFirst(name))
|
||||
// 键名与对象属性匹配检测
|
||||
if !structFieldValue.IsValid() {
|
||||
//return fmt.Errorf("No such field: %s in obj", name)
|
||||
return
|
||||
}
|
||||
// CanSet的属性必须为公开属性(首字母大写)
|
||||
if !structFieldValue.CanSet() {
|
||||
//return fmt.Errorf("Cannot set %s field value", name)
|
||||
return
|
||||
}
|
||||
// 必须将value转换为struct属性的数据类型,这里必须用到gconv包
|
||||
structFieldValue.Set(reflect.ValueOf(gconv.Convert(value, structFieldValue.Type().String())))
|
||||
}
|
||||
@ -445,29 +445,39 @@ func keepPing() {
|
||||
}
|
||||
}
|
||||
|
||||
// 数据库单例测试,在mysql中使用 show full processlist 查看链接信息
|
||||
func instance() {
|
||||
fmt.Println("instance:")
|
||||
db1, _ := gdb.New()
|
||||
db2, _ := gdb.New()
|
||||
db3, _ := gdb.New()
|
||||
for {
|
||||
fmt.Println("ping...")
|
||||
db1.PingMaster()
|
||||
db1.PingSlave()
|
||||
db2.PingMaster()
|
||||
db2.PingSlave()
|
||||
db3.PingMaster()
|
||||
db3.PingSlave()
|
||||
time.Sleep(1*time.Second)
|
||||
// like语句查询
|
||||
func likeQuery() {
|
||||
fmt.Println("likeQuery:")
|
||||
if r, err := db.Table("user").Where("name like ?", "%john%").Select(); err == nil {
|
||||
fmt.Println(r)
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// mapToStruct
|
||||
func mapToStruct() {
|
||||
type User struct {
|
||||
Uid int
|
||||
Name string
|
||||
}
|
||||
fmt.Println("mapToStruct:")
|
||||
if r, err := db.Table("user").Where("uid=?", 1).One(); err == nil {
|
||||
u := User{}
|
||||
if err := r.ToStruct(&u); err == nil {
|
||||
fmt.Println(r)
|
||||
fmt.Println(u)
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
r, e := db.Table("user").Where("name like ?", "%john%").Select()
|
||||
fmt.Println(e)
|
||||
fmt.Println(r)
|
||||
mapToStruct()
|
||||
//create()
|
||||
//create()
|
||||
//insert()
|
||||
|
||||
@ -6,7 +6,7 @@ database:
|
||||
- host: 127.0.0.1
|
||||
port: 3306
|
||||
user: root
|
||||
pass: "123456"
|
||||
pass: "8692651"
|
||||
name: test
|
||||
type: mysql
|
||||
role: master
|
||||
@ -15,7 +15,7 @@ database:
|
||||
- host: 127.0.0.1
|
||||
port: 3306
|
||||
user: root
|
||||
pass: "123456"
|
||||
pass: "8692651"
|
||||
name: test
|
||||
type: mysql
|
||||
role: master
|
||||
|
||||
@ -13,7 +13,7 @@ type gtInterface interface {
|
||||
|
||||
type st struct {
|
||||
age int
|
||||
name string
|
||||
Name string
|
||||
}
|
||||
|
||||
type mySt struct {
|
||||
@ -53,7 +53,7 @@ func main() {
|
||||
//// 我们需要调用的是实体结构体指针的方法,注意v2与v2的区别,以及方法定义的区别
|
||||
//v2.MethodByName("Echo2").Call([]reflect.Value{p})
|
||||
//v.MethodByName()
|
||||
fmt.Println(v.Type())
|
||||
fmt.Println(v.FieldByName("name"))
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2,11 +2,10 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"gitee.com/johng/gf/g/util/gutil"
|
||||
)
|
||||
|
||||
func main() {
|
||||
for i := 0; i < 100; i++ {
|
||||
fmt.Println(rand.Intn(200))
|
||||
}
|
||||
fmt.Println(gutil.LcFirst("ABC"))
|
||||
fmt.Println(gutil.UcFirst("abc"))
|
||||
}
|
||||
Reference in New Issue
Block a user