len with
如何自定义函数
template.Funcs(funcMap FuncMap) *Template
type FuncMap [string] interface{}
value 是函数 :可以有任意数量的参数,返回单个值或者 单个值+error
- 步骤: 创建一个FuncMap (map类型)
key 是函数名 value 就是函数 - 把FuncMap 附加到模板上
例子:
package main
import (
“net/http”
“text/template”
“time”
)
func main() {
http.HandleFunc("/range", webRangeHandle)
http.HandleFunc("/funcMap", custFunc)
http.ListenAndServe(“localhost:8010”, nil)
}
//遍历handle
func webRangeHandle(rw http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(“home.html”, “h1.html”)
if err != nil {
rw.WriteHeader(http.StatusNotFound)
} else {
var strSlice []string
for _, v := range []rune(“发送开了房间爱上了房价哦”) {
strSlice = append(strSlice, string(v))
}
t.Execute(rw, strSlice)
}
}
func custFunc(rw http.ResponseWriter, r *http.Request) {
attchFunc := template.FuncMap{“DateTimeToData”: converDataTime}
t := template.New(“home.html”).Funcs(attchFunc)
t.ParseFiles(“home.html”)
t.Execute(rw, time.Now())
}
func converDataTime(t time.Time) string {
return t.Format(time.RFC3339)
}
页面HTML代码:
home 页面
{{.|DateTimeToData}}111
222
<hr/>
如何使用自定义函数
常见用法: template.New("").Funcs(funcMap).Parse(…) 调用顺序非常重要。 可以在管道中使用, 也可以作为正常函数使用 管道比较好
组合模板:
layout 模板 就是网页中固定的部分, 他可以被多个网页重复使用
include (包含) action 的形式 : {{template “name” .}}
以这种layout 模板是不可行的,正确的做法是在模板文件中使用define action 在定义一个模板
例子:
package main
import (
“net/http”
“text/template”
“time”
)
func main() {
http.HandleFunc("/range", webRangeHandle)
http.HandleFunc("/funcMap", custFunc)
http.HandleFunc("/layout", layout)
http.ListenAndServe(“localhost:8010”, nil)
}
//遍历handle
func webRangeHandle(rw http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles(“home.html”, “h1.html”)
if err != nil {
rw.WriteHeader(http.StatusNotFound)
} else {
var strSlice []string
for _, v := range []rune(“发送开了房间爱上了房价哦”) {
strSlice = append(strSlice, string(v))
}
t.Execute(rw, strSlice)
}
}
func custFunc(rw http.ResponseWriter, r *http.Request) {
attchFunc := template.FuncMap{“DateTimeToData”: converDataTime}
t := template.New(“home.html”).Funcs(attchFunc)
t.ParseFiles(“home.html”)
t.Execute(rw, time.Now())
}
func converDataTime(t time.Time) string {
return t.Format(time.RFC3339)
}
func layout(rw http.ResponseWriter, r *http.Request) {
t := template.Must(template.ParseFiles(“layout.html”, “test.html”))
t.ExecuteTemplate(rw, “layout.html”, “你是个谁~~”)
}
网页 :
模板代码;
使用模板代码;
{{define “content”}}
test.html {{.}}
{{end}}
使用 block action 定义默认模板
{{block arg }}
Don is set arg
{{end}}
block action 可以定义模板,并同时就使用它
template : 模板必须可用
block : 模板可以不存在
连接sqlServer 数据库
想要连接到sql 数据库 首先需要加载目标数据库驱动, 驱动数据包里边含着该数据库交互的逻辑
sql.Open() 数据库驱动名称, 数据源名称 得到一个指向sql.DB 这个struct 的指针
sql.DB 是用来操作数据库的,它代表0个或者多个底层连接的池,这些连接由sql包来维护,sql 包会自动创建和释放这些连接。
Note 注意事项:
Open() 函数并不会连接数据库,甚至都不会去验证参数,它只是把后续连接到数据库必须的 struct 给 设置好
而真正连接是在被需要的时候才进行的懒设置的
sql.DB 不需要进行关闭,当然如果你想关闭也是可以的。
他就是用来处理数据的,而不是实际的连接。
这个抽象包含了数据库连接池,而且会对此进行维护
在使用sql.DB 的时候,可以定义它的全局变量进行使用,也可以将它传递函数/方法里。
如何获取驱动: 正常的做法是使用sql.Register() 函数,数据库驱动的名称和实现了driver.Driver 接口的 struct 来注册数据库驱动, 例如:
sql.Register("sqlserver",&div{})
但是之前的例子却没有用到,是在init() 函数里边。进行了自我注册
go get github.com/denisenkom/go-mssqldb 下载驱动
func (*DB) PingContext
例子中的 db.PingContext() 函数是用来验证与数据连接是否仍然有效,如果必要则建立一个连接。
这个函数需要一个 Context (上下文) 类型参数,这种类型可以携带时间 取消信号 和其他请求范围的值,并且可以横跨 API 边界和进程。
上例子中,创建 context 使用的是,context.Background() 函数, 该函数返回一个非 nil 的空 context 他不会被取消,他没有值,没有截止时间。
它通常在main 函数,初始化或者测试中, 作为传入请求项context。
例子:
package main
import (
“database/sql”
“fmt”
“log”
_ "github.com/denisenkom/go-mssqldb" // 根据自己放的驱动位置引用
)
var Db *sql.DB
const (
dataSource = “localhost” // 本地 也可以填写网址
port = 1433 //数据端口号 目前是缺省值
user = “sa” //登录数据库的用户名
pwd = “123456” //登录密码
database = “MyText” //数据库 根据自己数据库填写
sqlType = “sqlserver” //数据类型
)
func main() {
conStr := fmt.Sprintf(“server=%s;user id=%s;password=%s;port=%d;database=%s;encrypt=disable”, dataSource, user, pwd, port, database)
Db, err := sql.Open(sqlType, conStr)
if err != nil {
log.Fatalln(“open函数发生错误!”)
}
defer Db.Close()
err = Db.Ping()
if err != nil {
fmt.Println(“连接数据库失败!” + conStr + err.Error())
return
}
fmt.Println(“连接上数据库:” + conStr)
}