【Java完全攻略】自作ORMライブラリの作り方|アノテーション×リフレクションで構築!

プログラミング

「HibernateやJPAを使っているけど、なぜ動くのか仕組みを知りたい」
「SQLを自動で生成する処理を自分でも作ってみたい」
そんな思いをお持ちの方におすすめなのが、JavaでのORMライブラリの自作体験です。

本記事では、リフレクション・アノテーション・SQL文字列の動的生成を使って、
初心者でも構築できるシンプルなORMライブラリの作り方を、
コード付きでわかりやすく解説いたします。


ORMライブラリとは何か?

SQL操作をコードで簡単に扱える仕組み

結論:ORMとは「データベースとJavaのクラスを結びつける仕組み」です。

従来、データベース操作にはSQL文の記述が必要でした。
しかしORMを使えば、SQL文を直接書かずに以下のような操作ができます:

  • データの取得(SELECT)
  • データの登録(INSERT)
  • データの更新(UPDATE)
  • データの削除(DELETE)

これにより、保守性・可読性・安全性が大きく向上します。


自作ORMの基本構成を理解する

最小限で動く構成を設計します

結論:以下の4ファイルだけで簡易ORMは構築可能です。

1
2
3
4
5
src/
├─ Entity.java           // エンティティ用アノテーション
├─ Column.java           // カラム用アノテーション
├─ OrmManager.java       // ORMの本体(登録・取得など)
└─ User.java             // 実際のエンティティ(Userテーブル)

アノテーションの定義:Entity.java / Column.java

1
2
3
4
5
6
7
import java.lang.annotation.*;
 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
    String table();
}
1
2
3
4
5
6
7
import java.lang.annotation.*;
 
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
    String name();
}

エンティティクラスの例:User.java

1
2
3
4
5
6
7
8
9
10
11
@Entity(table = "users")
public class User {
    @Column(name = "id")
    public int id;
 
    @Column(name = "name")
    public String name;
 
    @Column(name = "email")
    public String email;
}

ORMの本体処理:OrmManager.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.lang.reflect.*;
 
public class OrmManager {
 
    public static String generateInsertSQL(Object obj) throws Exception {
        Class<?> cls = obj.getClass();
 
        if (!cls.isAnnotationPresent(Entity.class)) {
            throw new Exception("Entityアノテーションが見つかりません");
        }
 
        Entity entity = cls.getAnnotation(Entity.class);
        StringBuilder columns = new StringBuilder();
        StringBuilder values = new StringBuilder();
 
        for (Field field : cls.getDeclaredFields()) {
            if (field.isAnnotationPresent(Column.class)) {
                Column col = field.getAnnotation(Column.class);
                field.setAccessible(true);
                Object value = field.get(obj);
                columns.append(col.name()).append(", ");
                values.append("'").append(value).append("', ");
            }
        }
 
        String columnStr = columns.substring(0, columns.length() - 2);
        String valueStr = values.substring(0, values.length() - 2);
 
        return String.format("INSERT INTO %s (%s) VALUES (%s);", entity.table(), columnStr, valueStr);
    }
}

使い方例:Main.java

1
2
3
4
5
6
7
8
9
10
11
public class Main {
    public static void main(String[] args) throws Exception {
        User user = new User();
        user.id = 1;
        user.name = "Taro";
        user.email = "taro@example.com";
 
        String sql = OrmManager.generateInsertSQL(user);
        System.out.println(sql);
    }
}

出力結果:

1
INSERT INTO users (id, name, email) VALUES ('1', 'Taro', 'taro@example.com');

躓きやすいエラーと解決策

  • アノテーションが無視される
    @Retention(RetentionPolicy.RUNTIME) を設定していない
  • Field.get()でIllegalAccessException
    field.setAccessible(true) を必ず実行
  • nullがSQLに混じる問題
    null チェックを入れて "NULL" に変換処理を追加

応用アイデアで実用性を高める

  • SQL実行機能を追加(Connection.prepareStatement() など)
  • 更新・削除・検索SQLの生成に対応
  • 自動主キー判定やバリデーション追加
  • @Idアノテーションで主キー定義

完成構成のまとめ

  • Entity/Column.java:クラスとDBの橋渡しアノテーション
  • OrmManager.java:アノテーションからSQLを組み立てるロジック
  • User.java:エンティティの実体
  • Main.java:動作確認用のコード

まとめ:仕組みを知れば応用も自在

この記事では、Javaで自作ORMライブラリを作る方法を解説しました。

学べたポイント:

  • リフレクションの使い方
  • アノテーションの定義と活用
  • SQL組み立ての自動化ロジック

Hibernateなどの高度なフレームワークも、
根本的な仕組みはこの記事で扱ったような構造の積み重ねです。

一度自作してみると、使う側としての理解も格段に深まります。
ぜひあなたも、仕組みから学ぶORM開発に挑戦してみてください!

タイトルとURLをコピーしました