0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JDBC / Spring JDBC / ORM(MyBatis・JPA)の違いまとめ

Posted at

はじめに

Javaでデータベースにアクセスする方法として、JDBCSpring JDBCORM(MyBatisやJPA/Hibernate を利用できる。
どれもDBアクセスのための仕組みであり、抽象度や役割に違いがある。
今まで役割の違いについて曖昧な状態で開発を行なっていたので、本記事では、理解を深めるために整理した。

1. JDBC(Java標準API)

  • Java標準のDBアクセスAPI
  • SQLを直接記述し、ResultSet からオブジェクトに変換する必要がある
// JDBCを直接利用する例
String sql = "SELECT id, name FROM products WHERE id = ?";
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
    conn = dataSource.getConnection();          // コネクション取得
    ps = conn.prepareStatement(sql);            // SQL準備
    ps.setString(1, "p01");                     // パラメータ設定
    rs = ps.executeQuery();                     // SQL実行
    if (rs.next()) {
        Product p = new Product(                // 結果をオブジェクトにマッピング
            rs.getString("id"),
            rs.getString("name")
        );
    }
} finally {
    if (rs != null) rs.close();                 // リソース開放
    if (ps != null) ps.close();
    if (conn != null) conn.close();
}

  • 標準APIの利用
  • SQLを完全に制御できる
  • 記述の冗長さ
  • 例外処理、リソース開放、マッピング処理の手間

2. Spring JDBC

  • Springが提供するJDBCラッパー
  • SQLは記述する必要があるが、例外処理やリソース開放を自動化できる
  • さらに RowMapper によってSQLの実行結果をオブジェクトに簡潔に変換できる
String sql = "SELECT id, name FROM products WHERE id = ?";

// queryForObject を使って1件だけデータを取得
Product product = jdbcTemplate.queryForObject(
    sql,                          // 実行するSQL
    new Object[]{"p01"},          // プレースホルダ(?)に渡すパラメータ
    (rs, rowNum) ->               // RowMapper: ResultSetの1行をオブジェクトに変換する処理
        new Product(
            rs.getString("id"),   
            rs.getString("name")  
        )
);

JDBCラッパーとは

  • JDBCそのものは低レベルAPIで、SQL実行・例外処理・リソース開放(close())などを全部自分で書く必要がある
  • それを簡単に扱えるように「便利メソッド」や「共通処理」を提供するのが ラッパー
  • つまり「JDBCを内部で呼び出しているけど、外からはもっとシンプルなコードで使えるようにした仕組み

RowMapper の正体

  • Spring JDBC が提供するインターフェース
public interface RowMapper<T> {
    T mapRow(ResultSet rs, int rowNum) throws SQLException;
}

1行のデータをJavaオブジェクトに変換するために利用する。

クラスで実装する場合

// Product エンティティ
public class Product {
    private String id;
    private String name;
    public Product(String id, String name) {
        this.id = id;
        this.name = name;
    }
}

// RowMapper 実装
public class ProductRowMapper implements RowMapper<Product> {
    @Override
    public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
        // ResultSet からデータを取り出して Product に変換
        return new Product(rs.getString("id"), rs.getString("name"));
    }
}

// 利用例
String sql = "SELECT id, name FROM products WHERE id = ?";
Product product = jdbcTemplate.queryForObject(
    sql,                         // 実行するSQL
    new Object[]{"p01"},         // パラメータ
    new ProductRowMapper()       // RowMapper 実装を渡す
);

ラムダ式で書く場合(Java 8以降)

String sql = "SELECT id, name FROM products WHERE id = ?";
Product product = jdbcTemplate.queryForObject(
    sql,
    new Object[]{"p01"},
    // RowMapper をラムダ式で記述
    (rs, rowNum) -> new Product(
        rs.getString("id"),   // id 列を取得
        rs.getString("name")  // name 列を取得
    )
);

👉 RowMapper は関数型インターフェースなので、クラスを定義せずに簡潔に記述できる。

3. ORM(MyBatis / JPA(Hibernate))

  • ORMはオブジェクトとテーブルのマッピングを自動化する仕組み
  • 内部的にはJDBCを利用

MyBatis

  • SQLを明示的に記述するスタイル
  • 結果セットとオブジェクトのマッピングを自動化できる
Mapper.xml
<select id="findProductById" resultType="Product">
  SELECT id, name FROM products WHERE id = #{id}
</select>

resultType="Product" を指定することで、MyBatis が SQLの実行結果(ResultSet)
Product クラスにマッピングしてくれている。

Product p = productMapper.findProductById("p01");

JPA / Hibernate

  • オブジェクト操作によるDBアクセスを実現
  • SQLをほとんど意識せずに利用できる
// Product エンティティを取得(裏では SELECT が実行される)
Product p = entityManager.find(Product.class, "p01");

4. 比較

特徴 JDBC Spring JDBC MyBatis JPA/Hibernate
SQL記述 必須 必須 必須 不要
マッピング 手動 RowMapper 自動 自動
自由度
利用対象 SQLを直接制御したい場合 SQLを記述しつつ効率化したい場合 SQL派で効率化を重視する場合 SQLを隠蔽しオブジェクト中心で開発したい場合

5. まとめ

  • JDBC … 基礎。SQLを完全に制御できるが冗長
  • Spring JDBC … JDBCラッパー。例外処理やリソース開放を自動化でき、RowMapperでマッピングも簡潔にできる
  • MyBatis … SQLを記述したい派に最適。SQL制御と効率化の両立
  • JPA/Hibernate … SQLを隠蔽し、オブジェクト操作中心の開発ができる
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?