我的天哪!终于改好了连接数据库的bug!
1、go语言连接postgreSQL数据库
这次的作业要求讲blotdb数据库改成mysql数据库。但是我本地没装mysql而是装的postgresql,所以就换成postgresql来实现了。反正也差不多,使用的包也都一样。
首先安装依赖包:
go get github.com/lib/pq ,这个是连接postgresql数据库用的包。
go get github.com/go-sql-driver/mysql 这是框架需要用到的包。
导入文件的时候需要再加一个database/sql,然后上面装的两个包需要添加下划线:
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
"fmt"
"html/template"
"log"
"net/http"
"strings"
//"reflect"
"723ApiOnGo/723swapi/swapi"
//"github.com/boltdb/bolt"
"strconv"
)
前3行是数据库操作对用的导入。
创建数据库
这里需要用到sql,我新建了数据库和用户,代码过程如下:
CREATE USER wangkuo1 WITH PASSWORD '123456';
CREATE DATABASE go OWNER wangkuo1;
GRANT ALL PRIVILEGES ON DATABASE go TO wangkuo1;
然后就可以登陆数据库在里间建立各种数据表了。新建数据表的时候有个需要注意的问题就是char(length)来表示字符串的时候,length不能过长。一开始我设置50,然后创建数据表报错,懵逼了很久,后来试着把长度改短一些就能成功创建数据表了。
go语言连接数据库
这个我是真的踩了巨多的坑!整整一个下午的时间我都在尝试连接数据库,尝试查询数据库,处理从数据库中提取出来的信息。
首先连接数据库的语句是:
psqlInfo := fmt.Sprintf("host=localhost port=5432 user=wangkuo1 "+
"password=123456 dbname=go sslmode=disable")
db, err := sql.Open("postgres", psqlInfo)
if err != nil {
fmt.Println(err);
return
}
注意sql.open函数的第一个参数是数据库类型,要填postgres,我原来以为那个参数是数据库的名称,懵逼了好久才知道怎么回事。然后还有一个问题就是不要搞什么转换,他会把你的数据格式搞错,比如下面就是错误案例:
const (
host = "localhost"
port = 5432
user = "wangkuo1"
password = "123456"
dbname = "go"
)
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
db, err := sql.Open("postgres", psqlInfo)
if err != nil {
panic(err)
}
//会报错!!!
报错就是下面这个样子:
嗯就是你的字符串信息在传递的时候会发生转换导致完全不对的登陆信息导致无法连接数据库。这是另一个卡了我很久的问题。
插入数据
终于成功连接了数据库,接下来的内容就是要插入数据。
stmt,err:=db.Prepare("INSERT INTO login(username,password) VALUES ($1,$2)")
if err != nil {
fmt.Println(err);
}
stmt.Exec(username[0],password[0])
username[0]和password[0]是我传递进去的参数。这个倒是没遇到什么大问题。
看看我们数据库那边是否真正插入了数据?
查询数据
查询数据代码
sqlStatement := "SELECT password FROM login WHERE username=$1;"
var v []byte
row := db.QueryRow(sqlStatement, username[0])
err = row.Scan(&v)
switch err {
case sql.ErrNoRows:
//没有找到结果,在此输入的你响应过程
case nil:
//成功查询到结果,在此输入你的响应过程
default:
panic(err)
}
那么为什么这里要用byte数组来保存结果呢?这就涉及到了最后一个卡了我很久很久的问题。一开始我设置的v的类型是string,然后查询成功之后输入v,输入前端输入的密码,输出查询结果和前端输入是否相等,结果就是下面的结果:
卧槽!!!这是什么鬼!为什么比较结果是false啊!明明都一样啊!中间我想尽了各种方法始终不知到怎么回事,然后,我把字符串转换成了byte数组一输出:
终于看出了猫腻。因为我们的数据库设置的密码的类型是char(20),你在插入数据的时候不够20的长度就用空来补全。然后查询结果会连那补上去的一堆空字符页返回,导致了字符串无法匹配。知道了这个原因之后,我选取返回结果的非空部分在进行匹配,终于完成了登陆的验证问题。
然后就没有啦!其他的数据库操作基本上就和这个相同了。因为我们的web服务里,没有更改数据这个功能。