Golang の DB 操作 ORM をいろいろしらべてみたい

DB をローカルの Mac で適当に動かして、Golang を書いて試していきたいと思います。
Docker で PostgreSQL を立てます。（立て方と準備は、[最後に記載しています](https://qiita.com/mochizukikotaro/items/b09116e0ad2d30e37098#postgresql-%E3%81%AE%E6%BA%96%E5%82%99))


当記事のサンプルコードをまとめて、GitHub においておきました。

- [mochizukikotaro/golang-orm-sample](https://github.com/mochizukikotaro/golang-orm-sample)



# Golang のコード

以下を試してみたいと思います。

- [x] database/sql
- [x] gorm ([GitHub](https://github.com/jinzhu/gorm) :star2: 6876)
- [x] gorp ([GitHub](https://github.com/go-gorp/gorp) :star: 2576)
- [x] dbr ([GitHub](https://github.com/gocraft/dbr) :star: 854)
- [ ] xorm ([GitHub](https://github.com/go-xorm/xorm) :star: 2409)
- [x] sqlx ([GitHub](https://github.com/jmoiron/sqlx) :star: 3405)
- [ ] genmai ([GitHub](https://github.com/naoina/genmai) :star: 143) (追記）

※ star 数は 2017/10/26 時点
※ 未チェックはまだ触れていません

# やること

以下のユーザデータを `select` するサンプルを考えてみたいと思います。

```postgres
postgres=# select * from users;
 id | name
----+------
  1 | taro
  2 | yuki
```


## database/sql

```go:main.go
package main

import (
	"database/sql"
	"fmt"
	_ "github.com/lib/pq"
)

func main() {

	type User struct {
		Id   int
		Name string
	}

	db, _ := sql.Open("postgres",
		"user=postgres password=pw dbname=postgres sslmode=disable")

	rows, err := db.Query(`SELECT * FROM "users"`)
	if err != nil {
		fmt.Println(err)
	}

	defer rows.Close()

	users := []User{}
	user := User{}
	for rows.Next() {
		err = rows.Scan(&user.Id, &user.Name)
		if err != nil {
			fmt.Println(err)
		}
		users = append(users, user)
	}
	fmt.Println(users)
}

```

これで、以下を得ました。

```
[{1 taro} {2 yuki}]
```

簡単ですね。


## gorm

```go
package main

import (
	"fmt"
	"github.com/jinzhu/gorm"
	_ "github.com/lib/pq"
)

func main() {

	type User struct {
		Id   int
		Name string
	}

	db, _ := gorm.Open("postgres",
		"user=postgres password=pw dbname=postgres sslmode=disable")
	defer db.Close()

	var users []User
	db.Find(&users) // SELECT * FROM users;
	fmt.Println(users)
}

```

すごく簡単ですね。

# gorp

```go
package main

import (
	"database/sql"
	"fmt"
	_ "github.com/lib/pq"
	"github.com/go-gorp/gorp"
)

func main() {

	dbmap := initDb()
	defer dbmap.Db.Close()

	users := []User{}
	dbmap.Select(&users, "select * from users")
	fmt.Println(users)
}

type User struct {
	Id   int
	Name string
}

func initDb() *gorp.DbMap {
	db, _ := sql.Open("postgres",
		"user=postgres password=pw dbname=postgres sslmode=disable")
	dbmap := &gorp.DbMap{Db: db, Dialect: gorp.SqliteDialect{}}
	dbmap.AddTableWithName(User{}, "users").SetKeys(true, "Id")
	return dbmap
}
```

うーん。

# dbr

```go
package main

import (
	"fmt"
	"github.com/gocraft/dbr"
	_ "github.com/lib/pq"
)

func main() {

	type User struct {
		Id   int
		Name string
	}

	conn, _ := dbr.Open("postgres",
		"user=postgres password=pw dbname=postgres sslmode=disable", nil)

	sess := conn.NewSession(nil)

	users := []User{}
	sess.Select("id", "name").From("users").Load(&users)
	fmt.Println(users)
}
```

うーん。

# sqlx

```go
package main

import (
	"fmt"
	"github.com/jmoiron/sqlx"
	_ "github.com/lib/pq"
)

func main() {

	type User struct {
		Id   int
		Name string
	}

	db, _ := sqlx.Open("postgres",
		"user=postgres password=pw dbname=postgres sslmode=disable")

	users := []User{}
	db.Select(&users, "select * from users")
	fmt.Println(users)
}

```

わあ、とても簡単だぁ。


# 感想まとめ

- Rails みたいにやるなら `gorm` かなぁ
- 生で `database/sql` だけでやるのもありかなぁ
- 生も好きだけど小気味よくいきたいなら `sqlx` かなぁ

個人的には `sqlx` が好きそうです。

注意) 今回は簡単な `select` しか試していないので、アレですが... 😶

# PostgreSQL の準備

まずは、コンテナを立てます。

```bash:コンテナたてる
$ docker run --name some-postgres -e POSTGRES_PASSWORD=pw -p 5432:5432 -d postgres
```

ログインができるようになります。

```bash:ログイン
$ psql -U postgres -h localhost
Password for user postgres:
```

psql 内で、適当に table と データを用意しておきます。

```psql:テーブルつくってデータいれる
postgres=# create table users (id serial, name varchar(80));
CREATE TABLE
postgres=# insert into users (name) values ('taro'), ('yuki');
INSERT 0 2
postgres=# select * from users;
 id | name
----+------
  1 | taro
  2 | yuki
(2 rows)
```