LoginSignup
1
4

More than 1 year has passed since last update.

【Go】Go言語でDB接続

Last updated at Posted at 2022-09-25

【前提】

editor:VsCode

DB:data.sqlite3
機能:スキャナーへ入力してDMLが出来るように実装する。

//スキャナの生成の為のパッケージを作成します。
※ファイル名は拡張子をgoにする。→input.go等

package hello

import (
	"bufio"
	"fmt"
	"os"
)

func Input(msg string) string {
	scanner := bufio.NewScanner(os.Stdin)//入力を受け付けるスキャナ
	scanner.Scan()//入力を取得する
	return scanner.Text()//コンソールに出力
}

Go>src>の階層に上記ファイルを保存する。

【import】

※data.sqlite3のインストールの仕方については省きます。

package main

import (
	"database/sql"
	"fmt"
	"hello"
	"strconv"

	_ "github.com/mattn/go-sqlite3"
)

【構造体を作成】

レコードを保存する為の構造体を生成します。
type Mydata struct {
	ID   int
	Name string
	Mail string
	Age  int
}

【DBアクセス】

func main() {
    //ドライバ名:"sqlite3",データベース名:"data.sqlite3"
	con, er := sql.Open("sqlite3", "data.sqlite3")
	if er != nil {
		panic(er)
	}
	defer con.Close() DBの開放処理

    //操作したDB操作を標準入力する
	flg := hello.Input("all or id or other or insert or update or delete ") 

    //上記標準入力に応じたメソッドが作動する。
	if flg == "all" {
		findAll(con) //全件検索
	} else if flg == "id" {
		findUserById(con) //ユーザID検索
	} else if flg == "other" {
		findUserByNameOrMail(con) //ユーザ名検索
	} else if flg == "insert" {
		insert(con) //ユーザ登録
	} else if flg == "update" {
		update(con) //ユーザ情報更新
	} else if flg == "delete" {
		delete(con) //ユーザ削除
	} else {
		fmt.Println("error") //エラー出力
		return
	}

}

【使用するクエリ文一覧】

var all string = "select * from mydata"
var qry string = "select * from mydata where id=?"
var qry2 string = "select * from mydata where name like ? or mail like ?"
var qry3 string = "insert into  mydata (name,mail,age) values(?,?,?)"
var qry4 string = "update mydata set name=?,mail=?,age=? where id=?"
var qry5 string = "delete from mydata where id=?"

【出力メソッド】

構造体の情報が「String型」で出力されるように調整します。
※strconv.Itoa()はint型をstring型に変換するメソッドです。

func (m *Mydata) Str() string {
	return "<\"" + strconv.Itoa(m.ID) + ":" + m.Name + "\"" + m.Mail + "," +
		strconv.Itoa(m.Age) + ">"
}

【レコード情報の取り出しメソッド】

ScanでMydata内の各変数に引数を設定する。
※Scanは現在のカーソルにあるレコードから情報を取り出します。
レコードかr赤くカラムの値を取り出し、それを引数に用意されている変数に代入します。
引数の&(アンパサンド)は参照値渡しになります。

func cursor(md *Mydata, rs *sql.Rows) *Mydata {
	er := rs.Scan(&md.ID, &md.Name, &md.Mail, &md.Age)
	if er != nil {
		panic(er)//取り込みに失敗したらエラーを返す
	}
	return md
}

【全件検索メソッド】

func findAll(con *sql.DB) {
    //変数rsはレコードの結果を格納する。
	rs, er := con.Query(all)
	if er != nil {
		panic(er)
	}
	for rs.Next() {
        //Nextメソッドはカーソルを次のレコードに移動させる。
		var md Mydata  //構造体を生成
		md = *cursor(&md, rs)  //cursorメソッドで構造にレコードを代入
		fmt.Println(md.Str()) //Str()でコンソールに構造体の情報を出力
	}

	fmt.Println("end")
}

【ユーザID検索】

func findUserById(con *sql.DB) {
	for true {
		s := hello.Input("id")
		if s == "" {
			break
		}
		n, er := strconv.Atoi(s)
		if er != nil {
			panic(er)
		}

		rs, er := con.Query(qry, n)
		if er != nil {
			panic(er)
		}
		for rs.Next() {
			var md Mydata
			md = *cursor(&md, rs)
			fmt.Println(md.Str())
		}

	}
	fmt.Println("end")
}

【名前またはメール検索】

func findUserByNameOrMail(con *sql.DB) {
	for true {
		s := hello.Input("findUserByNameOrMail")
		if s == "" {
			break
		}
		rs, er := con.Query(qry2, "%"+s+"%", "%"+s+"%")
		if er != nil {
			panic(er)
		}
		for rs.Next() {
			var md Mydata
			md = *cursor(&md, rs)
			fmt.Println(md.Str())
		}

		fmt.Println("end")
	}
}

【ユーザ登録】

func insert(con *sql.DB) {
	nm := hello.Input("name")
	ml := hello.Input("mail")
	age := hello.Input("age")
	ag, _ := strconv.Atoi(age)

	con.Exec(qry3, nm, ml, ag)
	fmt.Println("入力完了")
}

// 構造体の生成
func mydatafmRw(rs *sql.Row) *Mydata {
	var md Mydata
	er := rs.Scan(&md.ID, &md.Name, &md.Mail, &md.Age)
	if er != nil {
		panic(er)
	}
	return &md
}

【ユーザ情報変更】

func update(con *sql.DB) {
	ids := hello.Input("update ID")             //アップデートするIDを入力
	id, _ := strconv.Atoi(ids)                  //stringからintに変換
	rw := con.QueryRow(qry, id)                 //クエリの結果を格納
	tgt := mydatafmRw(rw)                       //クエリの結果から構造体を生成
	ae := strconv.Itoa(tgt.Age)                 //intからstringに変換
	nm := hello.Input("name(" + tgt.Name + ")") //変更後のユーザー名を入力
	ml := hello.Input("mail(" + tgt.Mail + ")") //変更後のメールアドレスを入力
	ge := hello.Input("age(" + ae + ")")        //変更後の年齢を入力
	ag, _ := strconv.Atoi(ge)

	//入力がなければ変更を加えない
	if nm == "" {
		nm = tgt.Name
	}
	if ml == "" {
		ml = tgt.Mail
	}
	if ge == "" {
		ag = tgt.Age
	}

	con.Exec(qry4, nm, ml, ag, id)
	fmt.Println("更新完了")

}

【ユーザ削除】

func delete(con *sql.DB) {
	idd := hello.Input("select id for deleting")
	id, er := strconv.Atoi(idd)
	if er != nil {
		panic(er)
	}

	con.Exec(qry5, id)
	fmt.Println("更新完了")
}

【実行】

all or id or other or insert or update or delete : all //DB操作を入力
//今回の場合であればユーザ一覧が表示される
<"1:Taro"taro@yamada,39> 
<"2:Hanako"hanako@flower,28>
<"3:Sachiko"sachiko@happy,17>
<"4:Jiro"jiro@change,6>
end
1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4