データベースドライバの特定とインポート

使用しているDBMSをサポートするデータベースドライバが必要です。データベース用のドライバを特定するには、SQLDriversを参照してください。

ドライバをコードで使用可能にするには、他のGoパッケージと同様にインポートします。以下はその例です:

  1. import "github.com/go-sql-driver/mysql"

ドライバパッケージから直接関数を呼び出さない場合(例えば、sqlパッケージによって暗黙的に使用される場合など)、アンダースコアでインポートパスを接頭辞付けする空のインポートを使用する必要があります:

  1. import _ "github.com/go-sql-driver/mysql"

注意: ベストプラクティスとして、データベース操作にデータベースドライバのAPIを使用することは避けてください。代わりに、database/sqlパッケージの関数を使用してください。これにより、コードがDBMSと緩やかに結合され、必要に応じて異なるDBMSに切り替えやすくなります。

データベースハンドルのオープン

  1. データベースハンドルは、接続文字列を受け取る`````sql.Open`````または`````sql.OpenDB`````を呼び出すことで取得できます。どちらも[`````sql.DB`````](https://pkg.go.dev/database/sql#DB)へのポインタを返します。
  2. **注意:** データベースの資格情報をGoソースから外に出しておくことを確認してください。詳細については、[データベース資格情報の保存](#store_credentials)を参照してください。
  3. <a name="open_connection_string"></a>
  4. #### 接続文字列を使用したオープン
  5. 接続文字列を使用して接続したい場合は、[`````sql.Open`````関数](https://pkg.go.dev/database/sql#Open)を使用します。文字列の形式は、使用しているドライバによって異なります。
  6. MySQLの例を以下に示します:
  7. ``````bash
  8. db, err = sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords")
  9. if err != nil {
  10. log.Fatal(err)
  11. }
  12. `

ただし、接続プロパティをより構造化された方法でキャプチャすることで、より読みやすいコードが得られることが多いです。詳細はドライバによって異なります。

例えば、前述の例を以下のように置き換えることができ、MySQLドライバのConfigを使用してプロパティを指定し、FormatDSN methodを使用して接続文字列を構築します。

  1. // Specify connection properties.
  2. cfg := mysql.Config{
  3. User: username,
  4. Passwd: password,
  5. Net: "tcp",
  6. Addr: "127.0.0.1:3306",
  7. DBName: "jazzrecords",
  8. }
  9. // Get a database handle.
  10. db, err = sql.Open("mysql", cfg.FormatDSN())
  11. if err != nil {
  12. log.Fatal(err)
  13. }

コネクタを使用したオープン

接続文字列では利用できないドライバ固有の接続機能を活用したい場合は、sql.OpenDB functionを使用します。各ドライバは独自の接続プロパティのセットをサポートし、DBMSに特有の接続要求をカスタマイズする方法を提供することがよくあります。

前述のsql.Openの例をsql.OpenDBを使用するように適応させると、以下のようなコードでハンドルを作成できます:

  1. // Specify connection properties.
  2. cfg := mysql.Config{
  3. User: username,
  4. Passwd: password,
  5. Net: "tcp",
  6. Addr: "127.0.0.1:3306",
  7. DBName: "jazzrecords",
  8. }
  9. // Get a driver-specific connector.
  10. connector, err := mysql.NewConnector(&cfg)
  11. if err != nil {
  12. log.Fatal(err)
  13. }
  14. // Get a database handle.
  15. db = sql.OpenDB(connector)

エラーの処理

ハンドルを作成しようとした際にエラーをチェックする必要があります。sql.Openのように。これは接続エラーではありません。代わりに、sql.Openがハンドルを初期化できなかった場合にエラーが発生します。これは、指定したDSNを解析できない場合などに発生する可能性があります。

接続の確認

データベースハンドルをオープンすると、sqlパッケージはすぐに新しいデータベース接続を作成しない場合があります。代わりに、コードが必要とする時に接続を作成することがあります。すぐにデータベースを使用しない場合は、接続が確立できることを確認するために、PingまたはPingContextを呼び出してください。

以下の例のコードは、接続を確認するためにデータベースにpingを送信します。

  1. db, err = sql.Open("mysql", connString)
  2. // Confirm a successful connection.
  3. if err := db.Ping(); err != nil {
  4. log.Fatal(err)
  5. }

データベース資格情報の保存

データベース資格情報をGoソースに保存することは避けてください。これにより、データベースの内容が他者に露出する可能性があります。代わりに、コードの外部に保存する方法を見つけてください。ただし、コードがDBMSと認証するための資格情報を取得できるようにします。

一般的なアプローチの1つは、プログラムが開始する前に環境にシークレットを保存することです。おそらくシークレットマネージャーから読み込まれ、その後、Goプログラムはos.Getenvを使用してそれらを読み取ることができます:

  1. username := os.Getenv("DB_USER")
  2. password := os.Getenv("DB_PASS")

このアプローチにより、ローカルテストのために自分で環境変数を設定することもできます。

リソースの解放

  1. 通常、リソースは、`````Close`````関数への呼び出しを遅延させることで閉じられ、リソースは囲む関数が終了する前に解放されます。
  2. 以下の例のコードは、[`````sql.Rows`````](https://pkg.go.dev/database/sql#Rows)によって保持されているリソースを解放するために`````Close`````を遅延させます。
  3. ``````bash
  4. rows, err := db.Query("SELECT * FROM album WHERE artist = ?", artist)
  5. if err != nil {
  6. log.Fatal(err)
  7. }
  8. defer rows.Close()
  9. // Loop through returned rows.
  10. `