SQLiteOpenHelper
から派生した私のクラスは、一度に大きくなりました。発言時には、それは涼しいとはみなされない1500行以上のコードです。それが成長することを防ぐための、すなわちピースごとの分離を行うためのエレガントな解決策がいくつかあります。それらのものが何であるかはっきりしない。上記のクラスから継承することは悪い習慣であると言う人もいます。誤動作がデータベースの作成/アップグレード手順につながるからです。何かヒント?どうもありがとう!SQLiteOpenHelperから派生したクラスが巨大になっています
答えて
あり、例としては、DEVに示します。サイトでは、すべてのテーブルと列の名前をハードコードするモンスタークラスの作成を推奨します。これは混乱です。各表を処理するクラスを作成することもできます。これらのクラスは、テーブルごとにData Access Objectsとして動作します。
これは私が使用するものです。
public interface DataAccessObject<E> {
public void onCreate(SQLiteDatabase db);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion);
public void create(E... params);
public E[] retrieve(E... params);
public void update(E... params);
public void delete(E... params);
}
その後、私は各テーブルの実装をコーディングします。一般的なtipe Eは通常pojosです。注意データを保持するだけのクラス(pojos)と持続的なデータ(DAO)のクラスを混在させるわけではありません。たとえば、pojoはその変数(色、年など)とともにCar
になります。それから私は、DataAccessObject<Car>
を拡張するCarDAOをコード化します。そして、このDAOクラスはpojoの変数をDB列にマッピングし、テーブルを問い合わせてそれに書き込むことを担当します。
最後に、DAOが注入されたSQLiteOpenHelperを作成し、各テーブルの内容をそれらに委譲することができます。これらのDAO実装は、表名と列名の定数を持つ実装です。そして、複雑なクエリのために必要ならば、彼らはお互いに話すことができます。 (これはまた、このアプローチの欠点の1つであることに注意してください。多くのテーブルや列を含むクエリが必要なときは、きちんとしたデザインを作成するのは簡単ではありません。私は与えられたコードスニペットとして従う
(ほぼ)完全に同意します。私はテーブルに基づいて分離の程度を持っているとは思えません。私は代わりにドメインオブジェクトに基づいています(実際にはテーブルと同じであるかもしれません)。この答えに+1。 – Nick
あなたのヘルパーは、そのサイズである必要はありません。私はデータを操作するすべてのコードをヘルパーに配置していると仮定できます。
あなたはそれはあなたがオブジェクト指向の方法でそれにアクセスすることができますに関するものであり、先のクラスのコードを配置する必要があります。
たとえば、連絡先クラスがある場合。連絡先を保存したコードをデータベースに保存します。
:
SQLHelperクラス:
public class SQLHelper extends SQLiteOpenHelper {
public SQLHelper(Context context, String DBName)
{
super(context, DBName, null, DATABASE_VERSION);
}
public SQLiteDatabase getDBObject(int isWrtitable)
{
return (isWrtitable == 1) ? this.getWritableDatabase() : this.getReadableDatabase();
}
@Override
public void onOpen(SQLiteDatabase db)
{
super.onOpen(db);
onCreate(db);
}
@Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(TABLE_1);
db.execSQL(TABLE_2);
...
db.execSQL(TABLE_N);
}
}
MySQLManager:
public class MySQLManager
{
private SQLHelper sqlHelper;
//Singlton class
public void initMySQLManager(Context context, String DBName)
{
_context = context;
sqlHelper = new DBHandler(context, DBName);
}
public MyObject getMyObjectRecord() {
MyObject myObj = new MyObject();
Cursor cursor = null;
try {
cursor = dbObject.getWritableDatabase().rawQuery("select * FROM " + SQLHelper.MYOBJECT_TABLE + ";", null);
//fetch things
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
return bookVo;
}
//Similarly other methods.
}
はあなたがすべてのモデル固有のコードを置くことは避けるべきです。ほとんどの作業を行いますできるだけあなたのヘルパー。次のプロジェクトでできる限り再利用できるものと考えてください。一般的なデータ抽象化のパターンと原則のいくつかに従うことができます。
- たとえば、あなたはまた、持続性(読み取りおよびデータベースからの書き込み)に関連するすべての方法をそのフィールドやメソッドを持つあなたのビジネスオブジェクトを持つについてActive Recordを、考える、とすることができます。
- また、軽量オブジェクトについて考えることもできますし、いくつかのORMのように、エンティティマネージャなどのマッピング機能を提供する他のオブジェクトによってインスタンスをデータベースに保存してデータベースから取得することもできます。
- Zend TableGatewayを見れば、データベーステーブルをオブジェクトとして表現するための素晴らしいアプローチが得られます。これは、Androidとsqliteに移行することです。私は個人的に
下に説明として
これは広く、いくつかのORMで使用される概念であるを使用することですまた、ネイティブのZend Frameworkやその他のシステムでは、データの永続性を提供するために、オブジェクトやWebフォームをデータベースレコードにマッピングして理解しやすく維持する手助けをしています。
ヒートレーターは、一方のデータベースフィールド名をもう一方のエンティティプロパティにマップするオブジェクトです。この情報は内部的には格納されませんが、データベースからオブジェクトを作成するメカニズムとオブジェクトからデータセットを抽出してデータベースを更新するメカニズムの両方を提供します。
列名 - >エンティティプロパティの配列を持ち、そのYourClass hydrate()
メソッドが呼び出されると、データソースからモデルオブジェクトにそれぞれの情報が転送されます。extract(YourClass yourObject)
メソッドyourObjectに含まれているデータを対応するデータベースレコードに転送します
私はこのアプローチが大好きです。インターフェイスを作成するのは本当に簡単で、一般的な使用例にはいくつかの実装があります。 メインオブジェクトやヘルパーに影響を与えずにデータベース内の変更を実行できます。 また、同じインターフェースを使用してを作成すると、データをjson、xml、残りの呼び出し、またはと想像できるものにエクスポートするためのマッパーを作成できます。
あなたが良い水分補給業者について考えることができ、継承するクラスをいくつか作成することができれば、本当に小さなデータベースヘルパー、本当に小さなエンティティオブジェクト、一般的な作業を行う抽象クラス、あなたが必要とする可能性があるすべての重量ですが、テーブルやオブジェクトタイプごとに1つのクラスを持つことができるので、それほど多くはありません。したがって、クラスはかなり小さくなりますし、ビジネスレベルで関連するコードのみを含みます。
その後、command patternで
のようなコマンドクラスでDB操作を実行し、このコマンドをマージするfacade patternを使用することができます(プールのような解放する、またはキャッチ)のみのオープンとクローズのDB接続にシングルトンクラスを考慮することができますより複雑なデータベース操作の実行順序で実行できます。これにより、コードをきれいにして制御しやすくなります。 InsertBookCommand
クラスを変更した場合と同様に、関連するすべての操作がその動作によって変更されます。
を要約すると、私の解決策は次のとおりです。
オープンDB接続やコマンドにパラメータとしてデシベルを渡します。コマンドを実行します。
- 1. Android.Content.ActivityNotFoundException(アクティビティから派生したクラスから派生したクラス)
- 2. 同じクラスから派生したクラスから派生したC++サブクラス
- 3. ブーストから派生したクラスから派生したクラスでコピーが自動的に禁止されていますか?たとえば
- 4. コンクリートクラスから派生した抽象クラス
- 5. C#でEntity Frameworkによって生成されたクラスから派生する
- 6. 派生プロパティが非表示になっていますか? C#
- 7. インターフェイスから派生した別のクラスの中にあるインターフェイスから派生したクラスをインスタンシエートする...ちょっと調べるためには
- 8. 他の派生クラスから派生クラスメソッドにアクセスする方法
- 9. 派生クラスからクラスを派生させる
- 10. 派生クラスからベースクラス
- 11. 巨大なファイルから
- 12. Entity Framework 4.1のNotMappedクラスからEntityクラスを派生します。
- 13. は、C#のクラスから派生したオブジェクトをパラメータとして渡します。
- 14. 派生クラスが全体のベースコンストラクタを呼び出さない派生クラス
- 15. Pythonのリストクラスから派生したクラスの使い方
- 16. 別の派生クラスから他の派生クラスにアクセスするにはどうすればよいですか?
- 17. 他の派生クラスから派生クラスのメンバーにアクセスするにはどうすればよいですか?
- 18. 巨大なキャンバスを使った絵画
- 19. 例外がスローされましたが、キャッチされなかったsystem.exceptionから派生しました
- 20. ジャンゴ:からrequest.userから派生クラス
- 21. 辞書から派生したクラスに対してforeachを有効にする
- 22. 巨大クラスのStackOverflowException
- 23. 巨大なDBpediaダンプをロード中に例外が発生しました
- 24. std :: exceptionから派生しました
- 25. は私が再ファクタリングだ巨大なプロジェクトを持っている
- 26. 基本クラスから派生したインスタンスを保存する
- 27. Qt:基底クラスメソッドを派生クラスのスロットに持っていく
- 28. コンパイラが派生クラスのコンストラクタの定義に不満を持っていないのはなぜですか?
- 29. 派生クラスから別の派生クラスへのポインタを持つベクトル要素をスワップします
- 30. ベースには、それらから派生したクラスに関する情報がありますか?
公式カレンダプロバイダまたは連絡先プロバイダのSQLiteOpenHelpersを見てください:-) 'ContactsDatabaseHelper'の' onUpdate() 'メソッドは約900行です - 他のメソッドに関連するバージョンの変更を委任してください。しかし、彼らはバージョン番号800です!クラス全体は約5000行のコードです。だからあなたはあまりにも残念に感じるべきではありません:-)もっと真剣に:IMHO ** onUpgrade()は時間の経過とともに成長するはずです**。他に何もない! –