Go言語勉強録
Goは書いていたのですが、どれをネタにしようかと迷い迷っていました。
セッションの実装をネタにしようと思っていたのですが、実装と記事をまとめるまでが時間が相当かかりそうだったので、セッションの実装の際、データベースからデータを読み込む時に少しつまづいた部分をネタにしようと思いました。
今回は構造体の配列の要素追加をやっていきます。
過去の記事
- Go言語の環境構築 Hello Worldまで
- go言語 静的ページの作成
- AngularJSのhttp通信からのpostリクエストをgo側で取得
- go言語でhtmlから取得したデータをjson形式で保存する
- golang 並列処理でリバースプロキシ
本題
実際にデータベースのレコードの構造は以下のようになっています。
id int
name varchar(8)
address varchar(32)
age int
このデータベースの複数レコードを取得します。
まずは下準備の受け取るデータ構造の定義とデータベースに接続する部分を書きます。
type Test struct {
Id int
Name string
Adress string
Age int
}
func connectionDB() *sql.DB {
dsn := "username:passwd@tcp(127.0.0.1:3306)/test?parseTime=true"
db, err := sql.Open("mysql", dsn)
if err != nil {
fmt.Println("Err1")
}
return db
}
次にデータを取得するコードを書きます
func getRows(db *sql.DB) *sql.Rows {
rows, err := db.Query("SELECT * FROM testlist")
if err != nil {
fmt.Println("Err2")
panic(err.Error())
}
return rows
}
DBを引数にしてクエリを実行してその行データを返す関数になっています。QueryとExecはおそらくExecを使うべきだとおもうのですが。。今度リファレンスを見ておきます。
最後にメイン関数です。
func main() {
db := connectionDB()
defer db.Close()
rows := getRows(db)
// 行データ取得
test := Test{}
var result []Test
for rows.Next() {
error := rows.Scan(&test.Id, &test.Name, &test.Adress, &test.Age)
if error != nil {
fmt.Println("scan error")
} else {
result = append(result, test)
}
}
fmt.Println(result)
}
var result []Test
をtests := new([]Test)
でデータ構造を作っていたらappend関数の部分でエラーを吐かれた。new()で変数を作るとappend struct to slice
のエラーを吐かれるのでそもそものメモリの割り当て方が違うのかな。。
まとめ
データベースにアクセスすることができてアプリケーションで実現できる幅がさらに広がってきました。
new の割り当てと 配列宣言のメモリの割り当ての部分を理解しておくべきだなと思いました。
参考