[Java] SQLを書かずにDB操作?Spring Data JPAの魔法を解明

こんにちは。ゆうせいです。

新人エンジニアのみなさん、Javaの学習は順調ですか?

Webアプリケーションを作るとき、避けて通れないのが「データベース(DB)」とのやり取りですよね。

「Javaのコードは書けるけど、SQL文を書くのが苦手…」

「Javaのオブジェクトを、いちいちDBのテーブルに合わせて変換するのが面倒くさい!」

そんなふうに感じたことはありませんか?

その面倒な作業を、驚くほど簡単にしてくれるのが JPA、そして Spring Data JPA です。

今回は、まるで魔法のようにデータベースを操れるこの技術について、専門用語を噛み砕いて解説していきます。これを知ると、もう昔のやり方には戻れなくなるかもしれませんよ!


そもそもJPAとは?

Spring Data JPAの話をする前に、まずは JPA(ジェイピーエー) について理解しましょう。

通常、Javaは「オブジェクト指向」という言葉で会話しますが、データベースは「リレーショナル(表形式)」という言葉で会話します。この2人は言語が違うため、そのままでは話が通じません。

そこで、プログラマーが間に立って「通訳(SQLを書く作業)」をする必要がありました。これが大変なんです。

ここで登場するのが ORM(オーアールエム) という技術です。

これは Object-Relational Mapping の略で、その名の通り「Javaのオブジェクト」と「DBのリレーショナルな表」を自動的に結びつけてくれる仕組みのことです。

JPA(Java Persistence API)は、このORMをJavaで扱うための「公式ルールブック(仕様)」だと思ってください。

翻訳機を使って会話するイメージ

  • 今までのやり方(JDBCなど)あなたが辞書を片手に、一言一句SQLという外国語に翻訳してDBに命令する。
  • JPAを使ったやり方優秀な翻訳機に「このデータを保存して」と日本語(Java)で伝えるだけで、勝手にSQLに変換してDBに伝えてくれる。

つまり、SQLを意識せずに、Javaのコードだけでデータベース操作ができるようになるのです。

Spring Data JPAは何がすごいの?

JPA自体も便利なのですが、Spring Frameworkはそれをさらに使いやすく進化させた Spring Data JPA という機能を提供しています。

これがどれくらいすごいかと言うと、「メソッドの名前を書くだけで、SQLが自動生成される」 ほどです。

例えば、ユーザーを探す機能を実装したいとします。

従来のJPAでは、少し複雑な設定やコードを書く必要がありました。

しかし、Spring Data JPAなら、インターフェースに以下のように書くだけです。

findByEmail(String email);

これだけで、裏側では SELECT * FROM user WHERE email = ? というSQLが自動的に作られ、実行されます。

「メールアドレスで(ByEmail)探して(Find)」というメソッド名から、やるべきことを推測してくれるのです。

コードで見る違い

百聞は一見に如かず。実際のコードのイメージを見てみましょう。

ここでは「ユーザー(User)」を保存する処理を比べてみます。

昔ながらのやり方(イメージ)

以前は、DBに接続して、SQL文を文字列として組み立てて…と、大変な労力が必要でした。

// SQL文を文字列で書かないといけない(間違いやすい!)
String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "Yusei");
// ...以下、接続を閉じる処理など長いコードが続く

Spring Data JPAのやり方

まず、DBのテーブルに対応する「Entity(エンティティ)」クラスを作ります。これが「Java側の分身」です。

@Entity // 「これはDBのテーブルと紐付きますよ」という目印
public class User {
    @Id
    @GeneratedValue
    private Long id;
    private String name;
    private String email;

    // 省略:getterやsetterなど
}

次に、「Repository(リポジトリ)」というインターフェースを作ります。これが魔法の杖です。

Java

// JpaRepositoryを継承するだけで、基本的な機能が全部手に入る
public interface UserRepository extends JpaRepository<User, Long> {
    // 追加のメソッド定義も不要(保存や検索は最初から持っている)
}

最後に、これを使う場所(Serviceなど)です。

Java

@Service
public class UserService {
    // 依存性の注入(DI)でリポジトリをもらう
    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void registerUser() {
        User user = new User();
        user.setName("Yusei");
        
        // たったこれだけ!SQLは一切書いていない!
        userRepository.save(user);
    }
}

いかがですか? save というメソッドを呼ぶだけで、インサート文が勝手に発行されます。

Javaのリストにデータを追加するような感覚で、データベースを操作できるのです。

メリット・デメリット

非常に強力なSpring Data JPAですが、良い点ばかりではありません。

現場で使うために、メリットとデメリットをしっかり把握しておきましょう。

メリット

  1. 開発スピードが圧倒的に上がる基本的なCRUD(作成・読み取り・更新・削除)の機能は最初から用意されているため、コードを書く量が劇的に減ります。
  2. SQLのミスがなくなる人間が手書きでSQLを書くと、スペルミスやカンマの忘れなどが起きがちですが、自動生成ならその心配はありません。
  3. DB製品の変更に強いMySQLからPostgreSQLに乗り換えることになっても、Javaのコードを書き直す必要はほとんどありません。JPAが方言の違いを吸収してくれます。

デメリット

  1. 「N+1問題」などのパフォーマンス問題が起きやすいこれが最大の落とし穴です。裏でどんなSQLが発行されているか見えにくいため、気づかないうちに「大量の無駄なSQL」が実行されてしまい、アプリが遅くなることがあります。
  2. 複雑なSQLは苦手何千行にも及ぶような複雑な集計や検索を行う場合、JPAでやろうとすると逆に難しくなることがあります。その場合は素直にSQLを書くことも必要です。
  3. 学習コストがかかる「魔法」の裏側には複雑な仕組みがあります。エラーが起きたとき、JPAの仕組み(Entityのライフサイクルなど)を知らないと解決できないことがあります。

今後の学習の指針

Spring Data JPAは、現代のJava開発において必須級のスキルです。

まずは以下のステップで学習を進めてみてください。

  1. 簡単なCRUDアプリを作るSpring Bootを使って、画面からデータを登録し、一覧表示するアプリを作ってみてください。save や findAll といったメソッドの便利さに感動するはずです。
  2. 「N+1問題」について調べるデメリットで挙げたパフォーマンス問題です。これは必ずぶつかる壁なので、「なぜ起きるのか」「どうやって防ぐのか(JOIN FETCHなど)」を早めに知っておくと、現場で「おっ、できるな」と思われます。
  3. JPQLを学ぶメソッド名だけでは表現できない複雑な検索をするために、Java専用のクエリ言語(JPQL)というものがあります。これも少しずつ覚えていきましょう。

最初は「SQLを書かなくていいなんて最高!」という入り口で大丈夫です。

そこから少しずつ「裏でどんなSQLが動いているのかな?」と興味を持つことが、脱初心者への近道ですよ。

それでは、また次の記事でお会いしましょう。

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。