iku8log

Webエンジニアのタダのメモ。

MyBatis Generatorの生成されたモデルでblobが分離される

MyBatis Generatorを使って、コードを自動生成したところ、DB上でtext型のカラムが分離されて他クラスに居たので、 なぜだろうと思って調べたメモ。

DBはMySQLを使用。

commentテーブルを例にとって。このテーブルには3カラムだけ。

カラム名 説明
id bigint(PK) プライマリーキー
userId bigint(index) ユーザID
text text型 コメント内容

どうやらMySQL上でtext型やPKのカラムは、コード自動生成後別クラスのモデルにされるらしい。 例えば以下自動生成されたコメントクラス

public class Comment extends CommentKey implements Serializable {
    private Long userId;
}

おや、userIdしかない。PKのidとかtextカラムは?

CommentKeyこれを継承しているよう。

CommentKeyクラスを見てみると

public class CommentKey implements Serializable {
    private Long id;
    private static final long serialVersionUID = 1L;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
}

なるほどPKはなぜか別クラスになっているらしい。

そして、textカラムはどこにいったかと言うと、

CommentWithBLOBsクラス

public class CommentWithBLOBs extends Comment implements Serializable {
    private String text;
    private static final long serialVersionUID = 1L;
    public String getText() {
        return text;
    }
    public void setText(String text) {
        this.text = text;
    }

テキスト型のカラムは、〇〇WithBLOBsクラスになるっぽい。

で、Commentを継承しているので、すべてのカラムの情報を取得する場合は、

CommentWithBLOBsクラスを使えば良さそう。


でも、Mapperの方にもちょっと問題があって、

PK(今回はlong型のid)を指定して、データを取得するとき、 long型のidをCommentMapperselectByPrimaryKey に与えられないっぽい。なぜなら。

 CommentWithBLOBs selectByPrimaryKey(CommentKey key);

こんな感じで、long型ではなく、CommentKey型を期待しているから。

ちょっと面倒なので、MyBatis Generatorの設定を見直す。

generator_config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="schema" defaultModelType="hierarchical">
// 以下省略

設定はどこからコピって来たので、あまり気にしてはいなかった。 どうも、defaultModelTypeが怪しそうなので、調べてみると。

このプロパティは生成方法らしい。 以下公式。 http://www.mybatis.org/generator/configreference/context.html

3つくらいあるが、hierarchicalを明示的に指定していたため、〇〇Keyや〇〇WithBlobsクラスが出来ていた。

シンプルが楽なので、デフォルトにしてやることにした。↓

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <context id="schema" defaultModelType="conditional" targetRuntime="MyBatis3">
// 以下省略

指定しなくても、デフォルト値なので一緒だが明示的にね。 あと、今回関係ないがtargetRuntimeもデフォルト値をセットしておいた。

やっぱり公式ちゃんと見ないとね。

【Mac】Intellij内でMacのfinderを使わない方法

macのfinderは使いづらいので、intellijでファイル開いたりする時に、デフォルトfinderじゃなくします。

以下すべてintellij上の操作です。phpstormとか他のソフトも同じなはず。

  1. cmd + shift + a(shift2回でも可)を押す
  2. registryと検索
  3. ide.mac.file.chooser.nativeを検索
  4. 3のチェックを外す

f:id:iku8:20190706160008p:plain

これでfileを開いた時に、finderは使わなくなります。安心安心。

gradleのapiとimplementationの指定で、依存関係を伝搬したりしなかったり

gradleのapiとimplementationの指定で、依存関係を伝搬したりしなかったりするらしい。

apiとimplementationの違いは伝搬するかどうか

gradleで以下のような記述がある

Aプロジェクト(伝搬する)

dependencies {
    api 'org.apache.commons:commons-lang3:3.7'
}

Aプロジェクト(伝搬しない)

dependencies {
    implementation 'org.apache.commons:commons-lang3:3.7'
}

違いとしては、

apiは他プロジェクトにcommons-lang3:3.7が伝搬する。つまり他のプロジェクトでも、 Aプロジェクトに依存していれば、commons-lang3:3.7が使える。

implementationは他のプロジェクトで、Aプロジェクトに依存していても、 commons-lang3:3.7は使えない。

Aプロジェクトに依存している状態というのは、以下な感じかな。

Bプロジェクト

dependencies {
    implementation project(':Aプロジェクト')
}

この例では、implementationを使っているので、Aプロジェクトで依存しているものをBで使うことは出来ない

compileは非推奨

compileはとっくに非推奨になっているので使っちゃダメ。 ちなみにcompileはapiと同じく伝搬する。

なるほどなるほど。理解できた。

参考(わかりやすい) Gradle の compile, api, implementation とかについて - Qiita

EC2 Linux2上に立てた、MySQL5.7のタイムゾーンをJSTにする

EC2 Linuxと書いていますが、あまり関係はなくMySQL5.7のタイムゾーン設定のメモです。

my.confにタイムゾーンの設定を書くだけだとうまく反映されず Fatal error: Illegal or unknown default time zone 'Asia/Tokyo' となってしまったので、メモ。

MySQL起動

my.cnfにタイムゾーンを設定して起動すると、コケて起動しないので、 まずはmy.cnfを何もいじらず起動する。

sudo systemctl start mydqld
sudo systemctl status mydqld

mysqlタイムゾーン初期化

参考: MySQLでタイムゾーンを設定する - Qiita

どうやらMySQLタイムゾーンがバカになっているので、初期化する

/usr/bin/mysql_tzinfo_to_sql /usr/share/zoneinfo > ~/timezone.sql
mysql_tzinfo_to_sql /usr/share/zoneinfo/ | mysql -u root -p

パスワードを求められ、入力後初期化が実行される

再起動時にコケる可能性があり、念の為一度MySQLを停止しておく。

sudo systemctl stop mydqld

タイムゾーン設定

/etc/my.cnfに設定を追記する。

[mysqld]
default-time-zone='Asia/Tokyo'

起動

sudo systemctl start mydqld
sudo systemctl status mydqld

これでNOW()関数を実行していみると、JST時間で表示されると思います。 SHOW VARIABLES LIKE '%time_zone%'; 上記のクエリで、タイムゾーンの設定が見え、JSTになっていることが分かります。

Intellij springboot アプリケーション起動時に「Module not specified」が出た

Module not specified がでた。

stackoverflow.com

どうやら、Use classpath of moduleを指定する必要があるらしい。これで治った。