DBから、jsonファイルの作成 ハマったところ
Goでデータベース(以下略:DB)の情報をブラウザ側に渡したい時に、jsonファイルで渡すことにしました。
DBの操作が出来れば、結構簡単に出来ると思います。
それでは、さっそくサンプルコードを見てみましょう。
DBのデータ取得
以前書いたもので、selectDB関数のところを参考にして頂ければ、DBから情報を取得出来ると思います。
JSONファイルに書き出す用の準備
上記のコードの変更点を注目していきたいと思います。
importに新たに"encoding/json"が追加されていますね。
こちらは、読んで字の如く、jsonファイルの形式にエンコード(変換)してくれます。
構造体の後ろに'json:"キー"'が追加されていますね。
キーがjsonでの変数名になります。
値(value)は構造体に入った値が入ります.
SELECTした値をjson形式にする
selectDB関数の変更点を見てみましょう。
結果
{"chord":"1","userName":"テスト 太郎","category":"男性","recordDate":"1970-08-22T19:13:38Z"}
{"chord":"2","userName":"テスト 花子","category":"女性","recordDate":"1970-08-22T19:13:38Z"}
正しい、json形式になっていますね。
json, _ := json.Marshal(user)が追加されていますね。
これで、json形式に直してくれます。
ちなみに、jsonBytesの型はuint8 (uint8のスライス)なので、そのまま出力されると、byteで出されるので人間にはなんのこっちゃになるので、今回は分かりやすくstring型にキャストしてあります。
ブラウザ側に送る際には、http.ResponseWriterのWrite(jsonBytes)で送りましょう。
ブラウザ側でパースすると通信での負荷が多少は減ります。
今回は、構造体の配列で渡していますが、mapのinterfaceでも渡すことができます。
ハマったところ
構造体の設定のところで躓きました。
原因のソース部分
結果
{}
{}
...はい。
さっきと何が違うの?と思うところはありますが、変数名が小文字になっています。
json.Marshalメソッドは、変数が大文字でないと上手く値を返してくれません。
private関数はどうやら認識してくれないようです。
json.Marshalを使う時には、public関数で使いましょう。
どう言う思想の元で作られたのかは分かりませんが、個人的にあまり好きではない仕様ですね。
この仕様の理由は、公式Docをみると、名前の競合の解決の為となっています。
Embedding types introduces the problem of name conflicts but the rules to resolve them are simple. First, a field or method
X
hides any other itemX
in a more deeply nested part of the type. Iflog.Logger
contained a field or method calledCommand
, theCommand
field ofJob
would dominate it.Second, if the same name appears at the same nesting level, it is usually an error; it would be erroneous to embed
log.Logger
if theJob
struct contained another field or method calledLogger
. However, if the duplicate name is never mentioned in the program outside the type definition, it is OK. This qualification provides some protection against changes made to types embedded from outside; there is no problem if a field is added that conflicts with another field in another subtype if neither field is ever used.
なるほど、と言いたい所ですがなんだかなぁと思います。
嫌なら、自分で作れってことですね😂
せめて、エラーで吐いてくれたら納得出来るのですが、nilで返ってきたお陰で原因が分かるのに時間を取られました🤣
個人的書き置き場
あとは、null対応ですが、sqlite3が優秀なのか、mattnさんが優秀なのか、ぬるぽが出ないので、新たにDB構築するのは面倒臭いので、また気が向いた時に書こうかなと思います。
ソースは載せませんが、一応、interfaceで対応は出来ます。
ソースのレビューもこうした方が良いよなどのご意見も随時募集しているので、コメント・twitterなどに言って頂けると幸いです。