[ Team LiB ] |
8.4 In-Memory Versus Persistent Model StorageAll the examples to this point have used the memory model, but Jena also provides the capability to persist data to relational database storage. The databases supported are MySQL, PostgreSQL, Interbase, and Oracle. Within each database system, Jena also supports differing storage layouts:
The first step of storing a model in a database is to create the structure to store the data. The tables must be created in an already existing database, which has been formatted and had tables added. This code needs to be run once. After the database structure is created, it can then be opened directly in another application or used within the same application. In Example 8-12, I'm storing two models in the database using a different name for each. In addition, I'm also creating the JDBC connection directly rather than having DBConnection create it for me. The model used is based on a MySQL database, using the MMGeneric layout. I'm not using the slightly more efficient hash method (MMHash), primarily because the generic layout is the better one to take if you're thinking of accessing the data directly through JDBC rather than through Jena. Once the database is formatted, two RDF/XML documents are opened and stored in two separate models within the database. Example 8-12. Persisting two RDF/XML models to a MySQL databaseimport com.hp.hpl.mesa.rdf.jena.model.*; import com.hp.hpl.mesa.rdf.jena.rdb.ModelRDB; import com.hp.hpl.mesa.rdf.jena.rdb.DBConnection; import java.sql.*; public class pracRDFEighth extends Object { public static void main (String args[]) { // Pass two RDF documents, connection string, String sUri = args[0]; String sUri2 = args[1]; String sConn = args[2]; String sUser = args[3]; String sPass = args[4]; try { // Load driver class Class.forName("com.mysql.jdbc.Driver").newInstance( ); // Establish connection - replace with your own conn info Connection con = DriverManager.getConnection(sConn, "user", "pass"); DBConnection dbcon = new DBConnection(con); // Format database ModelRDB.create(dbcon, "MMGeneric", "Mysql"); // Create and read first model ModelRDB model1 = ModelRDB.createModel(dbcon, "one"); model1.read(sUri); // Create and read second model ModelRDB model2 = ModelRDB.createModel(dbcon, "two"); model2.read(sUri2); } catch (Exception e) { System.out.println("Failed: " + e); } } } The application expects the following command line: java pracRDFEighth firstrdffile secondrdffile connect_string username password You'll need to adjust the database connection string, username, and password to fit your environment. In the example, instead of reading the two models into separate databases, I could also have read them into the same database. Once the model data is persisted, any number of applications can then access it. In Example 8-13, I'm accessing both models, dumping all of the objects in the first and writing out triples from the second. Example 8-13. Accessing RDF models stored in MySQL databaseimport com.hp.hpl.mesa.rdf.jena.model.*; import com.hp.hpl.mesa.rdf.jena.rdb.ModelRDB; import com.hp.hpl.mesa.rdf.jena.rdb.DBConnection; import java.sql.*; public class pracRDFNinth extends Object { public static void main (String args[]) { String sConn = args[0]; String sUser = args[1]; String sPass = args[2]; try { // load driver class Class.forName("com.mysql.jdbc.Driver").newInstance( ); // Establish connection - replace with your own conn info Connection con = DriverManager.getConnection(sConn, sUser, sPass); DBConnection dbcon = new DBConnection(con); // Open two existing models ModelRDB model1 = ModelRDB.open(dbcon, "one"); ModelRDB model2 = ModelRDB.open(dbcon, "two"); // Print out objects in first model using toString NodeIterator iter = model1.listObjects( ); while (iter.hasNext( )) { System.out.println(" " + iter.next( ).toString( )); } // Print out triples in second model - find resource Resource res = model2.getResource("http://burningbird.net/articles/monsters1.htm"); // Find properties StmtIterator sIter = res.listProperties( ); // Print out triple - subject | property | object while (sIter.hasNext( )) { // Next statement in queue com.hp.hpl.mesa.rdf.jena.model.Statement stmt = sIter.next( ); // Get subject, print Resource res2 = stmt.getSubject( ); System.out.print(res2.getNameSpace( ) + res2.getLocalName( )); // Get predicate, print Property prop = stmt.getPredicate( ); System.out.print(" " + prop.getNameSpace( ) + prop.getLocalName( )); // Get object, print RDFNode node = stmt.getObject( ); System.out.println(" " + node.toString( ) + "\n"); } } catch (Exception e) { System.out.println("Failed: " + e); } } } Jena uses a highly normalized data model for the RDF statements. In addition to accessing the data through the Jena API, you can also access it directly using whatever database connectivity you prefer. However, I recommend that you access the data for read-only purposes and leave updates to the Jena API. |
[ Team LiB ] |