読者です 読者をやめる 読者になる 読者になる

UZABASE Tech Blog

株式会社ユーザベースの技術チームブログです。 主に週次の持ち回りLTやセミナー・イベント情報について書きます。

簡単シンプルなSQLライブラリ『JDBI』

技術チームインターンの前田です。

アプリケーションを開発していると、データベースと連携する必要が出てくる場合が多いかと思います。

この記事では、JavaプログラムからRDBMSを利用する際に便利なライブラリを紹介します。

このライブラリは、私が取り組んだ業務でも使用したもので、JDBIと呼ばれています。

JDBIとは

  • Javaプログラム↔RDBMS間の連携に便利なSQLライブラリです。

  • JDBIはJDBCの上に構築されているもので、JDBCのAPIの使い勝手の悪さをカバーしてくれます。

JDBIの便利な点

  • JDBIを利用することで、簡単にプログラムのロジックとSQL文を分離することが出来ます。

  • プログラム中のオブジェクトとRDBMSのレコード間の対応付けを行う、所謂O/Rマッパーとしても機能します。

  • O/Rマッピングの設定に、設定ファイルを使用しません。

似たような機能を持つフレームワークとしてHibernate、MyBatisなどが挙げられますが、これらはO/Rマッピングのための各種ファイル(~.xml等)の設定が必要であったり、それらを自動設定するためにもツールの使用が必要であったりで、利用がやや複雑な印象を受けます。

JDBIであれば、そのような設定ファイルや複雑な設定が不要で、シンプルなJavaコードのみで簡単に動作させることができます。

以下、簡単にその使用例を紹介します。

例えば、次のようなクラスがあったとします。

public class Company {
    private String name;
    private int num;
    
    // アクセサメソッドは省略
}

上記のオブジェクトに対応するテーブルを作成することにします。

CREATE TABLE `company` (
  `name` varchar(20) ,
  `number_of_employees` int(11)
) 

このとき、Daoは以下のようになります(JDBIではDaoにはインターフェースを使用します)。 この例では、オブジェクトが保持するフィールドの値をDBに挿入するSQL文と、 nameの値から対応するnum_of_employeesを取得するSQL文を書いています。

public interface CompanyDao {
    @SqlQuery("SELECT number_of_employees from company WHERE name = :name")
    int findByName(@Bind("name") String n);

    @SqlUpdate("INSERT INTO company(name,number_of_employees) values(:name,:num)")
    void insert(@BindBean Company d);
}

それぞれの処理を詳しく見ていきます。

@SqlQuery はデータを取得するSQL文を表し、@SqlUpdate はデータを更新するSQL文を表しています。 findByNameメソッドで使用している@Bindアノテーションは、プレースホルダに入るパラメータを指定するために使用します。 この場合だと、引数で与えられたString型のnに格納されている値がSQL文内の「:name」に対応付けられます。 メソッドの戻り値には、取得するデータの型を指定します。 例えば、上記のfindByNameメソッドはString型のパラメータを元にint型のデータを取得したいので、戻り値はint型です。

insertメソッドには、引数にとったJavaオブジェクトをRDBMSに挿入する処理が書かれています。 @BindBeanアノテーションが付けられているオブジェクトに対して、プレースホルダの「:◯◯」という記述の◯◯に対応するgetterが呼び出されることによって、プレースホルダへの対応付けが行われます。 この場合だと、Company型のdのgetName()とgetNum()メソッドが呼び出されます。

ここでは動作の説明を書きましたが、このような説明がなくても上記のコードを見ればすぐに動作イメージが掴めるような記述方式になっていると思います。

実際にDaoを使用してSQL文を実行するクラスを次に示します。

public class Test {
    public static void main(String[] args) {
        Company company = new Company("hoge", 10);
        DBI dbi = new DBI("JDBC接続URL", "ユーザ名", "パスワード");
        CompanyDao dao = dbi.onDemand(CompanyDao.class);
        dao.insert(company);
        System.out.println(dao.findByName("hoge"));
    }
}

上記のコードでは、「10」とコンソール出力します。

このように、JDBIではシンプル且つ簡単にデータベースとJavaプログラムを連携することができます。

ここではオブジェクト→レコードのマッピングを行いましたが、もちろんレコード→オブジェクトへのマッピングも可能です。 また、トランザクション機能などの基本的な機能も備えています。

現在では様々なO/Rマッピングフレームワークが存在し、状況や好みによってどれを選択するかは変わってくるかと思いますが、このライブラリもその選択肢の一つになり得るものだと思います。