エントリー
Android向けのアプリケーションを作成するというアイデアは、晴れたタイでの休息の5日目に思いつきました。 何が私にきっかけになったのか、どのように、どのようにアプリケーションを計画したのかについては詳しく説明しません(記事はそれについてではありません)。 しかし、このアイデアはしっかりと根付いていて、滞在6日目にホテルで無料のインターネットを使用してラップトップにMySqlをダウンロードしました。映画を観たり、カメラから写真を撮るためだけに撮影したものです。
私が始めたのは、あなたが推測したように、リレーショナルモデルです。
仕事は大変でしたが、このモデルを使用して数か月後、私はAndroidの開発のジャングルに飛び込みました。 それ以前は、モバイルプラットフォーム向けに.Net Compact Frameworkについてのみ記述しましたが、 Javaに直接慣れていたため、ボタンのあるシンプルなフォームを作成することは難しくありませんでした。 予想通り、オブジェクトモデルはまったく問題を引き起こさなかったため、デバイスの腸のどこかにテストデータが飛び散ることを喜んで予想して、 Android Developers WebサイトのData Storageセクションを開きました。 「 データベースの使用 」セクションを網羅的に呼び出すことはできませんが、すべてのAPIリファレンスが含まれているため、 SQLiteOpenHelperの継承者の記述を開始しました。 Entity Frameworkによって台無しにされたいくつかの成功したテストの後、私はダース以上のエンティティを持っていたので、何らかの種類のオームを使用するのもいいだろうと気づきました。 Great and Terrible “ android orm ”を駆使して 、 この記事への最初のリンクとStackOverflowの便利なリンクを入手しました。 合計3つのormを入力したら、実験を開始しました。
実験
最初のテストはもちろんOrmLiteでした 。
オルミテ
原則として、適切な実装、注釈の使用。 DatabaseHelperでのonCreateとonUpgradeの実装も気に入っており、記憶の奥深くで記憶されていました。 しかし! 各エンティティに追加のクラス<%EntityName%> DAOも作成するには-ありがとうございます! 最終的に、エンティティの基本クラスにアタッチされたものを作成することができますが、これからはさらに問題が発生します。
グリーンダオ
ドキュメントの「 データモデルとコード生成 」という見出しはこれ以上読みませんでした。 もちろん、このアプローチは私には完全に明確ではなく、その利点もありますが、属性に慣れるにつれて、アノテーションをもっと使いたいと思います。
ActiveAndroid
このormに大きな期待がありました:注釈、マニフェストを使用したデータベースの作成( Helper OrmLiteと同じ深さで記憶されています)、エンティティ自体のメソッドを介したマッピング...できました。
リレーショナルモデル
ormから少し逸脱して、最終的にどのようなリレーショナルモデルが得られたかを説明します。 原則として、その中のすべてはもちろん1つのものを除いて標準です。 Entity Frameworkでは、継承されたエンティティをマッピングするときに、過剰なフィールドを持つ1つのテーブルが作成されます。 たとえば、エンティティ「 Machine 」があるとします
/** * */ public class Car { /** * */ private CarType type; /** * */ private int enginePower; /** * - */ private int doorsCount; }
そして、それから継承された「 トラック 」エンティティ
/** * */ public class Truck extends Car{ /** * , . */ private boolean isTipper; }
通常、ormはこのクエリを生成してテーブルを作成する必要があります。
CREATE TABLE car (id INTEGER PRIMARY KEY, type INTEGER REFERENCE car_type(id), engine_power INTEGER, doors_count INTEGER, is_tipper INTEGER);
私は、 PostgreSQLのテーブルの継承に感銘を受けて、このモデルを作成しました。
CREATE TABLE car (id INTEGER PRIMARY KEY, type INTEGER REFERENCES car_type(id), engine_power INTEGER, doors_count INTEGER); CREATE TABLE truck (id INTEGER REFERENCES car(id) ON DELETE CASCADE, is_tipper INTEGER);
これは単なる例であり、エンティティにはさらに多くのフィールドとリレーションシップがあることをすぐに明確にします。したがって、 Carテーブルを詰まらせて、それに属さないようにしました。
その結果、選択はLeft Joinを介して行われる必要があります。
その結果、自転車を発明することにしました。つまり、自分でOrmを書くことにしました。
コンセプト
- エンティティジェネレーターはありません! すべての注釈を通じて。
- 可能な限り少ない種類の注釈、理想的には2つの注釈があります(これまではこれに準拠することが可能でした)。
- クラス自体の静的メソッドを介してエンティティを要求します。
- インスタンスメソッドを使用して作成、保存、削除します。
- 初期テーブルエントリを作成できる最もシンプルなヘルパー 。
実装
注釈
要約は2つしかありません。
- テーブル -クラスに適用され、テーブルを説明します。 プロパティ:
- 名前 -テーブルの名前(空の場合)-クラス名は小文字で取得されます。
- CashedList-このクラスのインスタンスについて、それぞれを再度ロードする必要があるか、キャッシュリストで検索する必要があるかを示します(少し後で説明します)。
- LeftJoinTo-指定された継承者のクラスを示します。
- RightJoinTo-現在を拡張するクラスを示します。
- 列 -フィールドに適用され、テーブルの列を説明します。 プロパティ:
- Name-列の名前;空の場合、小文字のフィールド名が使用されます。
- PrimaryKey-このフィールドがキーであることを示します。
- 継承 -この注釈が継承されることを示します。
- ReferenceActions -Referencesフィールドのアクションのリスト。
エンティティ
再び、例からそれらを検討します。
public class BaseEntity extends OrmEntity { @Column(primaryKey = true, inherited = true) private Long id; } @Table(name = “car_type”, cashedList = true) public class CarType extends BaseEntity { @Column private String code; } @Table(rightJoinTo = {Truck.class}) public class Car extends BaseEntity { @Column(name = “car_type”) private CarType type; @Column private List<Wheel> wheels; @Column(name = “engine_power”) private int enginePower; @Column(name = “doors_count”) private int doorsCount; } @Table public class Wheel extends BaseEntity { @Column(name = “car_id”) private Car car; @Column private String manufacturer; } @Table(leftJoinTo = Car.class) public class Truck extends Car { @Column(name = “is_tipper”) private boolean isTipper; }
Helper OrmLiteに類似したHelperの作業の結果、次のクエリを取得します。
CREATE TABLE car_type (id INTEGER PRIMARY KEY, code TEXT); CREATE TABLE car (id INTEGER PRIMARY KEY, car_type REFERENCES car_type (id), engine_power INTEGER, doors_count INTEGER); CREATE TABLE wheel (id INTEGER PRIMARY KEY, car_id INTEGER REFERENCES car (id), manufacturer TEXT); CREATE TABLE truck (car_id REFERENCES car (id), is_tipper INTEGER);
ormの詳細
OrmEntityクラスには、保護された静的メソッドがあります。
protected static <T extends OrmEntity> List<T> getAllEntities (Class<T> entityClass)
たとえば、 CarTypeクラスでは 、次のメソッドを実装します。
public static List<CarType> getAllEntities() { return getAllEntities(CarTpe.class); }
OrmEntityには、 alterおよびdeleteメソッドも保護されています。 BaseEntity基本クラスでは、 alterを非表示にし、 insertおよびupdateでヤンクします。
チェックと制限
エンティティには、 primaryKeyというラベルのフィールドが必要です 。 Long型でなければなりません(つまり、最初はidがnullで 、ohm alterはそれが何であるかを挿入または更新できるように、 L ongです)。
ColumnというラベルのフィールドがOrmEntityから継承されたエンティティのクラスを持つList型の場合、このクラスにはColumnというラベルの最初のクラス型のフィールドが必要です。
ColumnというラベルのフィールドがOrmEntityから継承されたタイプである場合、このタイプにはprimaryKeyの Columnというラベルのフィールドが必要です 。
クラスがleftJoinToでTableでマークされている場合、 leftJoinToで指定されたクラスは、最初のクラスが追加されるrightJoinToで Tableでマークされる必要があります。
失敗したチェックはすべてExceptionをスローします 。
おわりに
現時点では、 ormはまだ完成しておらず、必要に応じて開発しています。 タイプint 、 Long 、 double 、 String 、 Drawableがサポートされるようになりました。 途中ドキュメント 。
参照に対するアクションから、 ON DELETEのみがありますが、それを使用してCASCADEおよびSET NULLを作成し、残りを作成できます。
LeftJoinTo-完全には機能していませんが、今は完了しています。
考えたことをすべて終えてコードをとかすとすぐに、ライブラリをGitHubに投稿します 。