KittyORM and bulk operations

alt text alt text alt text

KittyORM by design provides several methods for updating, inserting and deleting collections of entities. If you want to save a collection of entities just call save(List<M> models) method of KittyMapper.class or its implementation and all models in provided collections would be updated or inserted (KittyORM would make a decision on this by processing POJO fields that can be used for unambiguous record definition in source table). Also, you can run update or insert methods directly, if you are sure that collection contains only new or existing entities. This approach also applicable for delete(List<M> models) method of KittyMapper.class and its implementations. Take a look at this example of bulk operations using KittyMapper.class CRUD controller:

 1// Initializing database instance
 2BasicDatabase db = new BasicDatabase(getContext());
 3// Getting mapper instance
 4RandomMapper mapper = (RandomMapper) db.getMapper(RandomModel.class);
 5// Generating list of entities to insert
 6List<RandomModel> toSave = new ArrayList<>();
 7// Filling this list with randomly generated POJOs
 8RNDRandomModelFactory rndFactory = new RNDRandomModelFactory(getContext());
 9for(int i = 0; i < 100; i++) {
10    toSave.add(rndFactory.newRandomModel());
11}
12// Running bulk save
13mapper.save(toSave);

Be aware of deleting entities with delete(List<M> models) that you are received from findWhere(SQLiteCondition where, QueryParameters qParams) (or other find method) with any clause. It’s not necessary, just use deleteWhere(SQLiteCondition condition) with this clause, it is much faster.

KittyORM and bulk operations in transaction mode

Using a lot of separate insertions is not really fast, because for each such operation SQLite would start its own query and this operation costs time. However, what to do when there are a lot of insertions (or record updates)? Just force KittyMapper to apply all your operations in transaction mode. This would force SQLite to run all your statements as a one query and this can speed up execution time of insertions up to 20x. It’s really useful feature when you need to save at your database big amounts of data. So, you can run your database write operations in transaction in two different ways:

  1. Apply bulk operation in transaction mode:

     1// Initializing database instance
     2BasicDatabase db = new BasicDatabase(getContext());
     3// Getting mapper instance
     4RandomMapper mapper = (RandomMapper) db.getMapper(RandomModel.class);
     5// Generating list of entities to insert
     6List<RandomModel> toSave = new ArrayList<>();
     7// Filling this list with randomly generated POJOs
     8RNDRandomModelFactory rndFactory = new RNDRandomModelFactory(getContext());
     9for(int i = 0; i < 100; i++) {
    10    toSave.add(rndFactory.newRandomModel());
    11}
    12// Running bulk save in transaction
    13mapper.saveInTransaction(toSave);

  2. Start transaction manually, do all your write operations and finish transaction:

     1// Initializing database instance
     2BasicDatabase db = new BasicDatabase(getContext());
     3// Getting mapper instance
     4RandomMapper mapper = (RandomMapper) db.getMapper(RandomModel.class);
     5// Generating list of entities to insert
     6List<RandomModel> toInsert = new ArrayList<>();
     7// Filling this list with randomly generated POJOs
     8RNDRandomModelFactory rndFactory = new RNDRandomModelFactory(getContext());
     9for(int i = 0; i < 100; i++) {
    10    toInsert.add(rndFactory.newRandomModel());
    11}
    12// Starting transaction for your database write operations
    13startTransaction(TRANSACTION_MODES.NON_EXCLUSIVE_MODE);
    14// Running some write database operations
    15mapper.insert(toSave);
    16SQLiteConditionBuilder builder = new SQLiteConditionBuilder();
    17builder.addColumn(AbstractRandomModel.RND_ANIMAL_CNAME)
    18       .addSQLOperator(SQLiteOperator.EQUAL)
    19       .addValue(Animals.DOG.name());
    20mapper.deleteWhere();
    21// Finishing transaction
    22finishTransaction();

You may start your transaction in three modes: TRANSACTION_MODES.EXCLUSIVE_MODE, TRANSACTION_MODES.NON_EXCLUSIVE_MODE (API level 11 and higher) and TRANSACTION_MODES.LOCKING_FALSE_MODE (deprecated in API level 16). By default, KittyMapper.startTransaction() would start transaction in EXCLUSIVE_MODE. Refer to official Android documentation about transaction modes for more info.