@@ -42,10 +42,13 @@ Driver是一个数据库驱动的接口,他定义了一个method: Open(name
42
42
}
43
43
44
44
返回的Conn只能用来进行一次goroutine的操作,也就是说不能把这个Conn应用于Go的多个goroutine里面。如下代码会出现错误
45
+
46
+ ...
47
+ go goroutineA (Conn) //执行查询操作
48
+ go goroutineB (Conn) //执行插入操作
49
+ ...
45
50
46
- go dosomething(Conn)
47
-
48
- 上面这样的代码会引发数据查询数据混乱,导致不知道是那个goroutine做的事情。会把goroutine A里面执行的查询返回给goroutine B执行的插入结果。
51
+ 上面这样的代码可能会导致不知道某个操作究竟是由哪个goroutine发起的,从而数据混乱,比如可能会把goroutine A里面执行的查询操作的结果返回给goroutine B从而使B错误的把此结果当成自己执行的插入结果。
49
52
50
53
第三方驱动都会定义这个函数,它会解析name参数来获取相关数据库的连接信息,解析完成后,它将使用此信息来初始化一个Conn并返回它。
51
54
@@ -60,9 +63,9 @@ Conn是一个数据库连接的接口定义,他定义了一系列方法,这
60
63
61
64
Prepare函数返回与当前连接相关的准备好Sql语句的状态,可以进行查询、删除等操作。
62
65
63
- Close函数关闭使得当前的连接失效,以及和当前连接相关的状态、处理 。因为database/sql里面实现了建议的conn pool,所以你不要再自己去实现缓存conn之类的,这样容易引起问题。
66
+ Close函数关闭当前的连接,以及执行释放连接拥有的资源等清理工作 。因为database/sql里面实现了建议的conn pool,所以你不要再自己去实现缓存conn之类的,这样容易引起问题。
64
67
65
- Begin函数返回一个事务处理Tx,可以进行事物操作,回滚、递交等操作 。
68
+ Begin函数返回一个代表事务处理的Tx,通过它你可以进行查询,更新等操作,或者对事务进行回滚、递交 。
66
69
67
70
##drive.Stmt
68
71
Stmt是一种准备好的状态,和Conn相关联,而且是只能应用于一个goroutine中,不能应用在多个goroutine中。
@@ -74,7 +77,7 @@ Stmt是一种准备好的状态,和Conn相关联,而且是只能应用于一
74
77
Query(args []Value) (Rows, error)
75
78
}
76
79
77
- Close函数关闭当前的链接状态,但是如果当前正在执行query,query还是有效返回raws数据 。
80
+ Close函数关闭当前的链接状态,但是如果当前正在执行query,query还是有效返回rows数据 。
78
81
79
82
NumInput函数返回当前预留参数的个数,当返回>=0时数据库驱动就会智能检查调用者的参数。当数据库驱动包不知道预留参数的时候,返回-1。
80
83
@@ -94,7 +97,7 @@ Query函数执行Prepare准备好的sql,传入需要的参数执行select操
94
97
这两个函数一个用来递交一个事务,一个用来回滚事务。
95
98
96
99
##drive.Execer
97
- 这个接口是Conn可选的可实现可不实现的接口
100
+ 这是一个Conn可选择实现的接口
98
101
99
102
type Execer interface {
100
103
Exec(query string, args []Value) (Result, error)
@@ -110,8 +113,9 @@ Query函数执行Prepare准备好的sql,传入需要的参数执行select操
110
113
RowsAffected() (int64, error)
111
114
}
112
115
113
- LastInsertId函数返回插入数据库之后返回自动增长字段的ID,Insert之后返回的数据
114
- RowsAffected函数返回通过query影响的数据库条数。
116
+ LastInsertId函数返回由数据库执行插入操作得到的自动增长ID号。
117
+
118
+ RowsAffected函数返回query操作影响的数据条目数。
115
119
116
120
##drive.Rows
117
121
Rows是执行查询返回的结果集接口定义
@@ -129,7 +133,7 @@ Columns函数返回查询数据库表的字段信息,这个返回的slice和
129
133
130
134
Close函数用来关闭Rows迭代器。
131
135
132
- Next函数用来返回下一条数据,把数据赋值给dest。dest里面的元素必须是drive.Value的值除了string,所有的string必须转换成 [ ] byte. 如果最后没数据了,Next函数最后返回io.EOF。
136
+ Next函数用来返回下一条数据,把数据赋值给dest。dest里面的元素必须是drive.Value的值除了string,返回的数据里面所有的string都必须要转换成 [ ] byte。 如果最后没数据了,Next函数最后返回io.EOF。
133
137
134
138
135
139
##drive.RowsAffected
@@ -156,30 +160,30 @@ Value的值必须所有的驱动里面控制的,Value要么是nil,要么是
156
160
time.Time
157
161
158
162
##drive.ValueConverter
159
- ValueConverter接口定义了如何把一个普通的值转化成drive .Value的接口
163
+ ValueConverter接口定义了如何把一个普通的值转化成driver .Value的接口
160
164
161
165
type ValueConverter interface {
162
166
ConvertValue(v interface{}) (Value, error)
163
167
}
164
168
165
- ValueConverter对于各种各种的值的实现必须保持高度的一致性,在驱动包里面很多地方会使用到这个转化接口
169
+ 在开发的数据库驱动包里面实现这个接口的函数在很多地方会使用到,这个ValueConverter有很多好处:
166
170
167
171
- 转化drive.value到数据库表相应的字段,例如int64的数据如何转化成数据库表uint16字段
168
172
- 把数据库查询结果转化成drive.Value值
169
- - 在scan函数里面如何吧dirve .Value值转化成用户定义的值
173
+ - 在scan函数里面如何把dirve .Value值转化成用户定义的值
170
174
171
175
##drive.Valuer
172
- Valuer接口定义了返回如何返回一个drive.Value值
176
+ Valuer接口定义了返回一个driver.Value的方式
173
177
174
178
type Valuer interface {
175
179
Value() (Value, error)
176
180
}
177
- 很多类型上面都定义了这个Value方法,用来实现每个相应类型如何转化为drive.Value类型 。
181
+ 很多类型都实现了这个Value方法,用来自身与driver.Value的转化 。
178
182
179
- 通过上面的讲解,对于驱动的开发有了细致的了解,一个驱动基本上就是实现上面的这些接口就能完成我们平常的增删改所有的操作了,底层就是和相应的数据库进行数据交互就可以了 。
183
+ 通过上面的讲解,你应该对于驱动的开发有了一个基本的了解,一个驱动只要实现了这些接口就能完成增删查改等基本操作了,剩下的就是与相应的数据库进行数据交互等细节问题了,在此不再赘述 。
180
184
181
185
##database/sql
182
- database/sql里面定义了基于这个驱动之上的一些方法,这些方法都是基于drive接口来封装的, 同时内部还实现了一个建议的conn pool。
186
+ database/sql在database/sql/driver提供的接口基础上定义了一些更高阶的方法,用以简化数据库操作, 同时内部还实现了一个建议的conn pool。
183
187
184
188
type DB struct {
185
189
driver driver.Driver
@@ -189,7 +193,7 @@ database/sql里面定义了基于这个驱动之上的一些方法,这些方
189
193
closed bool
190
194
}
191
195
192
- 我们可以看到Open函数返回的是DB对象,里面有一个freeConn,这个就是那个简易的连接池。它的实现也是就是很简单,当执行Db.prepare的时候最后会defer: ` db.putConn(ci, err) ` ,也就是放入连接池,而每次调用conn的时候也会优先判断freeConn的长度是否大于0,大于0说明有使用过的conn,直接拿出来就用了 。
196
+ 我们可以看到Open函数返回的是DB对象,里面有一个freeConn,,它就是那个简易的连接池。它的实现相当简单或者说简陋,就是当执行Db.prepare的时候会defer : db .putConn(ci, err),也就是放入连接池,每次调用conn的时候会先判断freeConn的长度是否大于0,大于0说明有可以复用的conn,直接拿出来用就是了,如果不大于0,则创建一个conn,然后再返回之 。
193
197
194
198
195
199
## links
0 commit comments