0
0

More than 3 years have passed since last update.

【Go】xormの使い方 その②

Posted at

はじめに

前回に続いて、xorm使い方その②です。
前回の続きですので、xormの導入などは終わっている程で話を進めます。
今回はいろんなメソッドを解説しようと思います。
今回解説するのは、以下の通りです。

目次

  • Table
  • Select
  • Sum, SumInt
  • Where, And, Or
  • OrderBy, Asc, Desc
  • SQL, Query

環境

go 1.15
github.com/go-sql-driver/mysql v1.6.0
xorm.io/xorm v1.2.3

DBのデータ

今回はこちらのデータを使用します。
スクリーンショット 2021-09-05 23.36.34.png

enginの用意

package main

import (
    "fmt"
    "log"
    "time"

    _ "github.com/go-sql-driver/mysql"
    "xorm.io/xorm"
)

type User struct {
    Id       int64 `xorm:"id"`
    Name     string
    Age      int
    Password string    `xorm:"password"`
    Created  time.Time `xorm:"created"`
    Updated  time.Time `xorm:"updated"`
}

func main() {
    engine, err := xorm.NewEngine("mysql", "root:root@tcp([127.0.0.1]:3306)/sample_db?charset=utf8mb4&parseTime=true")
    if err != nil {
        log.Fatal(err)
    }

    err = engine.Sync2(new(User))
    if err != nil {
        log.Fatal(err)
    }

    // メソッドを実行します
    // Table(*engine)
    // Select(*engine)
    // SetID(*engine)
    // Sum(*engine)
    // SumsInt(*engine)
    // WhereAnd(*engine)
    // WhereOr(*engine)
    // OrderBy(*engine)
    // Asc(*engine)
    // Desc(*engine)
    // SQL(*engine)
    // Query(*engine)
}

これでenginの用意が整いました。
以下は、main.goにメソッドを作成したら、こうなるというのを解説していきます。

Table

これは操作するテーブルを指定するだけです。
簡単です。

func Table(engine xorm.Engine) {
    user := User{}
    // ここでテーブルをユーザーテーブルを指定します。
    session := engine.Table("user")
    _, err := session.Where("id = ?", 1).Get(&user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("user:", user)
}

出力結果

user: {1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST}

テーブルを指定して、sessionに入れます。
それをWhereで条件を指定し、Getでマッピングします。
Tableでテーブルを指定しなくても、構造体から勝手に判断してくれます。
前回やった下記のコードでも同じように取得出来ます。

func Get(engine xorm.Engine) {
    user := User{}
    _, err := engine.Where("id = ?", 1).Get(&user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("user:", user)
}

結果は同じですが、Tableを使った方が明示的で分かりやすいです。

Select

SQLのSELECTと同じです。カラム名を指定します。

func Select(engine xorm.Engine) {
    user := User{}
    // ここでテーブルをユーザーテーブルを指定します。
    session := engine.Table("user")
    result, err := session.Select("name").Get(&user)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("user:", user)
    fmt.Println("result:", result)
}

出力結果

user: {0 花子 0  0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC}
result: true

カラムを指定しても、Getの返り値resultはtrueかfalseです。
構造体Userにはnameのカラムだけ入るので、結果は名前だけ更新されています。

Sum, SumInt

指定したカラムの値を合計します。
カラムの数を数えるのではないのでご注意ください。

func Sum(engine xorm.Engine) {
    user := User{}
    sumFloat64, _ := engine.Sum(user, "id")
    print(" sumFloat64: ", sumFloat64)
}

func SumsInt(engine xorm.Engine) {
    user := User{}
    sumInt, _ := engine.SumInt(user, "id")
    print(" sumInt: ", sumInt)
}

出力結果

sumFloat64: +6.000000e+000
sumInt: 6 

普通のSumはFloat64が返ってきます。
intで返して欲しい場合は、SumIntを使います。

Where, And, Or

この3つはSQLと同じように使います。

func WhereAnd(engine xorm.Engine) {
    users := []User{}
    session := engine.Table("user")
    err := session.Where("id > ?", 1).And("age = ?", 30).Find(&users)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("whereAndUsers:", users)
}

func WhereOr(engine xorm.Engine) {
    users := []User{}
    session := engine.Table("user")
    err := session.Where("id > ?", 1).Or("age = ?", 30).Find(&users)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("whereOrUsers:", users)
}

WhereAndはidが1より大きく、かつ、ageが30のユーザーを取得します。
WhereOrはidが1より大きい、もしくは、ageが30のユーザーを取得します。

出力結果

whereAndUsers: [{2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST}]
whereOrUsers: [{1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST}]

OrderBy, Asc, Desc

これも基本的には、ほとんどSQLと同じです。

func OrderBy(engine xorm.Engine) {
    users := []User{}
    session := engine.Table("user")
    err := session.OrderBy("id DESC").Find(&users)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("users:", users)
}

出力結果

users: [{3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST}]
func Asc(engine xorm.Engine) {
    users := []User{}
    session := engine.Table("user")
    err := session.Asc("id").Find(&users)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("AscUsers:", users)
}

出力結果

AscUsers: [{1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST}]
func Desc(engine xorm.Engine) {
    users := []User{}
    session := engine.Table("user")
    err := session.Desc("id").Find(&users)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("DescUsers:", users)
}

出力結果

DescUsers: [{3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST}]

.OrderByでidだけを指定すると、ASCになります。
.OrderByのidの後ろのDESCはDescでもdesc大丈夫です。
ただ単に昇順や降順にするだけなら、.Ascか.Descを使った方が分かりやすいですね。

SQL, Query

xormは生のSQLのQueryも実行出来ます。

func SQL(engine xorm.Engine) {
    users := []User{}
    err := engine.SQL("select * from user").Find(&users)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("users:", users)
}

出力結果

users: [{1 花子 30 パスワード 2021-08-29 16:47:24 +0900 JST 2021-08-29 16:47:24 +0900 JST} {2 たけし 30 パスワード 2021-08-29 16:48:42 +0900 JST 2021-08-29 16:48:42 +0900 JST} {3 太郎 20 パスワード 2021-08-29 16:49:35 +0900 JST 2021-08-29 16:49:35 +0900 JST}]
func Query(engine xorm.Engine) {
    results, err := engine.Query("select * from user")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println("results:", results)
}

出力結果

results: [map[age:[51 48] created:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 55 58 50 52 90] id:[49] name:[232 138 177 229 173 144] password:[227 131 145 227 130 185 227 131 175 227 131 188 227 131 137] updated:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 55 58 50 52 90]] map[age:[51 48] created:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 56 58 52 50 90] id:[50] name:[227 129 159 227 129 145 227 129 151] password:[227 131 145 227 130 185 227 131 175 227 131 188 227 131 137] updated:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 56 58 52 50 90]] map[age:[50 48] created:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 57 58 51 53 90] id:[51] name:[229 164 170 233 131 142] password:[227 131 145 227 130 185 227 131 175 227 131 188 227 131 137] updated:[50 48 50 49 45 48 56 45 50 57 84 49 54 58 52 57 58 51 53 90]]]

SQLもQueryもどちらも生のSQL文を使えますが、Queryはbyteで返って来ます。
SQLの方が使いやすそうです。

さいごに

他にも色々ありますが、今回はこの辺で。

参考

0
0
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
0
0