2019/09/08

宮崎旅行

2018年7月の最後の週末に1日休みを追加して宮崎へ旅行へ行った。

1日目

早起きして羽田へ、7時過ぎには羽田に着いていた。
吉祥寺羽田間のバス回数券を持ってたので幾分楽に。
宮崎は初なのでちょっとドキドキ、羽田 - 女満別線と同サイズの小型機も久しぶりなので懐かしい気持ち。ソラシドエアーとANA共同運行。
やはり機内では寝てしまった。
朝10時に宮崎着。すぐにバスで鵜戸神社を目指す。
今回は良くも悪くも終始バスの旅となってしまった。途中で鬼の洗濯岩を見てかなり興奮。
人工物なんではないかと思ってしまった。
鵜戸神社は思ってたよりずっと遠く、やっと着いたという感じ。
やっと着いて、鵜戸神社を目指す参道はやはり南国へ来たと実感させる。
野生のバナナなどを見る。実際のとこ野生ではないかもしれないが、外に普通にバナナの木が生えているとはすごい。
鵜戸神社は岩の中にある。良い雰囲気の神社だった。
天気も晴れていて景色が良い。波が綺麗。そういえば台風が来ていて波は荒かった。
その後どこを観光するか迷うものの、全て出来るだけ見て回ることにして、バスでサンメッセ日南へ向かう。バス時間が合わず、鵜戸神社の茶屋で1時間ほどだらだら過ごす。
サザエのつぼ焼きがうまい。
その後サンメッセで降りて、炎天下上り坂を歩いてモアイへ。入場料も払ったがモアイはイマイチだったかも。
モアイの所のレストランではなく次の道の駅フェニックスで昼にすることにして、すぐ離れる。
ところがバスに乗り継いで行ったフェニックスではレストランが終了していた。
そこで名物っぽいソフトクリーム(日向夏)を食べ、再びバスで青島へ。
アオシマは立派な観光地で通りの屋台やら大きなお土産屋、カフェ、入らなかったが植物園などがあり、青島と砂浜がある。

青島観光の時点では疲れていたので、
早々に今度は電車で宿のある宮崎駅へ向かう。
ところがその青島駅と電車が混乱させる。
かなり人がいる観光地なのに駅は無人駅、しかも何番ホームにどこ行きが来るのか全く分からず。改札も券売機も無く、無人ホームで途方に暮れるが、スマホで調べ、2、3番ホームへ移動、来た電車に乗り、車内で切符を買う。
それが海幸山幸という名物の電車だった。内部が木でできていた。
宮崎に着いてホテルに着き、荷物を下ろすと一気に安心して疲れも吹っ飛ぶ。
宮崎の繁華街へ繰り出すと丁度道路を通行止にして、ソーラン祭りのような祭りをやっていた。今回は土日とも丁度その祭りで賑わっていて楽しかった。
ここだけ切り取ると祭り見学を目的に来た旅行客のよう。
まぁ地元の子供達の踊りにはあまり興味がなかったので早々に居酒屋へ。
鶏肉の藁焼き、牛肉の藁焼きがうまかった。生食はあまりしないのだが、ここではとてもうまかった。

店を出たらまだ19時過ぎで明るかった。
まだお祭りをやっていた。遠くの地でよさこいを見た。

2日目

1日目にほとんど見るべきところを見てしまったようで、さまようことになる日。
まずは宮崎市の博物館、資料館を見て回ってみた。修学旅行のようで悪くは無い。
その後有名であるシーガイアを横目に、宮崎市フェニックス自然動物園を目指してみる。
さすがに東京の近くにある動物園とは違って寂れた雰囲気は隠せないようだが、動物園、遊園地としてはまぁ楽しめた。近くの海岸を歩いている間に雨が降ってきて、市街にもどるため、バス停まで歩く。歩いている間に豪雨になり、びしゃびしゃになりながらバスを待つ。イオンモールで時間を潰し、再びバスでホテルに戻る。
2日目の夕食も市街地でふらふらと探したのだが、残念ながら1日目と同じ系列のお店に入ってしまったらしい。美味しいが、どうせなら別の店も覗いてみたかった。
そのため、2軒目としてスペイン料理屋をバーのように利用して、お酒を飲みつつ過ごす。
すっかり酔いながら、宮崎市の繁華街はまた来たいと思わせるいいところだった。
ホテルが提携しているというスーパー銭湯の入浴券をもらえたので行ってみる。
旅行に来て温泉に入るというのは本当によかった。

3日目

まぁ市街地やお土産やをみてさっさと空港に行き、時間まで過ごした。
いろいろ回りすぎて1度の旅行では見切れないような感想だったが、青島あたりで1日遊んで過ごすのが良いのかなというリゾート地の旅行に慣れていない感じ。
でも市街地でのんびり過ごしてお酒を飲むようなおっさん旅行をするのも良いかな。

2019/09/03

MySQLで複数カラムの値が重複している行をSELECTしたい

または

MySQLでUnique制約を後付けする時にDuplicateエラーが起きてしまった時の解消法

結論としては、以下のSQLを修正して流し、出てきた重複行を1行だけ残して削除する。
以下のSQLは2カラムの重複を検索する例だが、3カラムにすることも出来る。
SELECT
  *
FROM
  one_table t0
INNER JOIN (
  SELECT
    aaa_id, bbb_id
  FROM
    one_table
  GROUP BY
    aaa_id, bbb_id
  HAVING COUNT(*) >= 2
) t1
ON
  t0.aaa_id = t1.aaa_id
AND
  t0.bbb_id = t1.bbb_id

Unique制約を後付けしなければならない状況とは?

本来 aaa_idカラムとbbb_idカラムは以下のように2つでUniqueであるべきだったが、
aaa_id, bbb_id
    1 ,    1
    2 ,    2
うっかり運用開始時に付け忘れていて、しかもシステムで
aaa_id, bbb_id
    1 ,    1
    1 ,    1
    2 ,    2
    2 ,    2
のように重複させちゃっていて、慌てて後でUnique制約を追加する、ということが不幸にも起きた場合。
すでに重複してしまってると、Uniqueを付けることはできないのでDuplicateエラーが発生する。
そこで、処理時点で重複している行を上記の手順で炙り出し、出てきた重複行を、1行を残して全て消す、という修正をしてからUnique制約を付ける、というお話。全部消すとデータが消えるので注意が必要だ。

サービスを運用してると不幸にも何度か遭遇するので、すぐ呼び出せるようにメモしておく。

2019/09/02

DIとDIコンテナ

DIを理解していなくてもDIは使える

そもそもこの記事はDI、Dependency Injectionがどうしても理解できないけど不自由なく使ってる人の感想である。特にベースがJava脳なのでJavaのDIを使っている感想。
どのくらい使っているかと言うと書いているソースのほとんどに@Injectionが書かれているくらい毎日使っている。

DIの浅はかな理解

インジェクションする〇〇Serviceと言うクラスは、ぶっちゃけると〇〇Utilsクラスとして作りたいし、全てpublic staticなメソッドとして処理を書きたい。しかし、アプリケーション始動時に動的に読み込む設定などがあり、どうしてもstaticでは作れないクラス。

そんなときにDIコンテナーに渡してやるとアプリケーション全体からstaticインスタンスのように使えるようになる。newを使わずインスタンス化されたインスタンスをインスタンスプールから引っ張り出して使えるようになる。

あっさりとしたまとめ

staticでは作れず、うかつにnewするのも難しいようなクラスがある場合(こういう時、という例は思いつかないが)、
staticクラスにする方法を考えたり、シングルトンにする方法と一緒に、DIコンテナーに登録するという方法を調査してみると良いかもしれない。

おそらくこうかなと思うDIの理解

DI、DIコンテナの利点は「インターフェースとその実装に分けることで本番処理のクラスとモックアップ用のクラスに分けて実装できる」という説明をよく見る。
実際JavaのInterfaceで十分なんじゃ無いかと思ったりして、理解できない。

ではなぜInjectionを毎日のように使うか、というとフレームワークがDIを標準でサポートしているからだ。毎日使っているPlayFrameworkでは、Springのレイヤーモデルである、Controller、Service、Repositoryの相互保有関係をDIで行うことを標準としているからだ。
DIの、Injectionされる側、ServiceクラスやRepositoryクラスのインスタンス化、インスタンスプールへの登録は裏で勝手にやってくれるので@Injectionと書くと自然と使えるようになる。
DIの利点はFramework側の構築で十分に受けており、Frameworkを使って開発する側は、newを使った単なるインスタンス化、staticインスタンスで利用とあまり変わらない意識で使える、ということだろう。