8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Golang + echo】GoとechoでSQLのデータを表示【PostgreSQL】

Last updated at Posted at 2019-12-11

1.はじめに

記事をご覧いただきありがとうございます。

今までC#とMySQLの接続は行ったことがあったのですが
ほとんど触れたことのないGo言語(+echo)とPostgreSQLとの接続
を行うことになったので備忘録的に手順を記していこうかと思います。

初歩的なところから説明するので適宜読み飛ばしていただければと思います。

2.PostgreSQLの設定

2-1.PostgreSQLのダウンロード

PostgreSQLのHPにアクセスしてダウンロードをクリック

無題.png

Binary packagesの中から自分のOSをクリック

無題.png

ページ内のDownload the installerをクリック(今回はWindowsですが他も同じ手順です。)

無題.png

自分のOSの使いたいバージョンのDownloadをクリック
(今回はWindowsx86-64の12.1バージョンをダウンロードしました。)

無題.png

2-2.PostgreSQLのインストールと環境変数設定(Windows10)

ダウンロードした**postgresql-(バージョン数)-(OS名)アプリケーションを実行し
このような画面が出たら基本的に
Next>**を押し続けてください。
passwordだけは自分で設定しますが、portは基本的に干渉しなければ変えなくてよいと思います

image.png

インストールが完了したらシステム環境変数を設定します。
PostgreSQLをインストールした場所の中のbinフォルダがある場所
(変更していなければ、C:\Program Files\PostgreSQL(バージョン数))
にPathを通します。

Windows10の場合、スタートメニューを右クリック>設定で以下の画面が出るので
「システム環境」と入力すると「システム環境変数」が出てきます。

image.png

下のような画面が出てくるので環境変数をクリック

image.png

システム環境変数のPathをクリックして編集>前のパスの間に**;(セミコロン)**を
はさんでPostgreSQLをインストールした場所の中のbinフォルダがある場所のパスを入力

無題.png

image.png

ここまで終わったらコマンドプロンプトを起動し、

psql --varsion

と入力してPostgreSQLのバージョン数が出ればインストール完了です。

3.echoのインストール

下のコマンドで一発でインストールできます。

go get -u github.com/labstack/echo...

4.SQLのデータをc.Stringでreturnするプログラム

4-1.概要

PostgreSQLの表示パターンを2個作っていきます。

  • sql.GetPost()

URLのプレースホルダからidをもらってきて
idが一致するレコードを表示する。

  • sql.GetPosts()

postsテーブルのレコードをすべて表示する。

4-2.データベースとテーブル作成

コマンドプロンプトでPostgreSQLにログインする
下のコマンドを打ってパスワードを入力

psql -U postgres

今回はsampleという名前のDBを作るので
下のコマンドを入力

CREATE DATABASE sample

先ほど作ったデータベースに接続するコマンドを入力

¥c sample

sampleデータベースにpostsテーブルを作る

create table posts (
  id integer, 
  content varchar(80),
  content author(80)
);

postsテーブルにレコード挿入する(お好きなだけどうぞ)

insert into posts values (1, 'test', 'test1user');
insert into posts values (2, 'testtest', 'test2user');
insert into posts values (3, 'testtesttest', 'test3user');

以上でPostgreSQLの操作は完了です。

4-3.フォルダ構成

作業フォルダ--- main.go
             ∟ sql      --- sql.go

4-4.main.go

package main

import (
    "github.com/labstack/echo"
    "github.com/labstack/echo/middleware"
    "github.com/~/sql"   //SQLについて記述したパッケージのパス
)

func main() {
    // Echoのインスタンス
    e := echo.New()

    // ミドルウェア類
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Use(interceptor.BasicAuth())

    // ルーティング
    e.GET("/sql/record/:id", sql.GetPost()) //プレースホルダでidをもらってくる
    e.GET("/sql/table", sql.GetPosts())

    // サーバー起動
    e.Start(":1323")
}

【ポイント】

  • 基本的にmain.goにはルーティングをだけをしています。

4-5.sql.go

package sql

import (
	"database/sql"
	"net/http"
	"github.com/labstack/echo"
	"github.com/pkg/errors"
	_ "github.com/lib/pq"
	"strconv"
)

type Post struct {
	Id      int
	Content string
	Author  string
}

var content string

var Db *sql.DB

func init() {
	var err error
	Db, err = sql.Open("postgres", "user=postgres dbname=sample password=自分で設定したパスワード sslmode=disable")
	if err != nil {
		panic(err)
	}
}

func GetPost() echo.HandlerFunc {
	return func(c echo.Context) error {
		id := c.Param("id")  //プレースホルダのidを取得
		post := Post{}
		if err := Db.QueryRow("select id, content, author from posts where id = $1", id).Scan(&post.Id, &post.Content, &post.Author); err != nil {
			return errors.Wrapf(err, "connot connect SQL")
		}
		return c.String(http.StatusOK, " ID : " + strconv.Itoa(post.Id) + " CONTENT : " + post.Content + " AUTHOR : " + post.Author)
		// string(Post.Id)だと何故かファイルダウンロードしてしまい、IDも表示されない。
		// strconv.Itoa(post.Id) の部分はプレースホルダから取り出したidでも可
	}
}

func GetPosts() echo.HandlerFunc {
	return func(c echo.Context) error {
		post := Post{}
		response := ""

		rows, err := Db.Query("select id, content, author from posts")
		if err != nil {
			return errors.Wrapf(err, "connot connect SQL")
		}
		defer rows.Close()

		for rows.Next(){
			if err := rows.Scan(&post.Id, &post.Content, &post.Author); err != nil {
				return errors.Wrapf(err, "connot connect SQL")
			}
			response += "ID : " + strconv.Itoa(post.Id) + "	CONTENT : " + post.Content + "	AUTHOR : " + post.Author + "\n"
		}

		return c.String(http.StatusOK, str)

	}
}

【ポイント】

  • Db.QueryRowは1つのレコードを取得する関数でDb.Queryは複数のレコードを取得する関数
  • post.Idに関してはint型なのでstring(Post.Id)にキャストしようと思うと思いますが
     それだと変な挙動をしてしまうので、strconvをインポートして**strconv.Itoa(post.Id)**とすることできちんと動きます。
  • GetPosts()のほうは何回もreturnすることができないのでresponseという文字列にすべての結果を格納して表示しています。

4-6.実行画面

  • sql.GetPost()
無題.png
  • sql.GetPosts()
無題.png

5.SQLのデータをc.JSONでreturnするプログラム(12.12 追記)

記事を投稿した後にAPIサーバで使うならc.JSONで返すプログラムでなければならないな…
と思いc.JSONでreturnするプログラムに作り変えてみました。

main.goは変更していないので4-4をご覧ください。

5-1.sql.go

package sql

import (
	"database/sql"
	"net/http"
	"github.com/labstack/echo"
	"github.com/pkg/errors"
	_ "github.com/lib/pq"
)

type Post struct {
	Id      int	`json:"id"`
	Content string	`json:"content"`
	Author  string	`json:"author"`
}

var content string

var Db *sql.DB

func init() {
	var err error
	Db, err = sql.Open("postgres", "user=postgres dbname=sample password=自分で設定したパスワード sslmode=disable")
	if err != nil {
		panic(err)
	}
}

func GetPost() echo.HandlerFunc {
	return func(c echo.Context) error {
		id := c.Param("id")
		post := Post{}
		posts := []*Post{}

		if err := Db.QueryRow("select id, content, author from posts where id = $1", id).Scan(&post.Id, &post.Content, &post.Author); err != nil {
			return errors.Wrapf(err, "connot connect SQL")
		}

		posts = append(posts, &Post{Id: post.Id, Content: post.Content, Author: post.Author})
		return c.JSON(http.StatusOK, posts)
	}
}

func GetPosts() echo.HandlerFunc {
	return func(c echo.Context) error {
		post := Post{}
		posts := []*Post{}

		rows, err := Db.Query("select id, content, author from posts")
		if err != nil {
			return errors.Wrapf(err, "connot connect SQL")
		}
		defer rows.Close()

		for rows.Next(){
			if err := rows.Scan(&post.Id, &post.Content, &post.Author); err != nil {
				return errors.Wrapf(err, "connot connect SQL")
			}
			posts = append(posts, &Post{Id: post.Id, Content: post.Content, Author: post.Author})
		}

		return c.JSON(http.StatusOK, posts)

	}
}

【ポイント】

  • structにjson:"○○"を追加する
  • postsにデータをappendしてからreturn

5-2.実行例

  • sql.GetPost()
    image.png

  • sql.GetPosts()
    image.png

6.終わりに

GoもechoもPostgreSQLも初心者なのでざっとした流れとSQLのデータ表示についてまとめてみました。
まとめてくれているサイトなどがかなり少なかったので同じようなことに迷っている人の
助けになれば幸いです。

何か間違っているところや改善したほうがいいところなどありましたら教えていただけると幸いです。

7.参考文献

8
2
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
8
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?