The Jena2 persistent storage subsystem implements an extension of the Model class that provides transparent persistence for models through the use of a database engine. Three database engines are currently supported, MySQL, Oracle, PostgreSQL and Microsoft SQL server, on both Linux and WindowsXP.
This document provides a brief overview of creating and accessing Jena2
persistent models. Users are now encouraged to use the factory mechanisms described
in model-factory.
Previous mechanisms based on directly calling ModelRDB
methods are
now deprecated.
The various options for configuring and accessing persistent models are described in Options. For details on installing and configuring the various database engines for use with Jena2, see the database engine-specific "how to" documents (HSQLDB Howto, MySQL HowTo, Derby HowTo, PostgreSQL HowTo, Oracle HowTo, Microsoft SQL Server HowTo).
In Jena2, all databases are multi-model and each model is, by default, stored in separate tables. Models may share database tables using the StoreWithModel option. Currently, model names may be any string however users are encouraged to use URIs as model names for compatibility with planned future Jena features. Note that the model name "DEFAULT" is reserved for use by Jena (as the name of the default model) and attempts to create such a named model will cause an exception.
As mentioned above, there are two mechanisms for creating persistent models, one using factory methods and another using constructors for the ModelRDB class. However, the factory methods do not return a ModelRDB instance. Consequently, certain methods defined on ModelRDB are not available for factory-created models, e.g., remove, setDoDuplicateCheck. If an application needs these methods, the ModelRDB constructors should be used. This is an interim measure until the factory-created models support all the ModelRDB capabilities. Below we review creating and opening models for each mechanism.
Creating or opening a model is a three-step process. First, the driver class must be loaded and a connection established to the database (note that in Jena2, the database type is specified as part of the database connection). Second, a model maker class is constructed. The model maker creates persistent instances of the Model class. Third, the model maker class is invoked to create new models or to open existing models. The following examples show how this is done.
new DBConnection(M_DB_URL, M_DB_USER, M_DB_PASSWD, M_DB);// database URL String M_DB_URL = "jdbc:mysql://localhost/test";// User nameString M_DB_USER = "test";// PasswordString M_DB_PASSWD = "";// Database engine nameString M_DB = "MySQL";// JDBC driverString M_DBDRIVER_CLASS = "com.mysql.jdbc.Driver";// load the the driver class Class.forName(M_DBDRIVER_CLASS);// create a database connection IDBConnection conn =
// create a model maker with the given connection parameters ModelMaker maker = ModelFactory.createModelRDBMaker(conn);
// create a default model Model defModel = maker.createDefaultModel();
...
// Open existing default model
Model defModel = maker.openModel();
// or create a named model Model nmModel = maker.createModel("MyNamedModel");
...
// or open a previously created named model Model prvModel = maker.openModel("AnExistingModel");
If using datbase-specific, low-level options (see "Options for Initialization and Access"), then the application may need to more directly use the ModelRDB interface.
Database-backed RDF models are instances of the class jena.db.ModelRDB
which supports the full jena.model.Model
interface and also
provides static methods to create, extend and reopen database instances.
ModelRDB supports several options (see "Options for Initialization and Access"). Some options alter the underlying database table structure and must be specified before the database is formatted. These methods are invoked on the underlying database driver instance for the connection. Ideally, the driver class need not be exposed to Jena applications. Consequently, use of the driver class to set these options should be considered an interim measure until the option setting can be integrated into the factory methods. See Enabling URI Compression for an example of setting these options. Other options apply to models. See Disable Duplicate Checking for an example of setting these types of options.
Creating an instance of ModelRDB is a two-step process. As with the factory methods, the first step is to load the driver class and establish a database connection. Second, the static methods on ModelRDB are used to create new ModelRDB instances or to open existing ones. The following examples show how this is done.
new DBConnection(M_DB_URL, M_DB_USER, M_DB_PASSWD, M_DB);// As before ...String M_DB_URL = "jdbc:mysql://localhost/test"; String M_DB_USER = "test"; String M_DB_PASSWD = ""; String M_DB = "MySQL"; String M_DBDRIVER_CLASS = "com.mysql.jdbc.Driver";// load the the driver class Class.forName(M_DBDRIVER_CLASS);// create a database connection IDBConnection conn =
// ---- Directly use ModelRDB
// create a default model ModelRDB defModel = ModelRDB.createModel(conn);
... // Open an existing model. ModelRDB defModel2 = ModelRDB.openModel(conn);
...
// create a named model ModelRDB nmModel = ModelRDB.createModel(conn,"MyModelName");
...
// open a named model ModelRDB nmModel2 = ModelRDB.openModel(conn,"ExistingModelName");
...
As an example of setting a database configuration option, the following shows how URI prefix compression is enabled. By default, URIs are stored fully expanded in the statement tables. Also shown is doubling the size of the prefix cache.
Class.forName(M_DBDRIVER_CLASS);
dbcon.getDriver().setDoCompressURI(true);
DBConnection dbcon = new DBConnection(M_DB_URL, M_DB_USER, M_DB_PASSWD, M_DB);
ModelRDB model = ModelRDB.createModel(dbcon, "myModelName");
int cacheSize = dbcon.getDriver().getCompressCacheSize();
// double the size of the prefix cache
dbcon.getDriver().setCompressCacheSize(cacheSize*2);
In Jena2, all databases are multi-model and each model is, by default, stored in
separate tables. Here is an example that checks to see if a specific named model exists and then creates or reopens it as necessary:
Class.forName(M_DBDRIVER_CLASS);
DBConnection dbcon = new DBConnection(M_DB_URL, M_DB_USER, M_DB_PASSWD, M_DB);
ModelRDB model;
if( !dbcon.containsModel("myModelName")
model = ModelRDB.createModel(dbcon, "myModelName");
else
model = ModelRDB.open(dbcon, "myModelName");
In this example, a configuration option is used to specify that a new model should share the tables of an existing model. Unlike the previous option, this option can be set after the database is formatted. It affects only subsequently created models.
Class.forName(M_DBDRIVER_CLASS);
DBConnection dbcon = new DBConnection(M_DB_URL, M_DB_USER, M_DB_PASSWD, M_DB);
ModelRDB model1, model2;
model1 = ModelRDB.createModel(dbcon, "myModel1"); // create a new model
dbcon.getDriver().setStoreWithModel("myModel1");
model2 = ModelRDB.createModel(dbcon, "myModel2"); // model2 is stored with model1
Some options apply to ModelRDB, e.g., query processing options. This example show how checking for duplicate statements can be disabled, as might be desirable when loading a large number of statements that the user is certain are duplicate-free.
Class.forName(M_DBDRIVER_CLASS);
DBConnection dbcon = new DBConnection(M_DB_URL, M_DB_USER, M_DB_PASSWD, M_DB);
ModelRDB model = ModelRDB.createModel(dbcon, "myModelName");
model.setDoDuplicateCheck(false); // disable duplicate checking