##studygolang数据库设计的看法##
源码使用sql来管理与数据库表的交互。在sql.db之上派生struct Dao。Dao结构封装SQL语句的组建过程,为具体的数据模块服务提供,提供增删查改等功能,以及数据返回。在Dao之上,则是各种与数据库表对应的实际的数据模块,这一层通过Dao拿到需要的数据或执行操作。
要分析源码设计思路,我的思路是需要从最底层开始分析,从最底层提供的能力,提供的API出发
- sql package提供的接口能力
在sql package内有一个结构是DB,他是数据库的一个句柄,并具有goroutine安全性。 sql.Rows 多用与对返回的结果集进行处理。sql.Result是对执行结果的
它的一下两个方法是所有查询方法的基础,Query的天然返回结果就是一个sql.Row
func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
func (db *DB) QueryRow(query string, args ...interface{}) *Row
对数据表的修改(插入,修改)则需要依靠下面方法
func (db *DB) Exec(query string, args ...interface{}) (Result, error)
另外有一个方法,需要跟type Stmt,以及相应的结果sql.Result结合使用
func (db *DB) Prepare(query string) (*Stmt, error)
type Stmt struct {
// contains filtered or unexported fields
}
func (s *Stmt) Exec(args ...interface{}) (Result, error)
- Dao模块
Dao模块的第一个功能是,抽象出sql执行过程中的一些数据接口,使用util package将具有这些数据interface的结构进行字符串处理拼出sql语句,先看他实现的接口
type Sqler interface {
Tablename() string
Columns() []string
SelectCols() string // 需要查询哪些字段
GetWhere() string
GetOrder() string
GetLimit() string
}
这几个接口为SQL语句的拼接提供表名,列名,条件语句以及结果的处理方法。这样Dao为util提供了接口实现,util为Dao提供了需要的SQL语句串。
Dao模块核心的功能是操作数据库,进行插入,修改,查询操作。这部分功能依赖与底层sql.DB与stmt提供的查询(query,queryRow),执行(exec)方法,以及sql.Rows 提供的scan方法,对返回结果集的处理。
看下Dao提供的几个主要的方法。
func (this *Dao) Insert() (sql.Result, error)
func (this *Dao) Update() error
func (this *Dao) Count() (total int, err error)
func (this *Dao) Find(colFieldMap map[string]interface{}, selectCol ...string) error
func (this *Dao) FindAll(selectCol ...string) (*sql.Rows, error)
Insert方法通过util拼装sqlstr,stmt方法来执行sql,Update方法通过util拼装sqlstr,之后调用sql.Exec。
count find findall则是调用的query或是queryRow方法实现查询以及对查询结果的处理。
func (this *Dao) Increment(field string, num int) error
这个Increment方法很奇怪,它的sqlstr是自己拼装起来的并没有使用util的拼装方法。自己组装了一个sql语句调用exec实现。
哈哈 今天下午去听海淀的讲座,得了一本许式伟的《go语言编程》嘿嘿。 讲到这个接口,用来解决相互依赖的问题,从源码中看来却是如此O(∩_∩)O~。
#2
更多评论
Increment这个方法是为了实现:浏览数、评论数增加。它实际上也是一个update。由于util中已经有了UpdateSql,这里就没有将sql提取出来。
#1