CanastaとSenoritを使ってAndroid用のOrmを書く、パート2

エントリー



私の最初の記事へのコミュニティの関心が、私をormで一生懸命働かせました。 私はまだそれについてすべてが好きではありません(コードが最適化されていない場所、実装が望んでいない場所、十分なチェックとおそらく安定性がない)が、それは私に現在必要なすべての機能を実行します。 だから、会う: UcaOrm



使用する



例として次のモデルを使用してormで作業することを検討します( 最初の部分のモデルについての詳細)。

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; }
      
      





カスタマイズ


ライブラリをプロジェクトに追加した後(将来、アセンブルされたjarをアップロードする予定ですが、現時点ではソースから自分でアセンブルできます)、 OrmHelperから継承されたヘルパーを作成する必要があります。

 public class DataBaseHelper extends OrmHelper { public DataBaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override protected void onCreate() { } @Override protected void onUpgrade(int oldVersion, int newVersion) { } @Override public void getDefaultValues(Class<? extends OrmEntity> entityClass, ArrayList<String> columns, ArrayList<ContentValues> valueList) { } }
      
      







getDefaultValuesメソッドを使用すると、作成されたテーブルに初期データを追加できます。 その実装はまだあまり便利ではなく、将来処理される予定です。

ここでヘルパーを登録する必要があります。 これは、 アプリケーション継承を介して行われます

 public class MyApp extends Application { @Override public void onCreate() { super.onCreate(); try { OrmFactory.SetHelper(DataBaseHelper.class, getApplicationContext()); } catch (Exception e) { e.printStackTrace(); } } @Override public void onTerminate() { OrmFactory.ReleaseHelper(); super.onTerminate(); } }
      
      







デフォルトでは、データベース名はLabelアプリケーションから作成され、バージョンは1番目になります。 これを変更するには、次の行をmanifestに追加します。

 <meta-data android:name="UO_DB_NAME" android:value="Cars" /> <meta-data android:name="UO_DB_VERSION" android:value="1" />
      
      





テーブル作成


テーブルはonCreateメソッドで作成され、更新はonUpdateメソッドで行われますが、 ormでは更新はまだサポートされていません。

したがって、必要なテーブルを作成します。

 protected void onCreate() { try { OrmUtils.CreateTable(CarType.class); OrmUtils.CreateTable(Car.class); OrmUtils.CreateTable(Wheel.class); OrmUtils.CreateTable(Truck.class); } catch (Exception e) { e.printStackTrace(); } }
      
      





CarTypeテーブル初期データを入力します。

 public void getDefaultValues(Class<? extends OrmEntity> entityClass, ArrayList<String> columns, ArrayList<ContentValues> valueList) { ContentValues values; if (entityClass.equals(CarType.class)) { values = new ContentValues(); values.put(columns.get(0), "Passenger"); valueList.add(values); values = new ContentValues(); values.put(columns.get(0), "Truck"); valueList.add(values); } }
      
      





すでに述べたように、 getDefaultValuesの実装は不完全です



簡単な選択


CarTypeテーブルにはすでにデータが格納されているため、まず単純なフェッチを検討し、次にインスタンスを作成してWhereでフェッチすることをお勧めします。

Car 」タイプのインスタンスを作成しましょう。 これを行うには、まずすべてのタイプを使用可能にする必要があります。 ormが動作するすべてのエンティティはOrmEntityから継承する必要があるため、静的なgetAllEntitiesメソッドを使用します。 美しさのために、 CarTypeクラスでオーバーライドできます

 public static List<CarType> getAllCarTypes(){ try { return OrmEntity.getAllEntities(CarType.class); } catch (Exception e) { e.printStackTrace(); } return null; }
      
      





エンティティ作成


Carのインスタンスを作成します。

  Car car = new Car(); car.setType(CarType. getAllCarTypes().get(0)); car.setEnginePower(116); car.setDoorsCount(4); Wheel whell = new Whell(); whell.setCar(car); whell.setManufacturer("Michrelli"); car.addWheel(whell);
      
      





もちろん、 whell.setCarはwhell.setCar(this)のようにaddWheel内にプルする方良いですが、わかりやすくするためにここで説明します。

そして、 alterメソッドを引くだけです:

  car.alter();
      
      





インスタンスを少し変更してみましょう。

  car.setEnginePower(120); car.getWheels().get(0).setManufacturer("Pirlin");
      
      







繰り返しますが、単にalterを呼び出します。

  car.alter();
      
      





トラック 」を作成します。



  Truck truck = new Truck(); truck.setType(CarType.getAllCarTypes().get(1)); truck.setEnginePower(220); truck.setDoorsCount(2); Wheel whell = new Whell(); whell.setCar(truck); whell.setManufacturer("Michrelli"); truck.addWheel(whell); truck.setTipper(true); truck.alter();
      
      





さらに、変数の型は私たちにとって重要ではありません。変数にある主なものとしてCarとして宣言できます。



サンプリング


Carに 2つのメソッドを実装します。

 public static List<Car> getAllCars() { try { return OrmEntity.getAllEntities(CarType.class, true); } catch (Exception e) { e.printStackTrace(); } return null; } public static List<Car> getCarsWithoutTrucks() { try { return OrmEntity.getAllEntities(CarType.class); } catch (Exception e) { e.printStackTrace(); } return null; }
      
      





違いはgetAllEntitiesの呼び出しのみです 。ただし、 getAllCarsは2つのレコードを返し、 getCarsWithoutTrucksは1 つのみを返します。2番目のパラメーターは、子テーブルに関連付けられたレコードを選択するか、 自給自足のみを選択します。

以下に注意することが重要です。タイプPassengerの 2番目のインスタンスを作成するとします。 フェッチするとき、 CarTypeクラスはCashedListとしてマークされているため 、両方のCarインスタンスは同じCarTypeインスタンスを参照します。



どこで取得する


さて、そして最も興味深い!

OrmEntityには、エンティティクラスを取得する静的Whereメソッドがあります。 美のために、 車でそれを描き直します

  public static OrmWhere Where(){ return Where(Car.class); }
      
      





そして、 120馬力の車を見つけてみてください:



  List<Car> cars = Car.Where().Equals("engine_power", 120).Select();
      
      





または120馬力の車 そして4つのドアがあります:



  List<Car> cars = Car.Where().Equels(“engine_power”, 120).And().Equals("doors_count", 4).Select();
      
      





または、 Pirlinホイールを備えた車の1つ:



  Car car = Car.Where().FindChild(Wheel.class, new OrmWhere(Wheel.class).Equals("manufacturer", "Pirlin")).SelectFirst();
      
      





子テーブルからのインクルードを含む選択はまだ実行できません( ormはそれをサポートしており、必要なのはOrmWhereのincludeLeftChildパラメーターで別のSelectメソッドを追加することだけです )。



おわりに



それが私のormができることのほとんどすべてです。 今、私が彼に割り当てるバージョン番号は0.1です。 既に述べたように、それは私のアプリケーションが現時点で必要とするすべてを実装しているため、たとえばOrmWhereの LessGreatなどの些細なことはまだ実装されていません。 テーブルを更新または削除する機能は実装されていません(同じCreateTableを使用して新しいテーブルを追加できます)。 左右のテーブルを結合するため 、パラメータを使用したクエリ呼び出しを放棄し、 SQLiteDatabaseからrawQueryをプルするとともに、キャッシュリストのすべてのエントリを取得するコストをO(nk)nはテーブル内のすべてのエントリの数、 k-すでに選択されているレコードの数)からO(n)まで 。 現在サポートされているタイプは、 IntLongDoubleDateStringDrawableおよびDocumentです。

おそらく、私は何かに言及するのを忘れましたが、どんな場合でも、どんな質問、特にUcaOrmの開発のための提案に喜んでいます。



All Articles