1概要


ORMLite

は、Javaアプリケーション用の軽量ORMライブラリです。他のORMフレームワークの複雑さやオーバーヘッドを追加することなく、最も一般的なユースケースに合わせてORMツールの標準機能を提供します。

主な機能は次のとおりです。

  • Javaアノテーションを使用してエンティティクラスを定義する

  • 拡張可能な

    DAO

    クラス

  • 複雑なクエリを作成するための

    QueryBuilder

    クラス

  • データベーステーブルを作成および削除するための生成クラス

  • 取引のサポート

  • エンティティ関係のサポート

次のセクションでは、ライブラリの設定方法、エンティティクラスの定義方法、およびライブラリを使用したデータベースに対する操作の実行方法について説明します。


2 Mavenの依存関係

ORMLiteを使い始めるには、


ormlite-jdbc


依存関係を

pom.xml

に追加する必要があります。 :

<dependency>
    <groupId>com.j256.ormlite</groupId>
    <artifactId>ormlite-jdbc</artifactId>
    <version>5.0</version>
</dependency>

デフォルトでは、これはhttps://search.maven.org/classic/#search%7Cga%7C1%7Ca%3A%22h2%22%20AND%20g%3A%22com.h2database%22[

h2

]依存関係も持ち込みます。 。この例では、

H2

インメモリデータベースを使用するので、別のJDBCドライバは必要ありません。

別のデータベースを使用したい場合は、対応する依存関係も必要になります。


3エンティティクラスの定義

ORMLiteを使用して永続化のためにモデルクラスを設定するために使用できる2つの主なアノテーションがあります。

エンティティクラスの**

@ DatabaseTable

プロパティの**

@ DatabaseField

まず、

name

フィールドと、主キーでもある

libraryId

フィールドを使用して

Library

エンティティを定義することから始めましょう。

@DatabaseTable(tableName = "libraries")
public class Library {

    @DatabaseField(generatedId = true)
    private long libraryId;

    @DatabaseField(canBeNull = false)
    private String name;

    public Library() {
    }

   //standard getters, setters
}


@ DatabaseTable

アノテーションには、デフォルトのクラス名に依存したくない場合にテーブルの名前を指定するオプションの

tableName

属性があります。

  • データベーステーブルの列として永続化したいフィールドごとに、

    @ DatabaseField

    アノテーションを追加する必要があります。

テーブルの主キーとして機能するプロパティは、

id



generatedId

、または

generatedSequence

属性のいずれかでマークできます。この例では、主キーが自動的にインクリメントされるように

generatedId = true

属性を選択します。

また、クラスには少なくとも

package-scope

の可視性を持つ引数のないコンストラクタが必要です。

私たちがフィールドを設定するために使用できる他のいくつかのよく知られた属性は

columnName



dataType



defaultValue



canBeNull



unique

です。


3.1.

JPA

アノテーションを使う

ORMLite固有のアノテーションに加えて、** JPAスタイルのアノテーションを使ってエンティティを定義することもできます。


JPA

標準アノテーションを使用する前に定義した

Library

エンティティの同等物は次のようになります。

@Entity
public class LibraryJPA {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long libraryId;

    @Column
    private String name;

   //standard getters, setters
}

ORMLiteはこれらのアノテーションを認識しますが、


javax.persistence-api


を追加する必要がありますそれらを使用するための依存関係。

サポートされている

JPA

アノテーションの完全なリストは@

Entity



@ Id、


@ Column、


@ GeneratedValue、

@

OneToOne



@ ManyToOne、

@

JoinColumn

、@

Version

です。


4

ConnectionSource


定義されたオブジェクトを操作するには、

ConnectionSource

** を設定する必要があります。

これには、単一の接続を作成する

JdbcConnectionSource

クラス、または単純なプール接続ソースを表す

JdbcPooledConnectionSource

を使用できます。

JdbcPooledConnectionSource connectionSource
  = new JdbcPooledConnectionSource("jdbc:h2:mem:myDb");
//work with the connectionSource

connectionSource.close();

パフォーマンスの良い他の外部データソースも、それらを

DataSourceConnectionSource

オブジェクトにラップすることで使用できます。


5

TableUtils

クラス


ConnectionSource

に基づいて



TableUtils

クラスの静的メソッドを使用してデータベーススキーマで操作を実行できます


  • createTable()

    – エンティティクラスの定義に基づいてテーブルを作成します。

または

DatabaseTableConfig

オブジェクト
**

createTableIfNotExists()

– それ以外は前のメソッドと同じ

テーブルが存在しない場合にのみテーブルを作成します。これだけで動作します
それをサポートするデータベース
**

dropTable()

– テーブルを削除する


  • clearTable

    () – テーブルからデータを削除する


TableUtils

を使用して

Library

クラスのテーブルを作成する方法を見てみましょう。

TableUtils.createTableIfNotExists(connectionSource, Library.class);


6.

DAO

オブジェクト

ORMLiteには、CRUD機能を使用して

DAO

オブジェクトを作成できる

DaoManager

クラスが含まれています** :

Dao<Library, Long> libraryDao
  = DaoManager.createDao(connectionSource, Library.class);


DaoManager

は、その後の__createDao()の呼び出しごとにクラスを再生成するわけではありませんが、代わりにパフォーマンスを向上させるために再利用します。

次に、

Library

オブジェクトに対してCRUD操作を実行できます。

Library library = new Library();
library.setName("My Library");
libraryDao.create(library);

Library result = libraryDao.queryForId(1L);

library.setName("My Other Library");
libraryDao.update(library);

libraryDao.delete(library);


DAO

は、すべてのレコードをループ処理できる反復子です。

libraryDao.forEach(lib -> {
    System.out.println(lib.getName());
});

ただし、ループが最後まで続く場合、ORMLiteは基礎となるSQL文を閉じるだけです。例外またはreturnステートメントは、コード内でリソースリークを引き起こす可能性があります。

そのため、ORMLiteのドキュメントでは、反復子を直接使用することをお勧めしています。

try (CloseableWrappedIterable<Library> wrappedIterable
  = libraryDao.getWrappedIterable()) {
    wrappedIterable.forEach(lib -> {
        System.out.println(lib.getName());
    });
 }

このようにして、

try-with-resources

または

finally

ブロックを使用してイテレータを閉じることができ、リソースリークを回避できます。


6.1. カスタムDAOクラス

提供されている

DAO

オブジェクトの動作を拡張したい場合は、

Dao

タイプを拡張する新しいインターフェースを作成できます。

public interface LibraryDao extends Dao<Library, Long> {
    public List<Library> findByName(String name) throws SQLException;
}

それでは、このインターフェースを実装し、

BaseDaoImpl

クラスを拡張するクラスを追加しましょう。

public class LibraryDaoImpl extends BaseDaoImpl<Library, Long>
  implements LibraryDao {
    public LibraryDaoImpl(ConnectionSource connectionSource) throws SQLException {
        super(connectionSource, Library.class);
    }

    @Override
    public List<Library> findByName(String name) throws SQLException {
        return super.queryForEq("name", name);
    }
}

  • この形式のコンストラクタが必要です。

最後に、カスタムの

DAOを使用するには、

Library__クラス定義にクラス名を追加する必要があります。

@DatabaseTable(tableName = "libraries", daoClass = LibraryDaoImpl.class)
public class Library {
   //...
}

これにより、

DaoManager

を使用してカスタムクラスのインスタンスを作成できます。

LibraryDao customLibraryDao
  = DaoManager.createDao(connectionSource, Library.class);

それから、標準の

DAO

クラスのすべてのメソッドとカスタムメソッドを使用できます。

Library library = new Library();
library.setName("My Library");

customLibraryDao.create(library);
assertEquals(
  1, customLibraryDao.findByName("My Library").size());


7. エンティティの関係の定義

ORMLiteは永続化のためにエンティティ間の関係を定義するために「外部」オブジェクトまたはコレクションの概念を使用します。

それぞれの種類のフィールドを定義する方法を見てみましょう。


7.1. 異物フィールド


@ DatabaseField

のアノテーションを付けたフィールドで

foreign = true

属性を使用することで、2つのエンティティクラス間に単方向の1対1の関係を作成できます。このフィールドは、データベースにも保持されているタイプである必要があります。

まず、

Address

という新しいエンティティクラスを定義しましょう。

@DatabaseTable(tableName="addresses")
public class Address {
    @DatabaseField(generatedId = true)
    private long addressId;

    @DatabaseField(canBeNull = false)
    private String addressLine;

   //standard getters, setters
}

次に、

Address

型のフィールドを

Library

クラスに追加します。

@DatabaseTable(tableName = "libraries")
public class Library {
   //...

    @DatabaseField(foreign=true, foreignAutoCreate = true,
      foreignAutoRefresh = true)
    private Address address;

   //standard getters, setters
}


@ DatabaseField

アノテーションにさらに2つの属性、

foreignAutoCreate



foreignAutoRefresh

を追加しました。どちらも

true.

に設定されています。


foreignAutoCreate = true

属性は、

address

フィールドを使用して

Library

オブジェクトを保存するときに、その

id

がnullではなく、

generatedId = true

属性を持っていれば、外部オブジェクトも保存されることを意味します。


foreignAutoCreate

をデフォルト値の

false

に設定した場合は、それを参照する

Library

オブジェクトを保存する前に、外部オブジェクトを明示的に永続化する必要があります。

同様に、

__ foreignAutoRefresh


=

true__属性は、ライブラリオブジェクトを取得するときに、関連する外部オブジェクトも取得するように指定します。それ以外の場合は、手動で更新する必要があります。


Address

フィールドを持つ新しい

Library

オブジェクトを追加し、両方を保持するために

libraryDao

を呼び出します。

Library library = new Library();
library.setName("My Library");
library.setAddress(new Address("Main Street nr 20"));

Dao<Library, Long> libraryDao
  = DaoManager.createDao(connectionSource, Library.class);
libraryDao.create(library);

次に、

address

が呼び出され、

Address

も保存されたことを確認します。

Dao<Address, Long> addressDao
  = DaoManager.createDao(connectionSource, Address.class);
assertEquals(1,
  addressDao.queryForEq("addressLine", "Main Street nr 20")
  .size());


7.2. 外国のコレクション

リレーションシップの



には、

@ ForeignCollectionField

アノテーションを付けて

ForeignCollection <T>

または

Collection <T>

型を使用できます。

上記のような新しい

Book

エンティティを作成してから、

Library

クラスに一対多の関係を追加しましょう。

@DatabaseTable(tableName = "libraries")
public class Library {
   //...

    @ForeignCollectionField(eager=false)
    private ForeignCollection<Book> books;

   //standard getters, setters
}

これに加えて、

Book

クラスに

Library

型のフィールドを追加する必要があります。

@DatabaseTable
public class Book {
   //...
    @DatabaseField(foreign = true, foreignAutoRefresh = true)
    private Library library;

   //standard getters, setters
}


  • ForeignCollection

    には、

    Book:

    型のレコードを操作する

    add()

    メソッドと

    remove()

    メソッドがあります。

Library library = new Library();
library.setName("My Library");
libraryDao.create(library);

libraryDao.refresh(library);

library.getBooks().add(new Book("1984"));

ここでは、

library

オブジェクトを作成し、次に

books

フィールドに新しい

Book

オブジェクトを追加しました。これもデータベースに永続化されます。

  • コレクションは遅延ロードされているとマークされているので(eager = false)、bookフィールドを使用する前に__refresh()メソッドを呼び出す必要があります。


Book

クラスの

library

フィールドを設定して関係を作成することもできます。

Book book = new Book("It");
book.setLibrary(library);
bookDao.create(book);

両方の

Book

オブジェクトが

library

に追加されたことを確認するために、

queryForEq()

メソッドを使用して、指定された

library

idを持つすべての

Book

レコードを検索できます。

assertEquals(2, bookDao.queryForEq("library__id", library).size());

ここで、

library

id

は外部キー列のデフォルト名であり、主キーは

library__オブジェクトから推測されます。


8

QueryBuilder


それぞれの

DAO

を使用して

QueryBuilder

オブジェクトを取得し、それを使用してより強力なクエリを構築することができます。

このクラスには、

selectColumns()、where()、groupBy()、


having()、countOf()、distinct()、orderBy()、join()など、SQLクエリで使用される共通の操作に対応するメソッドが含まれています。

複数の

Book

が関連付けられているすべての

Library

レコードを見つける方法の例を見てみましょう。

List<Library> libraries = libraryDao.queryBuilder()
  .where()
  .in("libraryId", bookDao.queryBuilder()
    .selectColumns("library__id")
    .groupBy("library__id")
    .having("count(** ) > 1"))
  .query();


9結論

この記事では、ORMLiteを使用してエンティティを定義する方法と、オブジェクトとそれに関連するリレーショナルデータベースを操作するために使用できるライブラリの主な機能について説明しました。

例の完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/libraries-data[over on GitHub]にあります。