improve model feature

This commit is contained in:
John
2019-08-30 20:29:12 +08:00
parent a31108e753
commit ee89a06b3e
17 changed files with 232 additions and 53 deletions

View File

@ -14,6 +14,8 @@ import (
"strings"
"time"
"github.com/gogf/gf/internal/structs"
"github.com/gogf/gf/text/gregex"
"github.com/gogf/gf/text/gstr"
"github.com/gogf/gf/util/gconv"
@ -24,6 +26,38 @@ type apiString interface {
String() string
}
const (
OrmTagForStruct = "orm"
OrmTagForUnique = "unique"
OrmTagForPrimary = "primary"
)
// 获得struct对象对应的where查询条件
func GetWhereConditionOfStruct(pointer interface{}) (where string, args []interface{}) {
array := ([]string)(nil)
for tag, field := range structs.TagMapField(pointer, []string{OrmTagForStruct}, true) {
array = strings.Split(tag, ",")
if len(array) > 1 && gstr.InArray([]string{OrmTagForUnique, OrmTagForPrimary}, array[1]) {
return array[0], []interface{}{field.Value()}
}
if len(where) > 0 {
where += " "
}
where += tag + "=?"
args = append(args, field.Value())
}
return
}
// 获得orm标签与属性的映射关系
func GetOrmMappingOfStruct(pointer interface{}) map[string]string {
mapping := make(map[string]string)
for tag, attr := range structs.TagMapName(pointer, []string{OrmTagForStruct}, true) {
mapping[strings.Split(tag, ",")[0]] = attr
}
return mapping
}
// 格式化SQL语句.
func formatQuery(query string, args []interface{}) (newQuery string, newArgs []interface{}) {
return handlerSliceArguments(query, args)
@ -138,7 +172,7 @@ func getInsertOperationByOption(option int) string {
// 将对象转换为map如果对象带有继承对象那么执行递归转换。
// 该方法用于将变量传递给数据库执行之前。
func structToMap(obj interface{}) map[string]interface{} {
data := gconv.Map(obj)
data := gconv.Map(obj, OrmTagForStruct)
for key, value := range data {
rv := reflect.ValueOf(value)
kind := rv.Kind()
@ -183,7 +217,7 @@ func bindArgsToQuery(query string, args []interface{}) string {
}
switch kind {
case reflect.String, reflect.Map, reflect.Slice, reflect.Array:
return "'" + gconv.String(args[index]) + "'"
return "'" + gstr.QuoteMeta(gconv.String(args[index]), "'") + "'"
}
return gconv.String(args[index])
}
@ -194,5 +228,5 @@ func bindArgsToQuery(query string, args []interface{}) string {
// 使用递归的方式将map键值对映射到struct对象上注意参数<pointer>是一个指向struct的指针。
func mapToStruct(data map[string]interface{}, pointer interface{}) error {
return gconv.StructDeep(data, pointer)
return gconv.StructDeep(data, pointer, GetOrmMappingOfStruct(pointer))
}

View File

@ -490,21 +490,21 @@ func (md *Model) Value() (Value, error) {
}
// 链式操作查询单条记录并自动转换为struct对象, 参数必须为对象的指针,不能为空指针。
func (md *Model) Struct(objPointer interface{}) error {
func (md *Model) Struct(pointer interface{}) error {
one, err := md.One()
if err != nil {
return err
}
return one.ToStruct(objPointer)
return one.ToStruct(pointer)
}
// 链式操作查询多条记录并自动转换为指定的slice对象, 如: []struct/[]*struct。
func (md *Model) Structs(objPointerSlice interface{}) error {
func (md *Model) Structs(pointer interface{}) error {
r, err := md.All()
if err != nil {
return err
}
return r.ToStructs(objPointerSlice)
return r.ToStructs(pointer)
}
// 链式操作将结果转换为指定的struct/*struct/[]struct/[]*struct,