Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call certain methods and return certain objects based on class type

Normally I try to use polymorphism to avoid using things like instanceof, and I don't like using ORM frameworks because they often cause me a lot more headache than they're worth, so I tried to make my own database class with simple features.

Some of you are probably giggling, "See, ORMs exist for a reason, don't roll your own!" but I'm not trying to make a full-blown ORM; just something lightweight for my specific use that does what I need (cue more giggling, I know).

Right now I am hitting this issue:

Normally when doing a select statement from an SQLiteDatabase when creating objects from the data tables, you use a Cursor object, iterate over the records, and instantiate an object in the loop.

Consider a Dog class that extends MyDatabaseClass.

Is it considered bad practice to do something like this:

public Cursor getDogCursor(Cursor cursor) {
    return database.query(Dog.TABLE_NAME, Dog.COLS, null, null, null, null, null);
}

public Cursor getCursor(Class<? extends MyDatabaseClass>) {
    if (clazz == Dog.class) return getDogCursor();
    //...
    return null;
}

public Dog getDogFromCursor(Cursor cursor) {
    String dogId = getLongFromColumnName(cursor, Dog._ID);
    String dogName = getStringFromColumnName(cursor, Dog.COL_NAME);
    return new Dog(dogId, dogName);
}

public MyDatabaseClass getDatabaseObjectFromCursor(Class<? extends MyDatabaseClass> clazz, Cursor cursor) {
    if (clazz == Dog.class) return getDogFromCursor(cursor);
    //...
    return null;
}

public List<? extends MyDatabaseClass> getList(Class<? extends MyDatabaseClass> clazz) {
    Cursor cursor = getCursor(clazz);
    List<MyDatabaseClass> list = new ArrayList<>();
    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
        list.add(getDatabaseObjectFromCursor(clazz, cursor);
        cursor.moveToNext();
    }
    cursor.close();
    return list;
}

}

So now if I want to get a list of Dogs I can do

List<Dog> dogList = (List<Dog>) myDatabaseInstance.getList(Dog.class);

or make it a static method of the Dog class if need be.

Is this considered a valid approach, or is it considered dangerous to do that class comparison like this? I would have loved to use polymorphism somehow but I couldn't see any good way to do it on account of there being different fields for different classes with different constructors.

like image 766
user7086932 Avatar asked Aug 30 '26 20:08

user7086932


1 Answers

if you supply the data type, you can use generics.

    public <T extends MyDatabaseClass> List<T> getList(Class<T> clazz) {
        Cursor cursor = getCursor(clazz);
        List<T> list = new ArrayList<>();
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            //noinspection unchecked
            list.add((T) getDatabaseObjectFromCursor(clazz, cursor));
            cursor.moveToNext();
        }
        cursor.close();
        return list;
    }
like image 53
Paulo Avatar answered Sep 02 '26 10:09

Paulo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!