Bonjour. Cette fois, je vais vous présenter comment faire fonctionner un conteneur Db2 configuré avec Docker avec Go. Reportez-vous aux articles suivants pour obtenir des informations sur la configuration d'un conteneur Db2 et sur l'insertion de données lors de l'installation.
Configurer un conteneur DB2 DB et insérer un peu de données Configuration avec les données de test initiales insérées dans le conteneur Db2 / DB
Cette fois, nous allons démarrer le conteneur Db2 avec des données insérées et introduire principalement l'implémentation dans Go.
Les codes peuvent être trouvés à ici.
C'est pour ceux qui ont pu insérer des données dans le conteneur Db2, mais comment obtenir réellement les données et les exploiter ou mettre à jour les données.
Cette fois, je vais vous présenter comment récupérer les données de Db2 en langage Go.
Getting Started L'environnement de développement est Windows, mais cela peut être fait sur Mac ou Linux.
Cette fois, nous nous concentrons sur la vérification de la communication avec Db2, nous ne l'avons donc pas transformée en API. J'écrirai un programme qui récupère simplement les données de Db2 et les envoie à la console. (Un jour, je présenterai également l'implémentation de l'API REST dans Go.)
Tout d'abord, je vais expliquer la structure des dossiers.
project
project
├─go
| ├─model
| | ├─user.go
| | ├─tweet.go
| | └─reply.go
| └─main.go
└─db
├─data
| ├─users_insert.csv
| ├─tweets_insert.csv
| └─replys_insert.csv
├─sql
| ├─users_create.sql
| ├─tweets_create.sql
| └─replys_create.sql
├─createschema.sh
├─Dockerfile
└─env.list
En fait, j'aimerais créer une conception axée sur le domaine, un domaine utilisateur, une infrastructure, etc. et faire une conception cool, mais c'est une autre opportunité.
Tout d'abord, construisez l'image du conteneur en utilisant Dockerfile
.
La commande à exécuter est la suivante.
$ cd db
$ docker build -t test-db:v1.0 .
Maintenant que l'image du conteneur est terminée, exécutons-la immédiatement.
$ docker run --name go-db --restart=always --detach --privileged=true -p 50000:50000 --env-file env.list test-db:v1.0
Des explications détaillées sont présentées sur ici.
L'important ici est que le port soit transféré à 50000: 50000. Gardez à l'esprit que le port 50000 exposé au client doit être spécifié lors de la connexion à la base de données.
Package à utiliser
3.1. go_ibm_db
基本的にGoでDb2を利用する際は、github.com/ibmdb/go_ibm_db
というパッケージを利用します。
Appuyez sur la commande suivante.
$ go get github.com/ibmdb/go_ibm_db
De plus, un pilote pour faire fonctionner SQL est nécessaire pour faire fonctionner la base de données. Puisqu'il y a diverses opérations, je vais le faire dans l'ordre.
まず、落としてきたgithub.com/ibmdb/go_ibm_db
を見に行きます。
Il est probablement déposé sous GOPATH
, donc si vous descendez dans cette hiérarchie, vous atteindrez un dossier appelé ʻinstaller. Le
setup.go` dans ce dossier est le script de téléchargement de clidriver.
$ cd PathToInstaller/installer
$ go run setup.go
Maintenant clidriver peut être téléchargé sous ʻinstaller`. (Si vous obtenez une erreur d'autorisation, essayez de modifier les autorisations dans le dossier du programme d'installation.) Je sens que cela prendra du temps.
Si vous pouvez le déposer en toute sécurité, vous devez passer le chemin de PathToInstaller / installer / clidriver / bin
, alors passons-le.
Ceci termine la configuration de go_ibm_db.
Si vous ne voulez pas déposer de paquets supplémentaires dans votre environnement, vous pouvez le faire avec go mod
.
Cependant, même dans ce cas, sqlcli.h
est requis, donc copiez le programme d'installation installé dans le projet, passez le chemin de clidriver / bin
avec un script shell, etc., et spécifiez le module à construire. Vous pouvez générer un fichier exécutable en faisant.
3.2. errors Il implémente également les erreurs, alors supprimez également le paquet ʻerrors`.
$ go get github.com/pkg/errors
Fondamentalement, l'implémentation est vraiment celle introduite dans 3. Je vais le présenter en examinant la fonction principale de main.go.
D'abord ce code
main.go
config := "HOSTNAME=localhost;DATABASE=USERDB;PORT=50000;UID=db2inst1;PWD=password"
conn, err := sql.Open("go_ibm_db", config)
if err != nil {
fmt.Printf("Échec de la connexion à la base de données.%+v", err)
}
defer conn.Close()
Stockez les informations de connexion à la base de données dans config. Sauf pour HOSTNAME et PORT, utilisez les informations sur env.list.
Connectez-vous avec la base de données avec sql.Open
en dessous.
Le premier argument spécifie le nom du pilote. Cette fois, c'est go_ibm_db
.
Le deuxième argument spécifie les informations de connexion à la base de données. Puisqu'il est possible de prendre une erreur, il est nécessaire de gérer l'erreur.
La connexion doit toujours être fermée, utilisez donc la pratique de Go pour fermer la connexion.
Vous avez maintenant obtenu une connexion avec le conteneur Db2. Nous allons l'utiliser pour manipuler les données.
Tout d'abord, nous obtenons tous les utilisateurs, stockons les informations dans la structure utilisateur et créons un tableau d'instances.
main.go
users, err := model.GetAllUser(conn)
if err != nil {
fmt.Printf("Échoué à obtenir%+v", err)
}
Regardons maintenant user.go, qui définit l'utilisateur DAO et DTO.
user.go
// User is users entity
type User struct {
id string
name string
mail string
password string
createdAt time.Time
updatedAt time.Time
}
func (u *User) String() string {
return fmt.Sprintf(
"Nom d'utilisateur:%s",
u.name,
)
}
// GetID returns user's id
func (u *User) GetID() string {
return u.id
}
La structure utilisateur définit les colonnes définies par table dans les champs. La méthode GetID est une méthode pour obtenir l'ID de l'utilisateur. J'écris ceci parce que les champs de la structure utilisateur sont spécifiés en privé pour transmettre l'ID aux requêtes dans d'autres tables. Eh bien, je pense que ce domaine fera des choses similaires dans d'autres langues.
En dessous, il existe une méthode pour obtenir tous les utilisateurs,
user.go
// GetAllUser returns all user instances
func GetAllUser(conn *sql.DB) ([]User, error) {
selectAllUserQuery := `SELECT * FROM users`
selectAllUserPstmt, err := conn.Prepare(selectAllUserQuery)
if err != nil {
return []User{}, errors.Wrapf(err, "La création de l'instruction a échoué")
}
var users []User
rows, err := selectAllUserPstmt.Query()
if err != nil {
return []User{}, errors.Wrap(err, "L'exécution de la requête a échoué")
}
for rows.Next() {
var user User
if err := rows.Scan(
&user.id,
&user.name,
&user.mail,
&user.password,
&user.createdAt,
&user.updatedAt,
); err != nil {
return []User{}, errors.Wrap(err, "Échec de la lecture des résultats")
}
users = append(users, user)
}
return users, nil
}
Il existe différentes manières de l'écrire ici, mais après avoir préparé l'instruction avec la méthode Prepare (), écrivez-la en exécutant la requête.
Lorsque vous faites cela, les enregistrements récupérés seront stockés dans des lignes
.
rows
a une méthode Next, et vous pouvez transformer chaque enregistrement avec une instruction for.
De plus, si vous passez les informations d'instance utilisateur à rows.Scan ()
, les informations d'enregistrement y seront stockées.
Vous avez maintenant stocké vos informations utilisateur dans votre instance utilisateur. Renvoie un tableau d'utilisateurs.
Revenons à la principale.
À partir de maintenant, l'ID est récupéré à partir de l'instance utilisateur, passé à la clause WHERE de Tweet, et l'enregistrement associé à l'utilisateur est récupéré. L'ID est ensuite extrait de l'enregistrement de tweet récupéré, la réponse qui lui est associée est récupérée et sortie, et elle est traitée pour l'enregistrement utilisateur.
main.go
//Étant donné que le nombre de cas est petit, utilisez une instruction triple for.
for _, user := range users {
fmt.Println(user.String())
tweets, err := model.GetAllTweets(conn, user.GetID())
if err != nil {
fmt.Printf("Échoué à obtenir%+v", err)
}
for _, tweet := range tweets {
fmt.Println(tweet.String())
replys, err := model.GetAllReplys(conn, tweet.GetID())
if err != nil {
fmt.Printf("Échoué à obtenir", err)
}
for _, reply := range replys {
fmt.Println(reply.String())
}
}
}
Pour passer l'ID à la clause WHERE
, définissez l'instruction SQL sur?
, CommeSELECT * FROM Tweets WHERE id_utilisateur =?
.
Vous pouvez personnaliser la clause WHERE en donnant un deuxième argument pour chaque paramètre.
Comment écrire
rows, err := selectAllTweetPstmt.Query(userID)
Ça ressemble à ça.
Lorsqu'elle est exécutée sous Windows, la partie japonaise sera affichée sous forme de caractères déformés lorsque la valeur est reçue du conteneur. Étant donné que le conteneur utilisé dans Db2 est un conteneur Linux, il semble que cela soit dû au fait que la chaîne de caractères est envoyée avec le code de caractère UTF-8.
Le résultat de l'exécution est le suivant.
Nom d'utilisateur:hoge
Corps du Tweet:�����̓e�X�g�ł��B,Date de création:2020-10-09 12:00:00 +0900 JST
Répondre nom d'utilisateur:fugaaaa,Texte de réponse:�e�X�g�m�F���܂����B,Date de création:2020-10-11 12:00:00 +0900 JST
-----------------------
Nom d'utilisateur:fuga
Corps du Tweet:�����̓e�X�g�ł��B,Date de création:2020-10-10 12:00:00 +0900 JST
Répondre nom d'utilisateur:hogeeee,Texte de réponse:�e�X�g�m�F���܂����B,Date de création:2020-10-11 12:00:00 +0900 JST
-----------------------
Eh bien, les personnages sont déformés. triste. C'est pourquoi je publierai le résultat de l'exécution sur Mac.
Nom d'utilisateur:hoge
Corps du Tweet:C'est un test.,Date de création:2020-10-09 12:00:00 +0900 JST
Répondre nom d'utilisateur:fugaaaa,Texte de réponse:J'ai confirmé le test.,Date de création:2020-10-11 12:00:00 +0900 JST
-----------------------
Nom d'utilisateur:fuga
Corps du Tweet:C'est un test.,Date de création:2020-10-10 12:00:00 +0900 JST
Répondre nom d'utilisateur:hogeeee,Texte de réponse:J'ai confirmé le test.,Date de création:2020-10-11 12:00:00 +0900 JST
-----------------------
Comme ça, je peux l'obtenir à partir de Db2.
J'ai introduit la méthode de connexion au conteneur Db2 avec Go, malgré les effets néfastes du code de caractère.
Avec cela, le développement d'API peut être fait facilement.
Recommended Posts