摘要
本周在项目方面系统学习了go语言,学习的go语言内容有切片、指针、结构体、继承、并发、通道、网络编程、数据库编程,让我明白了go语言的优点,一个最显著的优点是go语言天生支持并发编程,使用关键字"go"即可创建一个goroutine,再创建通道,用通道作为载体就可实现多个处理单元共同完成一项任务,大大提高任务程序执行效率。
1、go语言的数据库编程
用到了go语言标准库database/sql。用go语言标准库中与数据库连接的函数,设计实现对数据库中数据增删查改的函数。
以下是标准库函数:
-
连接数据库:sql.Open(“mysql”, dsn)
- “mysql”:表明连接的数据库是mysql。
- dsn:表明连接数据库的未知。dsn= “数据库账号:数据库密码@通信协议(ip地址:数据库端口号)/数据库名称”
-
数据库查询:db.QueryRow(sqlStr, id).Scan(&u1.id, &u1.name, &u1.age),输入数据库查询的mysal语言"sqlStr",函数将查询返回的值赋给数据库结构体u1。
-
数据库多行查询:db.Query(sqlStr, n),输入数据库查询的mysal语言"sqlStr",返回大于id>n的数据。
-
数据库插入:db.Exec(sqlStr),输入数据库查询的mysal语言"sqlStr"。
-
数据库更新:db.Exec(sqlStr, age, id),输入数据库查询的mysal语言"sqlStr"、需要更新数据的id号、更新后的age。
- 其中db是*sql.DB对象。
以下是自定义设计的函数:
- 数据库单行查询函数:query(id int8);输入id号,输出对应数据。
- 数据库多行查询函数:queryMore(n int);输入查询的id号最小值,输出id>=n的所有数据。
- 数据库中插入数据函数:func insert(name string, age int),输入插入这姓名、年纪即可插入。
- 数据库中数据删除函数:func deleteRow(id int),输入删除数据的id号即可删除。
10.数据库中数据更新函数:func updateRow(id int, age int) ,输入需要更新数据的id、年龄即可跟新数据。
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
)
var db *sql.DB
//用户结构体*******************************************************
type user struct {
id int
name string
age int8
}
//***********************数据库初始化*****************************
func initDB() (err error) {
//数据库信息
dsn := "root:root@tcp(127.0.0.1:3306)/day04"
//连接数据库
db, err = sql.Open("mysql", dsn)
if err != nil {
return err
}
err = db.Ping()
if err != nil {
return err
}
db.SetMaxOpenConns(10)
return nil
}
//************************数据库单行查询**************************************
func query(id int8) {
var u1 user
//查询单条sql语句
sqlStr := "select * from user where id=?"
//用QueryRow函数查询,将查询到的语句赋值给u1
db.QueryRow(sqlStr, id).Scan(&u1.id, &u1.name, &u1.age)
//输出u1
fmt.Printf("%v", u1)
}
//************************数据库多行查询************************************
//func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
func queryMore(n int) {
sqlStr := "select * from user where id>=?"
rows, err := db.Query(sqlStr, n)
if err != nil {
fmt.Printf("批量查询%s出错:%v", sqlStr, err)
return
}
defer rows.Close()
for rows.Next() {
var u1 user
rows.Scan(&u1.id, &u1.name, &u1.age)
fmt.Printf("%#v\n", u1)
}
}
//**********************向数据库插入数据****************************
func insert(name string, age int) {
sqlStr := "insert into user(name, age) values(?,?)"
ret, err := db.Exec(sqlStr, name, age)
if err != nil {
fmt.Printf("插入数据错误:%v", err)
}
id, err := ret.LastInsertId()
if err != nil {
fmt.Printf("提取数据出错:%v", err)
}
fmt.Printf("id: %d\n", id)
}
*************************删除数据库数据**********************
func deleteRow(id int) {
sqlStr := "delete from user where id=?"
_, err := db.Exec(sqlStr, id)
if err != nil {
fmt.Printf("语句:%s 删除失败: %v", sqlStr, err)
return
}
}
//**************************更新数据**********************************
func updateRow(id int, age int) {
sqlStr := "update user set age=? where id = ?"
db.Exec(sqlStr, age, id)
}
//***************************主函数*******************************
func main() {
// wg := sync.WaitGroup{}
err := initDB()
if err != nil {
fmt.Printf("初始化数据库出错: %v", err)
return
}
fmt.Println("连接数据库成功")
// insert()
queryMore(1)
deleteRow(2)
queryMore(1)
}
2、go语言网络编程
2.1 服务端
用Go标准库中net包中的net.Listen()函数创建基于"tcp"协议的服务端口,用net.Listener.Accept()等待客户端连接,故若无连接,则会一直等待,连接成功后用net.Conn.Read()读取客户端发送过来的数据。
package main
import (
"fmt"
"net"
)
func main() {
//启动本地端口服务
lister, err := net.Listen("tcp", "127.0.0.1:20000")
if err != nil {
fmt.Println("start server failed, err:", err)
return
}
//等待连接
conn, err := lister.Accept()
if err != nil {
fmt.Println("accept failed")
return
}
//与客户端连接
var tmp [128]byte
n, err := conn.Read(tmp[:])
if err != nil {
fmt.Println("read failed")
return
}
fmt.Println(string(tmp[:n]))
}
2.2 客户端
运用Go语言的标准库net,向函数net.Dial()输入要连接的计算机IP及连接协议,就可建立连接,用conn.Write()函数,可向服务器发送数据。
package main
import (
"fmt"
"net"
)
func e(er error, s string) {
if er != nil {
fmt.Println(s)
return
}
}
func main() {
//与server建立连接
conn, err := net.Dial("tcp", "127.0.0.1:20000")
e(err, "connect to server failed")
//发送数据
conn.Write([]byte("Hello Warld"))
conn.Close()
}