Meine Klasse, die von SQLiteOpenHelper
abgeleitet ist, wird im Laufe der Zeit immer größer. Zur Redezeit sind es mehr als 1500 Codezeilen, die nicht als cool angesehen werden. Es könnte eine elegante Lösung geben, um zu verhindern, dass sie wächst, d. H. Durch Stücke getrennt wird. Nicht sicher, was diese Stücke sein sollen. Einige Leute sagen, dass es eine schlechte Übung ist, von der erwähnten Klasse zu erben, weil dies zu einem Fehlverhalten bei der Erstellung/Aktualisierung von Datenbanken führt. Irgendein Hinweis? Danke vielmals!Meine von SQLiteOpenHelper abgeleitete Klasse wird sehr groß
Antwort
Ja, die Beispiele in der dev gezeigt. ermutigen Sie die Erstellung einer Monsterklasse, in der Sie die Namen aller Tabellen und Spalten fest codieren. Das ist ein Chaos. Möglicherweise möchten Sie eine Klasse erstellen, um jede Tabelle zu behandeln. Diese Klassen können als Data Access Objects für jede Tabelle fungieren. Diese
ist das, was ich benutze:
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);
}
Dann für jede Tabelle eine Implementierung I codieren. Die generischen tipe E sind in der Regel pojos. Beachten Sie, dass ich die Klassen, die nur dazu dienen sollen, Daten (pojos) zu speichern, nicht mit den Klassen mischen, die für das persistierende Abrufen von Daten (DAOs) zuständig sind. Zum Beispiel könnte ein Pojo Car
mit seinen Variablen (Farbe, Jahr, etc) sein. Dann würde ich einen CarDAO codieren, der DataAccessObject<Car>
verlängert. Und diese DAO-Klasse ist dafür verantwortlich, die Variablen des Pojos DB-Spalten zuzuordnen, die Tabelle abzufragen und darauf zu schreiben.
Schließlich können Sie eine SQLiteOpenHelper haben, die mit den DAOs injiziert wird, und delegiert Zeug für jede Tabelle an sie. Diese DAO-Implementierungen haben die Namen von Tabellen- und Spaltennamen. Und sie können miteinander reden, wenn sie für komplexe Anfragen benötigt werden. (Beachten Sie, dass dies auch einer der Nachteile dieses Ansatzes ist: Das Erstellen eines übersichtlichen Designs ist nicht einfach, wenn Sie Abfragen mit vielen Tabellen und Spalten benötigen).
Stimme (fast) vollständig zu. Ich bin mir nicht sicher, ob die Trennungsgrade auf Tabellen basieren.Ich würde es stattdessen auf die Domain-Objekte basieren (die in der Tat die gleichen wie die Tabellen sein können, hängt ab). +1 auf diese Antwort. – Nick
Ihr Helfer sollte nicht so groß sein. Ich kann nur annehmen, dass Sie allen Code, der Daten manipuliert, in Ihren Helper stecken.
Sie sollten Code in die Klasse einfügen, auf die er sich bezieht und auf die Sie objektorientiert zugreifen können.
z. B. Wenn Sie eine Klasse Kontakte haben. Sie würden Code, der einen Kontakt gespeichert hat, in die Datenbank einfügen.
ich als gegeben Code-Schnipsel folgen:
SQLHelper Klasse:
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: Welche meiste Arbeit macht:
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.
}
Sie vermeiden sollten alle modellspezifischen Code setzen in dein Helfer wie du kannst. Denken Sie darüber nach, dass Sie im nächsten Projekt so viel wie möglich wiederverwenden können. Sie können einige der gängigen Datenabstraktionsmuster und -prinzipien befolgen, die Sie sehen werden.
- Zum Beispiel können Sie darüber nachdenken, Active Record, wo Sie Ihre Business-Objekte haben, mit seinen Feldern und Methoden, und auch all Verfahren zum persistance bezogenen (lesen und aus der Datenbank schreiben).
- Sie können auch über ein leichtgewichtiges Objekt nachdenken und Instanzen speichern und von der Datenbank durch ein anderes Objekt abrufen, das Mapping-Funktionen bietet, wie z. B. ORMs.
- Sie können auch einen Blick auf Zend TableGateway werfen, dass es ein cooler Ansatz für die Darstellung von Datenbanktabellen als Objekte, die Sie auf Android und SQLite migrieren.
- Sie eine einfache und dennoch leistungsfähige Lösung auf hydrators Basis verwenden kann, wie ich weiter unten
persönlich erklären, ich ziehe, was hydrators
Dies ist ein Konzept weit verbreitet in einiger ORM verwendet zu verwenden, , auch in nativem Zend Framework und in anderen Systemen, um Datenpersistenz zu bieten, ist dies, um Objekte oder sogar Webformulare zu Datenbankeinträgen in leicht verständlicher Weise zu verwalten und zu verwalten.
Ein Hydrator ist ein Objekt, das die Datenbankfeldnamen auf der einen Seite den Entitätseigenschaften auf der anderen Seite zuordnet. Es speichert diese Informationen nicht intern, sondern bietet Mechanismen sowohl zum Erstellen von Objekten aus Datenbanken als auch zum Extrahieren von Datensätzen aus Objekten, um die Datenbank zu aktualisieren.
Ist etwas, das so einfach wie ein Objekt mit einem Array von Spaltennamen -> Entity Properties starten kann, und wenn die YourClass hydrate()
Methode aufgerufen wird, wird die entsprechende Information aus der Datenquelle auf das Modellobjekt übertragen, und wenn die extract(YourClass yourObject)
Methode heißt, es überträgt die in yourObject enthaltenen Daten auf den entsprechenden Datenbankeintrag
Ich mag diesen Ansatz sehr, da es sehr einfach ist, ein Interface zu erstellen, und mehrere Implementierungen für häufige Anwendungsfälle. So können Sie Änderungen in Ihrer Datenbank durchführen, ohne die Hauptobjekte oder den Helper zu beeinflussen. Mit der gleichen Schnittstelle können Sie auch Mapper erstellen, um Ihre Daten in JSON, XML, Ruheanrufe oder andere Dinge zu exportieren, die Sie sich vorstellen können.
Wenn Sie über eine gute Hydrator desing nachdenken und dann einige Klassen erstellen können, können Sie eine wirklich kleine Datenbankhilfe, wirklich kleine Entitätsobjekte, einige abstrakte Klassen, die gemeinsame Arbeit leisten, und einige konkrete Hydratoren, die bekommen können all das Gewicht, das Sie brauchen könnten, aber nie so viel, da Sie für jede Tabelle oder jeden Objekttyp einen haben können. Daher sind die Klassen deutlich kleiner und außerdem enthalten sie nur Code, der geschäftlich verwandt ist.
Sie können eine Singleton-Klasse nur öffnen und schließen DB-Verbindung (oder Fang, lassen Sie wie ein Pool) dann das Ausführen der db-Operationen mit Befehlsklasse wie in command pattern
Und Sie können facade pattern verwenden Betrachten Sie diese Befehle fusionieren in einer Ausführungsreihenfolge für komplexere Datenbankoperationen. Dadurch wird Ihr Code sauber und leicht zu kontrollieren. Wenn Sie zum Beispiel Ihre InsertBookCommand
Klasse ändern, werden alle damit verbundenen Vorgänge das Verhalten ändern.
Um es zusammenzufassen, meine Lösung ist:
öffnen DB-Verbindung und die DB als Parameter an Befehle übergeben. dann führe die Befehle aus.
- 1. selleryev Warteschlange in RabbitMQ wird sehr groß
- 2. SQLiteOpenHelper-Konstruktor wird nicht aufgerufen
- 3. Android Spinner Größe sehr groß
- 4. Abgeleitete Klasse Konstruktoraufrufe
- 5. Mit Erklärung (Abgeleitete Klasse)
- 6. Luabind: Abgeleitete Klasse als Parameter
- 7. Assign abgeleitete Klasse Basisklasse
- 8. Abgeleitete Klasse C++
- 9. Mitglied Funktionszeiger auf abgeleitete Klasse
- 10. Aufruf Template-Funktion der Eltern-Klasse von Abgeleitete Klasse
- 11. Wenn die SQLiteOpenHelper onCreate-Methode aufgerufen wird?
- 12. Swig Typumwandlung in abgeleitete Klasse?
- 13. wie von Basisklasse abgeleitete Klasse Name
- 14. Prevent abgeleitete Klasse von Gießen zu stützen
- 15. Gegossene abgeleitete Klasse zur Basis
- 16. eine abgeleitete Klasse Zwingen mit
- 17. eine abstrakte Klasse Mocking von einer abstrakten Klasse abgeleitete
- 18. Python Klasse Dekorateur abgeleitete Klasse verursacht Rekursion
- 19. Keine Erweiterungsmethode "First" auf abgeleitete Klasse
- 20. Abgeleitete Modelle einschließen Verwandte Klasse
- 21. Android: Kann ich eine SQLiteOpenHelper-Klasse für mehrere Datenbankdateien verwenden?
- 22. Statischer Initialisierer, der für eine abgeleitete Klasse nicht aufgerufen wird
- 23. Verwendung von SQLiteOpenHelper aus separaten Prozessen
- 24. SQL Server 2000 - tempdb wächst sehr groß
- 25. Skew verursacht Seitenhöhe wirklich sehr groß
- 26. ipa Dateigröße ist sehr groß xcode 7.3
- 27. Was nutzt die abgeleitete Klasse als Vorlagenparameter?
- 28. SQLiteOpenHelper "onCreate" wird nicht aufgerufen? (Die DB nicht vorhanden)
- 29. Was macht die SQLiteOpenHelper-Klasse mit dem Kontextparameter?
- 30. Könnte jemand mir helfen, meine App zu debuggen (nicht sehr groß)?
Sie sollten sich die SQLiteOpenHelper des offiziellen Kalenderanbieters oder des Kontaktanbieters ansehen :-) Die 'onUpdate()' Methode von 'ContactsDatabaseHelper' alleine ist ungefähr 900 Zeilen lang - während sie relevante Versionsänderungen an andere Methoden delegiert. Aber sie sind bei der Versionsnummer 800! Die Klasse insgesamt umfasst etwa 5000 Zeilen Code. Also sollte es dir nicht so leid tun :-) Ernsthafter: IMHO ** onlyUpgrade() sollte mit der Zeit immer größer werden **. Nichts anderes! –