環境
Spring boot
参考にしたサイト
Spring DATA JPAでデータ検索
JPQLの内部テーブル結合を試してみる
エラーメッセージ
MySQL server version for the right syntax to use near '' at line 1
もうこし長かったけど、構文エラーがあるよってエラー。
原因
JPQLの書き方が間違っていた!というか、MySQLのNativeQueryとはちょっと書き方がちがうんだなぁ~くらいの認識でしたけど、結構違う感じでしたね。
特に@OneToOne
とかの関連エンティティがある場合の扱い方が間違っていました。
外部キーで結合するので、LEFT JOIN
とか書いていたけど、それが原因でした。
application.propertiesに次のように書いて、SQLを参考にしました。コンソールに大量に表示されるようになります。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=true
けど、MySQLのSQL文とはなんかが違うみたいですね。
Hibernateってなに?
wikiによると
Java のためのオブジェクト関係マッピング (ORM) ライブラリであり、オブジェクト指向のドメインモデルを関係データベースにマッピングするためのフレームワークを提供する。
初心者には難しいですけど、多分の解釈でいうと、
データベースから取得してきたデータを、オブジェクトとかインスタンスのフィールドに代入して、以降はオブジェクトとして扱えるようにするためにHibernateっていうのがよしなにやってくれる
って認識で良さそうです。
PHPの学習をしているときには、
- DB接続
- レコード取得
- カラムを取得
- 配列に格納
- DB切断
って言う流れをそのまま書いてましたね。オブジェクトとかクラスをまだ知らないときです。
Javaをやりだして、早速クラスを勉強して、便利さもわかってきたところでなんとデーブルをそのままクラスと対応させることができるということもできることを理解しだしたのが最近です。
JPQLってなに?
JPAでDB(正確にはエンティティ)からデータを取得するSQLをJPQLと言います。
RepositoryでJPAが出てきてたな。これでデータベースから取得してクラスに格納できるようになるんだなと、なんとなく理解。
Repositoryでも@Queryアノテーションを付けてfindBy~みたいなメソッドを定義したことあったけど、なんのこっちゃわかっていませんでした。
でも今日わかったことが。
// 普通のSQL文を自分で書く
@Query(value="select * from なんちゃら~", nativeQuery = true)
// これがJPQLで、テーブルと紐付けたエンティティでSQL文を書ける的な
@Query("select エイリアス from オブジェクト エイリアス ~")
確かにわかりやすい記述ができるから便利だな~
エンティティの中に別のエンティティがあったらどうするの?
spring.jpa.show-sql=true
としていると、
jpaで発行されたSQLがコンソールに出力されるので、それを見ると、結合しているテーブルがある場合はleft outer join
って書いてました。
ちょっと複雑な条件の場合は生のSQL文を書いて、結合の部分はleft outer join
って書けばいいんだなとあいまいに考えていましたが、ちゃいましたね。
@OneToOneや@OneToManyなどのアノテーションで関連を記述していたら、そのエンティティを含むオブジェクトをデータベースから取得する際にjpaが勝手に中のエンティティのデータも持ってきてくれる。
イメージ
public class Book {
private Integer id;
private String name;
@OneToOne( fetch = FetchType.EAGER ,cascade = CascadeType.ALL)
@JoinColumn(name="buyer_id")
private Buyer buyer;
}
public class Buyer {
private name;
private address;
}
こんなイメージの関係性で、この場合は、
@Query("select b from Book b")
とするだけで、Buyerもちゃんと取ってきてくれる。
Joinとか書いてたら永遠に構文エラーが発生する
@Query("select b from Book b JOIN Buyer")
って書いてたら永遠に構文エラーになります。
しかもどこがおかしいっていうメッセージも、なんか場所がちがうんですよね。
near '' at line 1
``
ってどこ??`''`の中におかしいところがあるよってメッセージだけど、なんかちゃんと教えてくれませんでした。
### 結論!
JPQLとSQLは違うよっていう明確な、強い意志と理念が必要!!