Plain Old SQL Statements - examples
Pre-requisities and imports
We use the Jacarta commons lang library (commons-lang-2.1.jar), you can
get that at http://jakarta.apache.org/site/downloads/downloads_commons-lang.cgi
.
Setting up the connection
We simply create a POSS connection from a JDBC connection:
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection myConnection = DriverManager.getConnection("jdbc:mysql://"
+
hostPort + "/mysql?user=" + user + "&password=" + password);
PSconnection psConn = new PSconnection(myConnection);
Working directly from the connection
You can do most things directly from the connection. As long as
you use bind variables (as appropriate) the SQL will be automatically
cached, so there's no particular performance disadvantage to doing
things this way;
psConn.doSql("DROP TABLE IF EXISTS test1");
psConn.doSql("CREATE TABLE test1 (num INT,name VARCHAR(30))");
psConn.doSql("INSERT INTO test1 VALUES (1,'one'),(2,'two') ");
psConn.commit();
// fetch all the rows
System.out.println(psConn.fetchAll("SELECT * FROM test1"));
// Output: [[1, one], [2, two]]
// fetch with a bind variable into result set
RowSet rs = psConn.fetchAll("SELECT * FROM test1 WHERE num>?", 0);
System.out.println(rs.getRows());
Creating SQL statements
Creating a SQL object usually leads to better code and has more options
for dealing with the result set. You can bind variables either
directly using a bindArgs method, or in the execute or fetchAll
methods. RowSet and Row objects are all printable. A RowSet
acts like an ArrayList of HashMaps. The HashMap is keyed by
column name but you can retrieve by column number if you like:
PlainSql mySql = psConn
.createSql("SELECT * FROM test1 WHERE num=? AND
name=?");
mySql.bindArgs(1, "one");
mySql.execute();
while (mySql.nextRow()) {
Row r = mySql.fetchOne();
System.out.println("num=" + r.get("num")); // access column by name
System.out.println("value=" + r.get("value")); // access column by
// number
}
// The quick way (but you need enough memory to get all the rows)
RowSet rs = mySql.fetchAll(1, "one");
for (Row row : rs.getRows()) {
System.out.println(row);
}
The cache
PlainSql statements are prespared statement objects that are kept open
as long as the PlainSql object is open. When closed, they are
kept in a LRU cache in case you request a prepare on the same SQL text.
Obviously, using bind variables is neccessary to keep the cache
efficient.
There is one cache per connection. It's 30 statements big by
default, and statements are inserted at postition 20. This stops
one-off SQLs from pushing repeatable SQLs out.
I need to add some methods to let you configure the cache.
Table objects and array inserts
A table object is like a Plain SQL that is based on a SELECT * FROM table. You can select from the table, and there are methods to limit the rows returned.
But the main thiing is that there is an array insert interface, as shown below:
PlainTable test1 = psConn.createTable("test1");
// A RowSet matching the table
RowSet test1Rows = test1.emptyRowSet();
// Create a row and add it to the rowset
// Add some rows
for (int i = 3; i < 10; i++) {
test1Rows.addRow("num", i, "name", "row " + i);
}
//Add the rows as a batch
test1.insertArray(test1Rows);
psConn.commit();
test1Rows.clear(); // in case we want to do it again
System.out.println(psConn.fetchAll("SELECT * FROM test1").toString());
Other stuff
The PSsequence class is an efficient portable sequence number generator.
PlainTableDLL provides some convenient ways of creating tables. Its a work in progress.
PlainProc is a stored procedure object but it also is a work in progress.