前置操作
在 Go 中进行数据库操作主要通过数据库驱动和标准库中的 database/sql 包来实现。下面是导入相关的包
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql" // 导入 MySQL 驱动
)
连接数据库,首先需要声明相关信息
var(
db_Address = "127.0.0.1:3306"
db_username = "root"
db_password = "123456"
db_name = ""
)
这里声明数据库数据库地址,为了测试方便这里我使用本地地址,数据库用户名,数据库密码还有数据库名称。下一步就是测试连接是否成功,代码如下:
func connSql() *sql.DB {
db_info := "root:123456@tcp(127.0.0.1:3306)/"
db_info := strings.Join([]string{db_username, ":", db_password, "@tcp(", db_Address, ")/", db_name}, "")
db, err := sql.Open("mysql", db_info)
if err != nil {
fmt.Print("open mysql error", err)
return db
}
err = db.Ping()
db.SetConnMaxLifetime(100)
db.SetMaxIdleConns(10)
DB = db
if err != nil {
fmt.Print("open mysql error 2", err)
return db
}
return db
}
上面db_info有两种写法,使用下面那种写法更方便后面需要改变库环境的场合。sql.open("数据库",数据库相关信息)返回数据库和错误。下面先进行捕获错误,使用Ping方法进行数据连接测试。对于连接需要反复调用连接的情况,这里有个更加简单的方法,在外面声明db变量使用指针将其值进行更改,只需要执行一次就可以反复进行使用。
数据库操作
增加
首先我们需要创造一个数据库,并且声明表。
create table user(
user_name varchar(20),
user_password varchar(20)
);
insert into user (user_name, user_password)
values ('11','22');
这里实现创造数据表,向表中插入数据的操作。接下来进行增加操作测试。
// 定义模型
type user struct {
user_name string
user_password string
}
func insertUser(User user) int {
resp := User
if User.user_password == "" || User.user_name == "" {
fmt.Print("失败")
return -3
}
//exec, err := DB.Prepare("insert into user (user_name,user_password) values (?,?);")
s := "insert into user(user_name,user_password) values (?,?)"
res, err := DB.Exec(s, resp.user_name, resp.user_password)
if err != nil {
fmt.Println("err", err)
return -1
}
id, err := res.LastInsertId()
if err != nil {
fmt.Println("err1", err)
return -2
}
fmt.Println(id)
return 0
}
这里代码逻辑主要是
- 定义相关模型
- 检测参数
- 编写sql代码
- 执行sql代码
- 获取sql代码返回值
查询
代码如下
func selectdb(name string) *user {
if name == "" {
return nil
}
query, err := DB.Query("select * from user")
if err != nil {
return nil
}
columns, err := query.Columns()
defer query.Close()
if columns != nil {
fmt.Print(columns)
}
var u user
for query.Next() {
query.Scan(&u.user_name, &u.user_password)
fmt.Println("u : %#v", u)
}
fmt.Println()
return nil
}
代码逻辑如上的。值得注意的一点是我们需要进行将query进行关闭,query.next()是查看是否有后续元素,将后续元素的属性赋值到前面我们声明的变量u中,然后进行获得结果打印。
删除
func delete(user_name string) {
if user_name == "" {
return
}
sql := "delete from user where user_name = ?"
exec, err := DB.Exec(sql, user_name)
if err != nil {
fmt.Println("err")
return
}
fmt.Println(exec.RowsAffected())
}
RowsAffected返回影响相关行数,通过这个可以知道我们的代码是否有对数据库进行修改。
更新
func update(User user, user_name string) {
sql := "update user set user_name = ? and user_password = ? where user_name = ?"
exec, err := DB.Exec(sql, User.user_name, User.user_password, user_name)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(exec.LastInsertId())
}
注意点
可以看到在go中操作数据库主要使用的方法open,Ping,Exec,Query,Next,RowsAffected等。主要需要注意的是Exec和Query两个方法的异同之处。
- 返回值类型:
Query方法返回的是一个查询结果集,通常是一个*sql.Rows对象,用于迭代和获取查询结果的行数据。而Exec方法返回的是一个sql.Result对象,用于获取执行插入、更新或删除操作后的结果信息。 - 用途:
Query方法用于执行查询语句,可以获取符合条件的行数据。它通常用于执行SELECT语句。Exec方法用于执行插入、更新或删除操作。它通常用于执行INSERT、UPDATE或DELETE语句。 - 参数传递:
Query方法中的参数是包含查询语句和可选的参数值的格式化字符串,可以通过占位符?或命名参数来传递参数值。例如:db.Query("SELECT * FROM users WHERE id = ?", 1)。而Exec方法中的参数传递方式与之类似。 - 影响行数:
Exec方法会返回一个sql.Result对象,通过该对象可以获取到操作影响的行数。一般情况下,插入、更新或删除操作会返回受影响的行数。
综上所述,Query 方法适用于执行查询语句,而 Exec 方法适用于执行插入、更新或删除操作。它们的返回值类型、用途和参数传递方式都有所不同。根据具体的需求,我们选择使用相应的方法来进行数据库操作。