连接数据库
sq1.DB结构是一个数据库句柄(handle),它代表的是一个包含了零个或任意多个数据库连接的连接池(pool),这个连接池由sql包管理。程序可以通过调用Open函数,并将相应的数据库驱动名字(driver name)以及数据源名字(data source name)传递给该函数来建立与数据库的连接。
比如,在下面展示的例子中,程序使用的是mysql驱动。数据源名字是一个特定于数据库驱动的字符串,它会告诉驱动应该如何与数据库进行连接。
Open函数在执行之后会返回一个指向sq1.DB结构的指针作为结果。Open函数在执行时,不会真正的与数据库连接,甚至不会检查参数.
Open函数真正的作用是设置好连接数据库所需要的结构,并以惰性的方式,等真正需要的时候才建立与数据库连接
var Db *sql.DB
func init() {
var err error
Db, err = sql.Open("mysql", "esns:dccmmtop@tcp(192.168.32.128:3306)/chitchat")
if err != nil {
log.Fatal(err)
}
return
}
创建用户
type User struct {
Id int64
Uuid string
Name string
Email string
Password string
CreatedAt time.Time
}
func (u *User) Create() (err error) {
statement := "insert into users(uuid,name,email,password, created_at) value(?,?,?,?,?)"
// 预编译
stmt, err := Db.Prepare(statement)
if err != nil {
return err
}
defer stmt.Close()
// 加密密码
u.Password = Encrypt(u.Password)
// 生成UUID
u.Uuid = CreateUUID()
u.CreatedAt = time.Now()
// 执行
result, err := stmt.Exec(u.Uuid,u.Name,u.Email,u.Password,u.CreatedAt)
if err != nil {
return err
}
// 返回插入后的自增ID
u.Id, err = result.LastInsertId()
if err != nil {
util.Danger.Println("创建用户返回Id错误: ",err)
return err
}
util.Info.Println("新增用户: ", fmt.Sprintf("%v",*u))
userJson, err := json.Marshal(*u)
if err != nil {
return err
}
util.Info.Println("新增用户: ", string(userJson))
return
}
查询用户
// 根据ID查询用户
func FindUserById(id int64)(u User, err error) {
sql := "select id, uuid, `name`, email, password, created_at from users where id = ?"
u = User{}
// scan 将查询出来的每一列赋值给对应的属性
err = Db.QueryRow(sql, id).Scan(&u.Id, &u.Uuid, &u.Name, &u.Email, &u.Password, &u.CreatedAt)
if err != nil {
util.Danger.Println("查询用户错误: ", err)
return
}
return
}
获取多个对象
type Thread struct {
Id int64
Uuid string
UserId int64
Topic string
CreatedAt time.Time
}
// 获取用户发布多个帖子
func ThreadsList(userId int64)(threads []Thread){
sql := "select id, uuid, user_id, topic,created_at from threads where user_id = ? order by created_at desc"
rows, err := Db.Query(sql,userId)
if err != nil {
util.Danger.Println("查询 threads 错误, 返回空数据,err:", err)
return
}
defer rows.Close()
for rows.Next() {
thread := Thread{}
err := rows.Scan(&thread.Id,&thread.Uuid,&thread.UserId,&thread.Topic,&thread.CreatedAt)
if err != nil {
util.Danger.Println(err)
continue
}
threads = append(threads,thread)
}
return
}