golang物聯網之路一:來個簡單的CRUD吧


互聯網目前已進入其生命末期,而物聯網則正在落地開發,隨之而來的各種原生雲則是讓互聯網進入生命末期的主要誘因。同時由於物聯網的興起,對雲的要求則更加迫切,所以這里不得不掌握一門新的雲語言來增強自身的技能屬性,避免被時代拋棄,golang,作為新生代語言,則屬於天選之子。

當然了,新語言學習,我一向認為單純的看語法,按部就班的學習,是一件很枯燥且性價比極低的事情,所以這里,我們就從mysql的crud來學起吧。當然了,工欲善其事必先利其器,我們首先要在本地安裝好mysql server, go sdk,goland等必備工具,由於安裝過程寥寥幾筆,無需濃墨重彩,我這里不需多言。下面展示的是安裝好之后的代碼步驟

代碼層級

 代碼層級很簡單,dao放數據訪問層,entity是實體層,service中則是增刪改查的各種服務,main.go負責運行,而go.mod則是創建項目的時候,goland默認給我們創建的,注意這個go.mod非常重要,不要刪除,否則會導致無法import一些包。

數據庫連接connection.go

package dao

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"strings"
)

const(
	userName = "root"
	password = "root"
	ip       = "127.0.0.1"
	port     = "3306"
	dbName   = "test"
)

func InitDB() *sql.DB {
	//Golang數據連接:"用戶名:密碼@tcp(IP:端口號)/數據庫名?charset=utf8"
	path := strings.Join([]string{userName, ":", password, "@tcp(", ip, ":", port, ")/", dbName, "?charset=utf8"}, "")
	//打開數據庫,前者是驅動名,所以要導入: _ "github.com/go-sql-driver/mysql"
	db, err := sql.Open("mysql", path)
	if err != nil {
		//如果打開數據庫錯誤,直接panic
		panic(err)
	}
	//設置數據庫最大連接數
	db.SetConnMaxLifetime(10)
	//設置上數據庫最大閑置連接數
	db.SetMaxIdleConns(5)
	//驗證連接
	errPing := db.Ping()
	if errPing != nil {
		panic(err)
	}
	return db;
}

  注意,在寫驅動前,需要利用 go get -u github.com/go-sql-driver/mysql 命令將驅動包安裝到GOPATH指定的目錄下,go env命令可以查看GOPATH目錄,之后在goland中,確認GOPATH目錄,就可以正常的引用包了,否則import的包怎么都會檢測不到:

用戶實體user.go

package entity

type User struct{
	userId int
	userName string
	userAddr string
}

//(user *User) 其實就是java中的this關鍵字,指向當前對象

func (user *User) GetUserId() int  {
	return user.userId
}

func (user *User) SetUserId(userId int)  {
	user.userId = userId
}

func (user *User) GetUserName() string {
	return user.userName
}

func (user *User) SetUserName(userName string)  {
	user.userName = userName
}

func (user *User) GetUserAddr() string  {
	return user.userAddr
}

func (user *User) SetUserAddr(userAddr string)  {
	user.userAddr = userAddr
}

  需要注意,在go中,pulic,private,protected等修飾符是沒有的, 方法首字母大寫,則默認為public方法,方法首字母小寫,則默認為private方法。

增刪改查

package service

import (
	"firstgo/src/dao"
)

func CreateRecord() (int64,error){
	db := dao.InitDB()
	tx, err := db.Begin()
	if err != nil{
		panic(err)
	}

	sql := "insert into user (`user_name`, `user_addr`) values (?, ?)"
	stmt, err := db.Prepare(sql)
	if err != nil {
		panic(err)
	}
	result, err := stmt.Exec("testuser","china, beijing")
	if err != nil {
		//SQL執行失敗,直接panic
		panic(err)
	}
	//提交事務
	tx.Commit()
	//返回插入記錄的id
	return result.LastInsertId()
}

  新增用戶,驅動代碼如上,注意返回值,在go中,是支持多返回值的。

package service

import (
	"firstgo/src/dao"
)

func DeleteRecord(userId int) (int64, error) {
	db := dao.InitDB()
	tx, err := db.Begin()
	if err != nil {
		panic(err)
	}

	sql := "delete from user where user_id = ? "
	stmt, err := db.Prepare(sql)
	if err != nil {
		panic(err)
	}
	result, err := stmt.Exec(userId)
	if err != nil {
		//SQL執行失敗,直接panic
		panic(err)
	}
	//提交事務
	tx.Commit()
	return result.RowsAffected()
}

  刪除用戶代碼如上,需要注意的是 :=的寫法,實際上是屬於自動推導類型。

package service

import "firstgo/src/dao"

func UpdateRecord(userAddr string, userId int)(int64, error) {
	db := dao.InitDB()
	tx, err := db.Begin()
	if err != nil {
		panic(err)
	}

	sql := "update user set user_addr = ? where user_id = ? "
	stmt, err := db.Prepare(sql)
	if err != nil {
		panic(err)
	}
	result, err := stmt.Exec(userAddr, userId)
	if err != nil {
		//SQL執行失敗,直接panic
		panic(err)
	}
	//提交事務
	tx.Commit()
	return result.RowsAffected()
}

  更新代碼如上,和刪除方法類似,無需多言。

package service

import (
	_ "database/sql"
	"firstgo/src/dao"
	"firstgo/src/entity"
)

func QueryList() []entity.User {
	db := dao.InitDB()

	sql := "select * from user "
	stmt, err := db.Prepare(sql)
	if err != nil {
		panic(err)
	}

	rows, err := stmt.Query()
	if err != nil {
		//SQL執行失敗,直接panic
		panic(err)
	}

	var users []entity.User
	for rows.Next() {
		var id int
		var name, password string
		err := rows.Scan(&id, &name, &password)
		if err != nil {
			//讀取結果集失敗
			panic(err)
		}

		var user entity.User
		user.SetUserId(id)
		user.SetUserName(name)
		user.SetUserAddr(password)
		users = append(users, user)
	}

	return users
}

  查詢列表方法如上,從代碼中,可以看到go中數組的寫法和我們正常寫法不一樣,需要適應。

//package名稱需要設置為main,才會進入main方法運行
package main

import (
	"firstgo/src/service"
	"fmt"
)

func main() {

	//新增
	recordId, err := service.CreateRecord()
	if err == nil && recordId > 0 {
		fmt.Println("插入成功,id:", recordId)
	}

	//刪除
	var removedRecordId = 1
	rowAffected, err := service.DeleteRecord(removedRecordId)
	if err == nil && rowAffected>0 {
		fmt.Println("刪除成功,id:", removedRecordId )
	}

	//更新
	var userAddr = "shanghai, china"
	var updateRecordId = 3
	record, err := service.UpdateRecord(userAddr, updateRecordId)
	if err == nil && record>0{
		fmt.Println("更新成功,id:", updateRecordId)
	}

	//查詢
	queryList := service.QueryList()
	if queryList != nil{
		fmt.Println("查詢列表,list:", queryList)
	}
}

  寫好后,在main.go中運行起來即可。記住,main方法的運行一定要有個package為main的包,否則會報錯。運行起來后,我們就可以看到如下輸出了:

插入成功,id: 9
更新成功,id: 3
查詢列表,list: [{2 testuser china, beijing} {3 testuser shanghai, china} {4 testuser china, beijing} {5 testuser china, beijing} {6 testuser china, beijing} {7 testuser china, beijing} {8 testuser china, beijing} {9 testuser china, beijing}]

Process finished with the exit code 0

  是不是很簡單?

 

參考

https://blog.csdn.net/qq_45193304/article/details/105464606


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM