1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| package clause
import ( "fmt" "strings" )
type generator func(values ...interface{}) (string, []interface{})
var generators map[Type]generator
func init() { generators = make(map[Type]generator) generators[INSERT] = _insert generators[VALUES] = _values generators[SELECT] = _select generators[LIMIT] = _limit generators[WHERE] = _where generators[ORDERBY] = _orderBy }
func genBindVars(num int) string { var vars []string for i := 0; i < num; i++ { vars = append(vars, "?") } return strings.Join(vars, ", ") }
func _insert(values ...interface{}) (string, []interface{}) { tableName := values[0] fields := strings.Join(values[1].([]string), ",") return fmt.Sprintf("INSERT INTO %s (%v)", tableName, fields), []interface{}{} }
func _values(values ...interface{}) (string, []interface{}) { var bindStr string var sql strings.Builder var vars []interface{} sql.WriteString("VALUES ") for i, value := range values { v := value.([]interface{}) if bindStr == "" { bindStr = genBindVars(len(v)) } sql.WriteString(fmt.Sprintf("(%v)", bindStr)) if i+1 != len(values) { sql.WriteString(", ") } vars = append(vars, v...) } return sql.String(), vars
}
func _select(values ...interface{}) (string, []interface{}) { tableName := values[0] fields := strings.Join(values[1].([]string), ",") return fmt.Sprintf("SELECT %v FROM %s", fields, tableName), []interface{}{} }
func _limit(values ...interface{}) (string, []interface{}) { return "LIMIT ?", values }
func _where(values ...interface{}) (string, []interface{}) { desc, vars := values[0], values[1:] return fmt.Sprintf("WHERE %s", desc), vars }
func _orderBy(values ...interface{}) (string, []interface{}) { return fmt.Sprintf("ORDER BY %s", values[0]), []interface{}{} }
|
也就是说,我们还需要一个步骤,根据数据库中列的顺序,从对象中找到对应的值,按顺序平铺。即 u1、u2 转换为 ("Tom", 18), ("Same", 25) 这样的格式。
Find 功能的难点和 Insert 恰好反了过来。Insert 需要将已经存在的对象的每一个字段的值平铺开来,而 Find 则是需要根据平铺开的字段的值构造出对象。同样,也需要用到反射(reflect)。