com.revusky.oreo.jdbc
Class JDBCBackedRecordSet
java.lang.Object
|
+--com.revusky.oreo.AbstractDataSource
|
+--com.revusky.oreo.AbstractMutableDataSource
|
+--com.revusky.oreo.jdbc.JDBCBackedRecordSet
- All Implemented Interfaces:
- DataListener, DataSource, java.util.EventListener, MutableDataSource, java.rmi.Remote
- public class JDBCBackedRecordSet
- extends AbstractMutableDataSource
- implements DataListener
A class that is essentially a facade in front of an external
relational database. This is just one of various
possible ways to implement this. This implementation allows for
an in-memory cache of adjustable size. This container
is probably fairly efficient for a web app whose profile is that
there are a lot of reads and relatively few writes to the
external RDBMS. That is probably more the rule than the exception.
There are 2 PROPERTY parameters that must be configured
in the XML:
- JDBC_DRIVER_CLASS
- JDBC_URL
These should be self-explanatory. They are needed so that this
class can talk to a database via JDBC. A tiny gotcha in terms of
configuring the JDBC_URL parameter is that the ampersand (&
)
must be written via the XML entity: &
There are several optional PROPERTY parameters as well:
- MAX_CACHE_SIZE
- CACHE_REFRESH_FREQUENCY
- DEFAULT_RECORD
- CREATE_TABLES_IF_NECESSARY
- DOUBLE_QUOTE_LITERAL
The first of the above properties determines how big an in-memory
record cache to maintain. The algorithm is pretty simplistic. The cache is simply
allowed to grow (no attempt is made to maintain most-recently-used info)
and when it goes beyond the maximum size, it gets wiped and starts
building up again. The second optional parameter indicates the frequency
with which to wipe the in-memory cache. (The default is never.)
This is specified in seconds. If you were to specify a value of 3600,
for example, this means, that the cache will never live beyond one hour.
What this would mean practically is that, if you did a bulk update
of the backing RDBMS externally, it would take a maximum of one
hour before the webapp reflected the new data. Of course, if you
wanted it to do so immediately, you could always have an administrative
function that called the wipeCache()
method
on the data source object.
The DEFAULT_RECORD property can be optionally specified
to indicate a default record type for this container. In particular,
if an instance of this class is homogeneous, i.e. only contains one
record type, then it may be nice to specify this, since it
frees you of the need to specify the type parameter in calls
to get() for example.
The CREATE_TABLES_IF_NECESSARY property takes a list
of record types for which to create tables if they do not already
exist in the underlying database. This is a good bootstrap feature,
though I should mention that this has not been tested
against a broad range of databases. Also, you must have
the right to create tables on the DB in question.
The DOUBLE_QUOTE_LITERAL property, if set to "Y", means that
you represent a literal quote character as '' as opposed to the default \'
- Author:
- Jonathan Revusky
Method Summary |
void |
delete(Record rec)
Delete a record |
Record |
get(java.lang.String type,
java.lang.Object key)
|
protected JDBCConnection |
getConnection()
|
void |
handleEvent(DataEvent event)
handle the event when the MutableDataSource we are listening
to has modified data |
void |
init(java.util.Properties props)
A method that initializes a DataSource with a set of
initialization properties. |
void |
insert(Record rec)
Adds a new record to the managed pool. |
java.util.List |
keys(java.lang.String type)
|
void |
playEvent(DataEvent event)
"play" an event
This will be mostly used in restarting an app
and reconstructing the state of the data from logs. |
java.util.List |
select(RecordFilter filter)
Fetches a list of records matching filter. |
protected java.lang.Object |
uniqueKey(Record rec)
|
void |
update(Record oldRec,
Record newRec)
Replaces an existing version of a record with a new updated version. |
void |
wipeCache()
If this data source is backed by some external mechanism,
like an RDBMS, wipes the in-memory cache, if one is being
maintained. |
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
JDBCBackedRecordSet
public JDBCBackedRecordSet()
throws java.io.IOException
handleEvent
public void handleEvent(DataEvent event)
throws java.io.IOException
- Description copied from interface:
DataListener
- handle the event when the MutableDataSource we are listening
to has modified data
- Specified by:
handleEvent
in interface DataListener
init
public void init(java.util.Properties props)
throws java.io.IOException
- Description copied from interface:
DataSource
- A method that initializes a DataSource with a set of
initialization properties. This is called internally
within Oreo and should not be called by application
code. As an implementor, you should make sure
that this method is only called once, for example,
throw a RuntimeException if an attempt is made to call this
on a DataSource a second time.
- Overrides:
init
in class AbstractDataSource
delete
public void delete(Record rec)
throws java.io.IOException
- Description copied from interface:
MutableDataSource
- Delete a record
- Following copied from interface:
com.revusky.oreo.MutableDataSource
- Parameters:
the
- record to delete.
insert
public void insert(Record rec)
throws java.io.IOException
- Description copied from interface:
MutableDataSource
- Adds a new record to the managed pool.
- Following copied from interface:
com.revusky.oreo.MutableDataSource
- Parameters:
rec
- the record to add- Throws:
DuplicateRecordException
- if another record already exists
with same primary key as 'rec'.java.io.IOException
- if the record cannot be
initialized (i.e. has missing fields or invalid
field values, etc.), or in case of a low-level error.
update
public void update(Record oldRec,
Record newRec)
throws java.io.IOException
- Description copied from interface:
MutableDataSource
- Replaces an existing version of a record with a new updated version.
Some implementations may use the oldRec parameter
to guarantee that there are no concurrency issues.
In such case, it would throw a ConcurrentModificationException
- Following copied from interface:
com.revusky.oreo.MutableDataSource
- Parameters:
oldRec
- the record to replace.newRec
- the new record.- Throws:
java.io.IOException
- thrown in case of any other database or
communication error.
keys
public java.util.List keys(java.lang.String type)
throws java.io.IOException
- Following copied from interface:
com.revusky.oreo.DataSource
- Parameters:
type
- the record type we are interested,
under some circumstances, this may be null.- Returns:
- a list of all valid lookup keys that correspond
to a given record type.
get
public Record get(java.lang.String type,
java.lang.Object key)
throws java.io.IOException
- Following copied from interface:
com.revusky.oreo.DataSource
- Parameters:
type
- the type of the record, if this is null,
then any type will do.key
- the lookup key- Returns:
- a Record of the given type, with
the given lookup key. If the data source allows multiple records,
only returns the first one found. Use getRecords() in that situation.
returns null if none is found.
wipeCache
public void wipeCache()
- Description copied from interface:
DataSource
- If this data source is backed by some external mechanism,
like an RDBMS, wipes the in-memory cache, if one is being
maintained. Otherwise, it does nothing.
- Overrides:
wipeCache
in class AbstractDataSource
select
public java.util.List select(RecordFilter filter)
throws java.io.IOException
- Description copied from interface:
MutableDataSource
- Fetches a list of records matching filter. If filter is null,
returns all the records in the container.
- Following copied from interface:
com.revusky.oreo.MutableDataSource
- Parameters:
filter
- the record filter, or null.- Returns:
- a List of all the records that are an instance of a
given class. If no records match the filter, an empty List.
playEvent
public void playEvent(DataEvent event)
throws java.io.IOException
- Description copied from interface:
MutableDataSource
- "play" an event
This will be mostly used in restarting an app
and reconstructing the state of the data from logs.
Note that data listeners are not notified.
getConnection
protected JDBCConnection getConnection()
uniqueKey
protected java.lang.Object uniqueKey(Record rec)
throws java.io.IOException