How can I efficiently refactor SQLite access in Java?

eryno

I am writing an Android app, in Java, which uses an SQLite database containing dozens of tables. I have a few Datasource classes set up to pull data from these tables and turn them into their respective objects. My problem is that I do not know the most efficient way to structure code that accesses the database in Java.

The Datasource classes are getting very repetitive and taking a long time to write. I would like to refactor the repetition into a parent class that will abstract away most of the work of accessing the database and creating objects.

The problem is, I am a PHP (loosely-typed) programmer and I'm having a very hard time solving this problem in a strictly-typed way.

Thinking in PHP, I'd do something like this:

public abstract class Datasource {

    protected String table_name;
    protected String entity_class_name;

    public function get_all () {

        // pseudo code -- assume db is a connection to our database, please.
        Cursor cursor  =  db.query( "select * from {this.table_name}");

        class_name  =  this.entity_class_name;
        entity  =  new $class_name;

        // loops through data in columns and populates the corresponding fields on each entity -- also dynamic
        entity  =  this.populate_entity_with_db_hash( entity, cursor );

        return entity;
    }
}

public class ColonyDatasource extends Datasource {

    public function ColonyDataSource( ) {
        this.table_name  =  'colony';
        this.entity_class_name  =  'Colony';
    }
}

Then new ColonyDatasource.get_all() would get all the rows in table colony and return a bunch of Colony objects, and creating the data source for each table would be as easy as creating a class that has little more than a mapping of table information to class information.

Of course, the problem with this approach is that I have to declare my return types and can't use variable class names in Java. So now I'm stuck.

What should one do instead?

(I am aware that I could use a third-party ORM, but my question is how someone might solve this without one.)

CenterOrbit

First, is that you don't want to do these lines in your Java code:

class_name  =  this.entity_class_name;
entity  =  new $class_name;

It is possible to do what you are suggesting, and in languages such as Java it is called reflection. https://en.wikipedia.org/wiki/Reflection_(computer_programming)

In this (and many cases) using reflection to do what you want is a bad idea for many reasons.

To list a few:

  • It is VERY expensive
  • You want the compiler to catch any mistakes, eliminating as many runtime errors as possible.
  • Java isn't really designed to be quacking like a duck: What's an example of duck typing in Java?

Your code should be structured in a different way to avoid this type of approach.

Sadly, I do believe that because it is strictly typed, you can't automate this part of your code:

// loops through data in columns and populates the corresponding fields on each entity -- also dynamic
        entity  =  this.populate_entity_with_db_hash( entity, cursor );

Unless you do it through means of reflection. Or shift approaches entirely and begin serializing your objects (¡not recommending, just saying it's an option!). Or do something similar to Gson https://code.google.com/p/google-gson/. I.e. turn the db hash into a json representation and then using gson to turn that into an object.

What you could do, is automate the "get_all" portion of the object in the abstract class since that would be repetitive nearly every instance, but use an implementation so that you can have the abstract function rest assured that it can call a method of it's extending object. This will get you most of the way towards your "automated" approach, reducing the amount of code you must retype.

To do this we must consider the fact that Java has:

Try something like this (highly untested, and most likely wont compile) code:

// Notice default scoping
interface DataSourceInterface {
    //This is to allow our GenericDataSource to call a method that isn't defined yet.
    Object cursorToMe(Cursor cursor);
}

//Notice how we implement here?, but no implemented function declarations!
public abstract class GenericDataSource implements DataSourceInterface {
    protected SQLiteDatabase database;

    // and here we see Generics and Objects being friends to do what we want.
    // This basically says ? (wildcard) will have a list of random things
    // But we do know that these random things will extend from an Object
    protected List<? extends Object> getAll(String table, String[] columns){
        List<Object> items = new ArrayList<Object>();

        Cursor cursor = database.query(table, columns, null, null, null, null,null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            // And see how we can call "cursorToMe" without error!
            // depending on the extending class, cursorToMe will return 
            //   all sorts of different objects, but it will be an Object nonetheless!
            Object object = this.cursorToMe(cursor);
            items.add(object);
            cursor.moveToNext();
        }
        // Make sure to close the cursor
        cursor.close();
        return items;
    }
}

//Here we extend the abstract, which also has the implements.
// Therefore we must implement the function "cursorToMe"
public class ColonyDataSource extends GenericDataSource {
    protected String[] allColumns = {
        ColonyOpenHelper.COLONY_COLUMN_ID, 
        ColonyOpenHelper.COLONY_COLUMN_TITLE, 
        ColonyOpenHelper.COLONY_COLUMN_URL
    };

    // Notice our function overloading!
    //    This getAll is also changing the access modifier to allow more access
    public List<Colony> getAll(){
        //See how we are casting to the proper list type?
        // Since we know that our getAll from super will return a list of Colonies.
        return  (List<Colony>)super.getAll(ColonyOpenHelper.COLONY_TABLE_NAME, allColumns);
    }


    //Notice, here we actually implement our db hash to object
    // This is the part that would only be able to be done through reflection or what/not
    // So it is better to just have your DataSource object do what it knows how to do.
    public Colony cursorToMe(Cursor cursor) {
        Colony colony = new Colony();
        colony.setId(cursor.getLong(0));
        colony.setTitle(cursor.getString(1));
        colony.setUrl(cursor.getString(2));
        return colony;
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How can I efficiently refactor SQLite access in Java?

From Dev

How can I access semi-sparse data efficiently in java?

From Dev

How can I use the Factory pattern to refactor my Java code?

From Dev

How can I refactor this code to be more concise?

From Dev

How can I refactor a set of ugly if statements?

From Dev

How can i refactor these lines of code?

From Dev

How Can I Refactor To Avoid Duplication?

From Dev

how can I translate efficiently a Java code to python?

From Dev

How can I refactor this horrid abstract java class with multiple generics into something "better"?

From Dev

How can I access my SQLite Database in a static way?

From Dev

How can I efficiently write the (700,000 lines) content from a For-loop into a file efficiently from Java?

From Dev

How can I shuffle bits efficiently?

From Dev

How can I efficiently index a file?

From Dev

How can I efficiently find the accuracy of a classifier

From Dev

How can I efficiently store a grid of rectangles?

From Dev

How can I efficiently merge these two datasets?

From Dev

How can I write this CSS more efficiently?

From Dev

How Can I Rewrite This More Efficiently

From Dev

How can I efficiently render an image in Django?

From Dev

How can I write this CSS more efficiently?

From Dev

How can I implement these JavaScript functions efficiently

From Dev

How can I efficiently use threads in this case?

From Dev

How can I refactor these two lines to one statement?

From Dev

How can I tell PHPStorm to refactor namespaces and class names?

From Dev

How can I use ESLint to refactor/restyle code in webstorm

From Dev

How can I refactor this code that finds the end of Unix time?

From Dev

How can I remove/refactor a «friend» dependency declaration properly?

From Dev

How can I refactor these simple functions and make them more DRY?

From Dev

How can I refactor a simple class member to a more complex type?

Related Related

  1. 1

    How can I efficiently refactor SQLite access in Java?

  2. 2

    How can I access semi-sparse data efficiently in java?

  3. 3

    How can I use the Factory pattern to refactor my Java code?

  4. 4

    How can I refactor this code to be more concise?

  5. 5

    How can I refactor a set of ugly if statements?

  6. 6

    How can i refactor these lines of code?

  7. 7

    How Can I Refactor To Avoid Duplication?

  8. 8

    how can I translate efficiently a Java code to python?

  9. 9

    How can I refactor this horrid abstract java class with multiple generics into something "better"?

  10. 10

    How can I access my SQLite Database in a static way?

  11. 11

    How can I efficiently write the (700,000 lines) content from a For-loop into a file efficiently from Java?

  12. 12

    How can I shuffle bits efficiently?

  13. 13

    How can I efficiently index a file?

  14. 14

    How can I efficiently find the accuracy of a classifier

  15. 15

    How can I efficiently store a grid of rectangles?

  16. 16

    How can I efficiently merge these two datasets?

  17. 17

    How can I write this CSS more efficiently?

  18. 18

    How Can I Rewrite This More Efficiently

  19. 19

    How can I efficiently render an image in Django?

  20. 20

    How can I write this CSS more efficiently?

  21. 21

    How can I implement these JavaScript functions efficiently

  22. 22

    How can I efficiently use threads in this case?

  23. 23

    How can I refactor these two lines to one statement?

  24. 24

    How can I tell PHPStorm to refactor namespaces and class names?

  25. 25

    How can I use ESLint to refactor/restyle code in webstorm

  26. 26

    How can I refactor this code that finds the end of Unix time?

  27. 27

    How can I remove/refactor a «friend» dependency declaration properly?

  28. 28

    How can I refactor these simple functions and make them more DRY?

  29. 29

    How can I refactor a simple class member to a more complex type?

HotTag

Archive