[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5. Advanced Concepts


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.1 Spring Configuration

ORMLite contains some classes which make it easy to configure the various database classes using the Spring Framework.

TableCreator

Spring bean that auto-creates any tables that it finds DAOs for if the system property ormlite.auto.create.tables has been set to true. It will also auto-drop any tables that were auto-created if the property ormlite.auto.drop.tables has been set to true. This should be used carefully and probably only in tests.

DaoFactory

Spring bean that can be used to create Dao’s for certain classes without needing to define their own Dao class.

Here’s an example of a full Spring configuration.

 
<!-- URL used for database, probably should be in properties file -->
<bean id="databaseUrl" class="java.lang.String">
    <!-- we are using the in-memory H2 database in this example -->
    <constructor-arg index="0" value="jdbc:h2:mem:account" />
</bean>

<!-- datasource used by ORMLite to connect to the database -->
<bean id="connectionSource"
    class="com.j256.ormlite.jdbc.JdbcConnectionSource"
    init-method="initialize">
    <property name="url" ref="databaseUrl" />
    <!-- probably should use system properties for these too -->
    <property name="username" value="foo" />
    <property name="password" value="bar" />
</bean>

<!-- abstract dao that is common to all defined daos -->
<bean id="baseDao" abstract="true" init-method="initialize">
    <property name="connectionSource" ref="connectionSource" />
</bean>

<!-- our daos -->
<bean id="accountDao"
    class="com.j256.ormlite.examples.common.AccountDaoImpl"
    parent="baseDao" />
<bean id="deliveryDao" class="com.j256.ormlite.spring.DaoFactory"
  factory-method="createDao">
    <constructor-arg index="0" ref="connectionSource" />
    <constructor-arg index="1"
      value="com.j256.ormlite.examples.spring.Delivery" />
</bean>

You can also take a look at the spring example code. See spring example.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.2 Class Configuration

The simplest mechanism for configuring a class to be persisted by ORMLite is to use the @DatabaseTable and @DatabaseField annotations. See section Adding ORMLite Annotations. However if you do not own the class you are persisting or there are permission problems with the class, you may want to configure the class using Java code instead.

To configure a class in code, you use the DatabaseFieldConfig and DatabaseTableConfig objects. The field config object holds all of the details that are in the @DatabaseField annotation as well as the name of the corresponding field in the object. The DatabaseTableConfig object holds the class and the corresponding list of DatabaseFieldConfigs. For example, to configure the Account object using Java code you’d do something like the following:

 
List<DatabaseFieldConfig> fieldConfigs =
    new ArrayList<DatabaseFieldConfig>();
DatabaseFieldConfig field1 = new DatabaseFieldConfig("name");
field1.setId(true);
fieldConfigs.add(field1);
DatabaseFieldConfig field2 = new DatabaseFieldConfig("password");
field2.setCanBeNull(false);
fieldConfigs.add(field2);
DatabaseTableConfig<Account> accountTableConfig
    = new DatabaseTableConfig<Account>(Account.class, fieldConfigs);

AccountDaoImpl accountDao =
    new AccountDaoImpl(connectionSource, accountTableConfig);

See the Javadocs for the DatabaseFieldConfig class for the fields to pass to the constructor. You can also use the no-argument constructor and call the setters for each field. You use the setters as well when you are configuring a class using Spring wiring. Here is the above example in Spring:

 
<bean id="accountTableConfig"
  class="com.j256.ormlite.table.DatabaseTableConfig">
    <property name="dataClass"
        value="com.j256.ormlite.examples.common.Account" />
    <property name="tableName" value="account" />
    <property name="fieldConfigs">
        <list>
            <bean class="com.j256.ormlite.field.DatabaseFieldConfig">
                <property name="fieldName" value="name" />
                <property name="id" value="true" />
            </bean>
            <bean class="com.j256.ormlite.field.DatabaseFieldConfig">
                <property name="fieldName" value="password" />
                <property name="canBeNull" value="false" />
            </bean>
        </list>
    </property>
</bean>

You can also look at the field configuration example code. See field config example.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.3 Database Specific Code

ORMLite uses an internal DatabaseType object which defines all of the per-database information necessary to support the various features on all of the different database types. The JdbcConnectionSource uses the database URL to pick the correct DatabaseType. If it picks an incorrect one then you may need to set the DatabaseType on the connection source directly. For example:

 
String databaseUrl = "jdbc:derby://dbserver1:1527/";
DatabaseType databaseType = new DerbyClientServerDatabaseType();
ConnectionSource connectionSource =
   new JdbcConnectionSource(databaseUrl, databaseType);

Android users do not need to worry about this because the AndroidConnectionSource always uses the SqliteAndroidDatabaseType. See section Using With Android.

The DatabaseType classes are found in com.j256.ormlite.db. Each of the supported databases has a class there which implements the code needed to handle the unique features of the database (H2DatabaseType, MySqlDatabaseType, etc.). If you want to help develop and test against other SQL databases, a externally available server that the author could connect to and test against would be appreciated. Please contact the author if your database is not supported or if you want to help.

The following methods are currently used by the system to isolate the database specific behavior in one place. See the javadocs for the DatabaseType class for the most up to date information.

isDatabaseUrlThisType

Return true if the database URL corresponds to this database type. Usually the URL is in the form jdbc:ddd:… where ddd is the driver url part.

loadDriver

Load the driver class associated with this database so it can wire itself into JDBC.

appendColumnArg

Takes a field type and appends the SQL necessary to create the field. It may also generate arguments for the end of the table create statement or commands that must run before or after the table create.

dropColumnArg

Takes a field type and adds all of the commands necessary to drop the column from the database.

appendEscapedEntityName

Add a entity-name (table or column name) word to the SQL wrapped in the proper characters to escape it. This avoids problems with table, column, and sequence-names being reserved words.

appendEscapedWord

Add the word to the string builder wrapped in the proper characters to escape it. This avoids problems with data values being reserved words.

generateIdSequenceName

Return the name of an ID sequence based on the table-name and the field-type of the id. This is required by some database types when we have generated ids.

getCommentLinePrefix

Return the prefix to put at the front of a SQL line to mark it as a comment.

isIdSequenceNeeded

Return true if the database needs a sequence when you insert for generated IDs. Some databases handle generated ids internally.

getFieldConverter

Return the field converter associated with a particular field type. This allows the database instance to convert a field as necessary before it goes to the database.

isVarcharFieldWidthSupported

Return true if the database supports the width parameter on VARCHAR fields.

isLimitSqlSupported

Return true if the database supports the LIMIT sql command.

isLimitAfterSelect

Return true if the LIMIT should be called after SELECT otherwise at the end of the WHERE (the default).

appendLimitValue

Add the necessary SQL to limit the results to a certain number.

isOffsetSqlSupported

Return true if the database supports the OFFSET SQL command in some form.

isOffsetLimitArgument

Return true if the database supports the offset as a comma argument from the limit. This also means that the limit must be specified if the offset is specified.

appendOffsetValue

Append to the string builder the necessary SQL to start the results at a certain row number.

appendSelectNextValFromSequence

Add the SQL necessary to get the next-value from a sequence. This is only necessary if isIdSequenceNeeded returns true.

appendCreateTableSuffix

Append the SQL necessary to properly finish a CREATE TABLE line.

isCreateTableReturnsZero

Returns true if a ’CREATE TABLE’ statement should return 0. False if > 0.

isEntityNamesMustBeUpCase

Returns true if table and field names should be made uppercase. This is an unfortunate "feature" of Derby and Hsqldb. See the Javadocs for the class for more information.

isNestedSavePointsSupported

Returns true if the database supports nested savepoints (transactions).

getPingStatement

Return an statement that doesn’t do anything but which can be used to ping the database by sending it over a database connection.

isBatchUseTransaction

Returns true if batch operations should be done inside of a transaction. Default is false in which case auto-commit disabling will be done.

isTruncateSupported

Returns true if the table truncate operation is supported.

isCreateIfNotExistsSupported

Returns true if the table creation IF NOT EXISTS syntax is supported.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.4 DAO Methods

The DAO classes provide the following methods that you can use to store your objects to your database. This list may be out of date. See the Dao interface class for the latest methods.

queryForId(ID id)

Looks up the id in the database and retrieves an object associated with it.

queryForFirst(PreparedQuery<T> preparedQuery)

Query for and return the first item in the object table which matches a prepared statement. This can be used to return the object that matches a single unique column. You should use queryForId if you want to query for the id column.

queryForAll()

Query for all of the items in the object table and return a list of them. For medium sized or large tables, this may load a lot of objects into memory so you should consider using the iterator method instead.

queryForEq(String fieldName, Object value)

Query for the items in the object table that match a simple where with a single field = value type of WHERE clause. This is a convenience method for calling queryBuilder().where().eq(fieldName, value).query().

queryForMatching(T matchObj)

Query for the rows in the database that match the object passed in as an argument. Any fields in the matching object that are not the default value (null, false, 0, 0.0, etc.) are used as the matching parameters with AND. If you are worried about SQL quote escaping, you should use queryForMatchingArgs.

queryForMatchingArgs(T matchObj)

Same as queryForMatching but this uses SQL ? arguments. This is slightly more expensive but you don’t have to worry about SQL quote escaping.

queryForFieldValues(Map<String, Object> fieldValues)

Query for the rows in the database that matches all of the field to value entries from the map passed in.

queryForFieldValuesArgs(Map<String, Object> fieldValues)

Same as queryForFieldValues but this uses SQL ? arguments. This is slightly more expensive but you don’t have to worry about SQL quote escaping.

queryForSameId(T data)

Query for a data item in the table that has the same ID as the data parameter.

queryBuilder()

Create and return a new QueryBuilder object which allows you to build a custom query. See section Query Builder Basics.

updateBuilder()

Create and return a new UpdateBuilder object which allows you to build a custom update statement. See UpdateBuilder.

deleteBuilder()

Create and return a new DeleteBuilder object which allows you to build a custom delete statement. See DeleteBuilder.

query(PreparedQuery<T> preparedQuery)

Query for the items in the object table which match a prepared statement. See section Custom Statement Builder. This returns a list of matching objects. For medium sized or large tables, this may load a lot of objects into memory so you should consider using the iterator method instead.

create(T data)

Create a new entry in the database from an object. Should return 1 indicating 1 row was inserted.

createIfNotExists(T data)

This is a convenience method to creating a data item but only if the ID does not already exist in the table. This extracts the id from the data parameter, does a query for on it, returning the data if it exists. If it does not exist then create is called with the data parameter.

createOrUpdate(T data)

This is a convenience method for creating an item in the database if it does not exist. The id is extracted from the data argument and a query-by-id is made on the database. If a row in the database with the same id exists then all of the columns in the database will be updated from the fields in the data parameter. If the id is null (or 0 or some other default value) or doesn’t exist in the database then the object will be created in the database. This also means that your data item must have an id field defined.

update(T data)

Save the fields from an object to the database. If you have made changes to an object, this is how you persist those changes to the database. You cannot use this method to update the id field – see updateId(). This should return 1 since 1 row was updated.

updateId(T data, ID newId)

Update an object in the database to change its id to a new id. The data must have its current id set and the new-id is passed in as an argument. After the id has been updated in the database, the id field of the data object will also be changed. This should return 1 since 1 row was updated.

update(PreparedUpdate<T> preparedUpdate)

Update objects that match a custom update statement.

refresh(T data, ID newId)

Does a query for the object’s id and copies in each of the field values from the database to refresh the data parameter. Any local object changes to persisted fields will be overwritten. If the database has been updated this brings your local object up-to-date. This should return 1 since 1 row was retrieved.

delete(T data)

Delete an object from the database. This should return 1 since 1 row was removed.

deleteById(ID id)

Delete an object from the database if you have its id. This should return 1 since 1 row was removed.

delete(Collection<T> datas)

Delete a collection of objects from the database using an IN SQL clause. This returns the number of rows that were deleted.

deleteIds(Collection<ID> ids)

Delete the objects that match the collection of ids from the database using an IN SQL clause. This returns the number of rows that were deleted.

delete(PreparedDelete<T> preparedDelete)

Delete objects that match a custom delete statement.

iterator()

This method satisfies the Iterable Java interface for the class and allows you to iterate through the objects in the table using SQL. This method allows you to do something like:

 
for (Account account : accountDao) { … }

WARNING: See the Dao class for warnings about using this method.

iterator(PreparedQuery<T> preparedQuery)

Same is the iterator method but with a prepared statement parameter. See section Custom Statement Builder.

getWrappedIterable()

This returns a one time use iterable class that can be closed afterwards. The DAO itself is CloseableWrappedIterable but multiple threads can each call this to get their own closeable iterable. This allows you to do something like:

 
CloseableWrappedIterable<Account> wrappedIterable =
    accountDao.getWrappedIterable();
try {
    for (Account account : wrappedIterable) {
        …
    }
} finally {
    wrappedIterable.close();
}
getWrappedIterable(PreparedQuery<T> preparedQuery)

Same as getWrappedIterable() but with a prepared query parameter.

closeLastIterator()

This closes the last iterator returned by the iterator() method.

NOTE: This is not reentrant. If multiple threads are getting iterators from this DAO then you should use getWrappedIterable() method.

queryRaw(String query, String... arguments)

Query for all of the items in the object table that match the SQL select query argument. This method allows you to do special queries that aren’t supported otherwise. For medium sized or large tables, this may load a lot of objects into memory so you should consider using the iterator() method on the GenericRawResults instead of the getResults method. See section Issuing Raw Queries.

queryRaw(String query, RawRowMapper<UO> mapper, String... arguments)

Same as the above queryRaw method but with the addition of a row mapper. Instead of each row being returned as an array of strings, this will map the row using the mapper object passed in. See section Issuing Raw Queries.

queryRaw(String query, DataType[] columnTypes, RawRowObjectMapper<UO> mapper, String... arguments)

Similar to the above queryRaw but uses the column-types array to present an array of object results to the mapper instead of strings. The arguments are optional but can be set with strings to expand ? type of SQL. See section Issuing Raw Queries.

queryRaw(String query, DataType[] columnTypes)

Same as the above queryRaw method but with the addition of a an array of column data types. Instead of each row being returned as an array of strings, they are returned as an array of objects. See section Issuing Raw Queries.

queryRawValue(String query, String... arguments)

Perform a raw query that returns a single value (usually an aggregate function like MAX or COUNT). If the query does not return a single long value then it will throw a SQLException.

executeRaw(String statement)

Run a raw execute SQL statement against the database. See section Issuing Raw Execute Statements.

updateRaw(String statement)

Run a raw update SQL statement (INSERT, DELETE, or UPDATE against the database. See section Issuing Raw Update Statements.

callBatchTasks(Callable callable)

Call the call-able that will perform a number of batch tasks. This is for performance when you want to run a number of database operations at once – maybe loading data from a file. This will turn off what databases call "auto-commit" mode, run the call-able and then re-enable "auto-commit". If auto-commit is not supported then it will try to use a database transaction to speed up the tasks.

NOTE: If neither auto-commit nor transactions are supported by the database type then this method may not give any performance improvement.

 
accountDao.callBatchTasks(connectionSource,
  new Callable<Void>() {
    public Void call() throws SQLException {
        // insert a number of accounts at once
        for (Account account : accountsToInsert) {
           // update our account object
           accountDao.create(account);
        }
        return null;
    }
});
countOf()

Returns the value returned from a SELECT COUNT(*) query which is the number of rows in the table. Depending on the database and the size of the table, this could be expensive.

countOf(PreparedQuery<T> preparedQuery)

Returns the number of rows in the table associated with the prepared query passed in. Depending on the size of the table and the database type, this may be expensive and take a while.

assignEmptyForeignCollection(T parent, String fieldName)

Assigns an empty collection to the appropriate collection field that has the field-name. This allows you to add things to the collection from the start. This allows you to do something like:

 
accoundDao.assignEmptyForeignCollection(account, "orders");
// this would add it the collection and the internal DAO
account.orders.add(order1);
setObjectCache(boolean enabled);

Call this with true to enable an object cache for the DAO. Set to false to disable any caching. See section Object Caches.

setObjectCache(ObjectCache objectCache);

Same as setObjectCache(boolean) except you specify the actual cache instance to use for the DAO. This allows you to inject your own cache classes. Call it with null to disable the cache. See section Object Caches.

clearObjectCache();

Flush the object cache if it has been enabled. This will remove an objects that are in the cache to reclaim memory. Any future queries will re-request them from the database.

mapSelectStarRow(DatabaseResults results)

Return the latest row from the database results from a query to select * (star). This allows you to remap the results. It is particularly useful if you are repositioning a database cursor externally.

getSelectStarRowMapper()

Return a row mapper that is suitable for mapping results from a query to select * (star).

idExists(ID id)

Returns true if an object exists that matches this ID otherwise false.

startThreadConnection()

WARNING: This method is for advanced users only. It is only to support the setAutoCommit(conn, boolean) and other methods below. Chances are you should be using the TransactionManager class’ callInTransaction(Callable) method instead f this method unless you know what you are doing.

This allocates a connection for this specific thread that will be used in all other DAO operations. The thread must call endThreadConnection(conn) once it is done with the connection. It is highly recommended that a try / finally pattern be used here to ensure you do not leak connections.

This is really only useful if you are using a pooled connection source and want to do certain operations on the same pool. Android users, for example have a single connection to the database so this is effectively a no-op.

endThreadConnection(DatabaseConnection connection)

This method is used to free the connection returned by the startThreadConnection() above.

setAutoCommit(DatabaseConnection connection, boolean autoCommit)

Set auto-commit mode to be true or false on the connection returned by the startThreadConnection(). This may not be supported by all database types.

isAutoCommit(DatabaseConnection connection)

Return true if the database connection returned by the startThreadConnection() is in auto-commit mode otherwise false. This may not be supported by all database types.

commit(DatabaseConnection connection)

If you have previously called setAutoCommit(conn, false) then this will commit all changes to the database made from that point up to now on the connection returned by the startThreadConnection(). The changes will be written to the database and discarded. The connection will continue to stay in the current auto-commit mode.

WARNING: Chances are you should be using the TransactionManager class’ callInTransaction(Callable) method instead unless you know what you are doing.

rollBack(DatabaseConnection connection)

If you have previously called setAutoCommit(conn, false) then this will roll-back and flush all changes to the database made from that point up to now on the connection returned by the startThreadConnection(). None of those changes will be written to the database and are discarded. The connection will continue to stay in the current auto-commit mode.

WARNING: Chances are you should be using the TransactionManager class’ callInTransaction(Callable) method instead unless you know what you are doing.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.5 ORMLite Logging

ORMLite uses a log system which can plug into Apache commons logging, Log4j, Android Log, or its own internal log implementations. The logger code first looks for the android.util.Log and if found will use the Android internal logger. Next it looks for org.apache.commons.logging.LogFactory class in the class-path – if found it will use Apache commons logging. If that class is not found it then looks for org.apache.log4j.Logger and if found will use Log4j. If none of these classes are available it will use an internal logger – see LocalLog. The logger code also provides simple {} argument expansion like slf4j which means that you can save on toString() calls and StringBuilder operations if the log level is not high enough. This allows us to do something like the following:

 
private static Logger logger =
  LoggerFactory.getLogger(QueryBuilder.class);
…
logger.debug("built statement {}", statement);

If you are using log4j (through Apache commons logging or directly), you can use something like the following as your log4j.properties file to see details about the SQL calls.

 
log4j.rootLogger=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# print the date in ISO 8601 format
log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} [%p] %c{1} %m%n

# be more verbose with our code
log4j.logger.com.j256.ormlite=DEBUG

# to enable logging of arguments to all of the SQL calls
# uncomment the following lines
#log4j.logger.com.j256.ormlite.stmt.mapped.BaseMappedStatement=TRACE
#log4j.logger.com.j256.ormlite.stmt.mapped.MappedCreate=TRACE
#log4j.logger.com.j256.ormlite.stmt.StatementExecutor=TRACE

Notice that you can uncomment the last lines in the above log4j.properties file to log the arguments to the various SQL calls. This may expose passwords or other sensitive information in the database so probably should only be used during debugging and should not be the default.

If you are using the LocalLog logger (which is helpful for testing at least) then you can configure it using a ormliteLocalLog.properties file. The file configures the log output of the ORMLite LocalLog class. Lines in the file have the format class-regex-pattern = Level. For example:

 
com\.j256\.ormlite.* = DEBUG
com\.j256\.ormlite\.stmt\.mapped\.BaseMappedStatement = TRACE
com\.j256\.ormlite\.stmt\.mapped\.MappedCreate = TRACE
com\.j256\.ormlite\.stmt\.StatementExecutor = TRACE

NOTE: You should escape any period characters with a single backslash unless they are part of a regex match.

For logging with Android, See section Android Logging.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.6 External Dependencies

ORMLite does not have any direct dependencies. It has logging classes that depend on Apache commons-logging and Log4j but these classes will not be referenced unless they exist in the class-path.

If you want to get the ORMLite Junit tests to run, there are test dependencies on the following packages:

javax.persistence

For testing the compatibility annotations @Column and the like.

org.junit

We use Junit for our unit tasks.

org.easymock.easymock

We use, and are in love with, EasyMock. It allows us to mock out dependencies so we can concentrate on testing a particular class instead of the whole package.

com.h2database

As a test database implementation, H2 is very fast and simple to use. However, we recommend MySQL or Postgres for multi-threaded, high-performance, production databases.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.7 Using Database Transactions

Database transactions allow you to make a number of changes to the database and then if any of them fail, none of the changes are actually written. For example, let’s say you are recording an order into your order entry system which requires you to insert a row into the Order table and also to update the Account table with the order number. If the Order was inserted but then a disk error stopped the Account from being updated, the Order data would be left dangling. If you used a transaction then both changes would be saved to the database only when the transaction was closed. Most (not all) databases support transactions which are designed specifically with these sorts of scenarios in mind.

ORMLite has basic support for transactions through the use of the TransactionManager class which wraps databases operations in a transaction. If those operations throw an exception, then the transaction is "rolled-back" and none of the operations are persisted to the database. Once the operations are finished, if no exception is thrown, then the transaction is "committed" and the changes are written to the database.

 
// we need the final to see it within the Callable
final Order order = new Order();

TransactionManager.callInTransaction(connectionSource,
  new Callable<Void>() {
    public Void call() throws Exception {
        // insert our order
        orderDao.create(order);
        // now add the order to the account
        account.setOrder(order);
        // update our account object
        accountDao.update(account);
        // you could pass back an object here
        return null;
    }
});

If for some reason, the accountDao.update() fails in the above example, the order insert will not be committed to the database. Transactions allow you to make multiple operations while still ensuring data integrity. Notice that you can return an object from the callable so you could pass back the number of rows affected or other information.

NOTE: Performing database operations within a transaction also has the side effect of better performance since a number of changes are written at once in a batch. The Dao.callBatchTasks() method should always be used if you are looking for performance of a large number of operations. See callBatchTasks.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.8 Object Caches

As of September 2011, one of the newer features in ORMLite is the ability to enable an object cache for a DAO. The object cache keeps an internal collection of objects that have been created or queried and will return a reference to the same object if it is handled in the future.

For example:

 
Dao<Account, String> accountDao =
    DaoManager.createDao(connectionSource, Account.class);
// enable the default object cache for this dao
accountDao.setObjectCache(true);

Account account = new Account("Jim Coakley");
accountDao.create(account);
// this will create the account object and add it to cache

Account result = dao.queryForId("Jim Coakley");
// this result will be the same object as account above
assertSame(account, result);

NOTE: For an object cache to work, the class being stored must have an ID field. If you try to enable the object cache for a class without an ID field, an exception will be thrown. The following operations are supported by the object cache:

By default the cache that is used internally by ORMLite if you enable the cache with true will be a "weak-reference" cache. This means that if no other code has a strong reference to the object, it will be removed from the cache during the next garbage collection cycle. ORMLite also has a "soft-reference" cache which will use more memory to hold objects if available and supported by your OS. You can enable it using:

 
Dao<Account, String> accountDao =
    DaoManager.createDao(connectionSource, Account.class);
// enable a soft-reference cache
accountDao.setObjectCache(
    ReferenceObjectCache.makeSoftCache());

The reference caches store a small object that refers to the cached object. These small objects only get cleaned up when the object is accessed. You should consider calling the cleanNullReferencesAll() method on your cache to remove these objects and free up their associated memory on occasion.

There is also a Least Recently Used (LRU) cache that will store a certain number of objects based on a capacity value. Each class gets the same capacity value so if the same cache is used in 5 different daos, then 500 objects will be held in the LruObjectCache if the capacity is 100.

 
Dao<Account, String> accountDao =
  DaoManager.createDao(connectionSource, Account.class);
// enable least-recently-used cache with max 100 items per class
accountDao.setObjectCache(new LruObjectCache(100));

You can also implement your own cache class that implements the ObjectCache interface.

All of the caches can be cleared if you want to free up memory and you can also disable the cache from the DAO if necessary.

 
// clear all Account items from the cache
accountDao.clearObjectCache();
…
// disable the cache
accountDao.setObjectCache(false);

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.9 Configuring a Maven Project

To use ORMLite in your project if you are using maven, then you should add the following configuration stanza to your pom.xml file. As mentioned below, you will also need to add some database driver as well to your dependency list. In this example we are using MySQL but any of the supported JDBC database drivers will do.

 
<project>
    …
    <dependencies>
        <dependency>
            <groupId>com.j256.ormlite</groupId>
            <artifactId>ormlite-jdbc</artifactId>
            <version>4.48</version>
        </dependency>
        <!-- You will need to add some sort of database driver too.
             In this example we've used MySQL. -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.10</version>
        </dependency>
    </dependencies>
</project>

The -jdbc artifact mentioned in the example depends on the -core artifact, but that should be pulled in automatically by maven.

NOTE: I do not have any details about how to configure Android projects with maven. If you are doing so then just replace the ormlite-jdbc artifact name with ormlite-android.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.10 Running Batch Operations

Every so often you need to efficiently do a number of database updates at one time – bulk database inserts is a common pattern. ORMLite supports a callBatchTasks method on the Dao class which supports this behavior in most database types. For example:

 
final List<Account> accountsToInsert = new ArrayList<Account>();
…
accountDao.callBatchTasks(new Callable<Void>() {
    public Void call() throws Exception {
        for (Account account : accountsToInsert) {
            accountDao.create(account);
        }
    }
});

Databases by default commit changes after every SQL operation. This method disables this "auto-commit" bahavior so a number of changes can be made faster and then committed all at once. More specifically, the method turns "auto-commit", calls the Callable.call() method passed in as an argument, calls SQL commit to persist the changes when the call returns, and finally re-enabled auto-commit. Some databases do not support auto-commit so a transaction may be used to accomplish the same behavior.

NOTE: If neither auto-commit nor transactions are supported by the database type then callBatchTasks method may do nothing.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.11 Custom Data Type Persisters

ORMLite has internal definitions for storing the basic primitive and other common data types. See section Persisted Data Types. Sometimes, however, you either want to store a new data type in your database or you want to change the way ORMLite stores values to the database for common types – this often happens when you are trying to work with an existing schema. You can change how types are stored in the database by defining a class which implements the DataPersister interface.

For example, you might have a Date field in an existing database that was not nullable but instead stored the date 0000-00-00 when there was no date. You want ORMLite to return null if the 0 date was retrieved from the database. To implement a custom data persister to handle the Date type in this manner would probably override the com.j256.ormlite.field.types.DateType class and tweak the result-to-sql-argument method as follows:

 
@Override
public Object resultToSqlArg(FieldType fieldType,
      DatabaseResults results, int columnPos)
      throws SQLException {
   Timestamp timestamp = results.getTimestamp(columnPos);
   if (TODO: somehow test fo 0000-00-00 here)
      return null;
   else
      return timestamp;
}

The data persister example has a MyDatePersister class which does just that. See data persister example. To use your persister class on a particular field in your objects, you would do something like this:

 
@DatabaseField(persisterClass = MyDatePersister.class)
Date birthDate;

ORMLite also allows you to define data persisters for atypical or custom data types that are not handled at all by the internal classes. When defining a data persister class from scratch, you could extend one of the other data type persisters or the BaseDataType class. You will need to define the following methods.

  1. parseDefaultString – Converts a default string into a SQL argument suitable to be loaded into the database.
  2. resultToSqlArg – Uses the DatabaseResults object to get the right SQL argument type out of the results.
  3. sqlArgToJava – Converts the SQL argument to the associated Java class.

Look at the other data types in com.j256.ormlite.field.types for other examples. When you have defined your persister class, you can use it with the persisterClass construct above or you can register it with the DataPersisterManager.registerPersisters(...) method. This will then automatically call your persister whenever a field with the associated class is configured.

 
DataPersisterManager.registerDataPersisters(
   MyTypePersister.getSingleton());

You probably would not want to register the MyDatePersister above because you would not want to change the persistence behavior for all Date types.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Gray Watson on December 16, 2013 using texi2html 1.82.