BuzzSQL User's Guide
 Limitation of Liability
This publication and the software it describes are provided "as is" without warranty of any kind, express or implied, including, but not limited to, the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.
 Contents
1. Introduction
1.1 What BuzzSQL Is
1.2 What BuzzSQL Isn't
1.3 Objectives
1.4 Target Audience
1.5 Architecture
2. Compatibility
2.1 Java Version
2.2 Operating Systems
2.3 Databases
3. Installation
3.1 Dependencies
3.2 Included JARs
3.3 Configuration Files
3.3.1 BuzzSQL Properties (buzzsql.properties)
3.3.2 Database Connection Configuration (buzzsql-datasources.xml)
3.4 BuzzSQL Logging
3.4.1 DEBUG Level
3.4.2 INFO Level
3.4.3 WARN Level
3.4.4 ERROR Level
3.4.5 FATAL Level
3.5 3rd Party Library Logging
4. Usage
4.1 Constructors
4.2 SQL and Arguments
4.3 Execution
4.4 Closing the Object
4.5 SQL Objects
4.5.1 Select (com.buzzsurf.sql.Select)
4.5.2 Update (com.buzzsurf.sql.Update)
4.5.3 Insert (com.buzzsurf.sql.Insert)
4.5.4 Delete (com.buzzsurf.sql.Delete)
4.5.5 Stored Procedure (com.buzzsurf.sql.StoredProcedure)
4.5.5.1 OutParameter (com.buzzsurf.sql.OutParameter)
4.5.5.2 InOutParameter (com.buzzsurf.sql.InOutParameter)
5. Connecting to the Database
5.1 DataSource Manager (com.buzzsurf.sql.DataSourceManager)
5.1.1 Modes of Operation
5.1.1.1 J2EE - Application Server Mode
5.1.1.2 J2SE - Stand-alone Mode
5.1.2 Initialization
5.1.3 DataSource Naming
5.2 Connection Pooling
6. Miscellaneous Topics
6.1 Explicit Connections
6.2 Transactions
6.3 Method Chaining
6.4 Thread Safety
6.5 Release Information (com.buzzsurf.sql.ReleaseInfo)
7. JavaDoc - API Documentation
8. Contacting the Author
9. License
10. Change Log
  1. Introduction
Welcome to the BuzzSQL User's Guide. This guide explains the basics about what BuzzSQL is, how to program with it, and how to configure it. This guide assumes you are familiar Java development.
  1.1 What BuzzSQL Is
BuzzSQL is a simple to use Java API for accessing a relational database. It functions as a thin layer over Java JDBC by providing straight forward wrapper classes for the more complex underlying JDBC calls. It further simplifies JDBC by providing automatic setup of database connection pooling, configuration, logging, and statement handling.

BuzzSQL lends itself extremely well to smaller, non-enterprise level, stand-alone applications where only a few quick database queries or updates are needed.
  1.2 What BuzzSQL Isn't
BuzzSQL is NOT an object-relational mapping library (ORM). It does not examine your database structure or generate classes. BuzzSQL does not write SQL for you; you must understand SQL syntax and know how to write queries for your target database platform.
  1.3 Objectives
The objective of BuzzSQL is to achieve a middle ground between using straight JDBC connections for database access, and more complex object-relational mapping libraries such as Hibernate, Torque, or Cayenne.

BuzzSQL was written to fill a need the author saw for a Java database access library that is less complex and cumbersome than most ORM libraries, but simplifies JDBC statement handling and provides automatic connection pooling and configuration using properties files. It is designed to work well in both J2EE application servers and stand-alone J2SE applications.
  1.4 Target Audience
The target audience is beginner to advanced level Java developers that are looking for a quick and efficient database access layer without the overhead and headaches of an ORM tool. BuzzSQL probably isn't for you if you're looking for database reverse engineering, SQL script generation, strictly object-oriented data objects, high performance caching, or lots of XML configuration files.
  1.5 Architecture
The object structure of BuzzSQL is clean and straight forward, making the library easy to learn and use by novice Java developers. Most objects are modeled according to standard SQL statement names; Select for Select, Insert for Insert, Update for Update, etc.

BuzzSQL is a thin layer on top of JDBC, and therefore provides access to all the underlying JDBC objects. You can use as little or as much of it as you need. Connections to the database are always obtained through a JNDI naming context. As a result, it integrates almost seamlessly with J2EE application servers. In fact, in most application server environments no additional configuration files are needed. When a naming context is not available as is common in a stand-alone J2SE application, BuzzSQL creates one automatically and loads it with DataSources according to your configuration file.
  2. Compatibility
 
  2.1 Java Version
J2SE 5.0 or later is required. BuzzSQL does NOT function on Java 1.4 or earlier, as it depends on language enhancement in Java 5 such as autoboxing, variable arguments, and generics.

BuzzSQL will work equally well using the Java JRE or JDK.

Note: Java 5.0 is the same as Java 1.5. JDK is the same as SDK. J2EE is NOT the same as J2SE; BuzzSQL does not require J2EE.

BuzzSQL was developed using Eclipse, and as such it may be more convenient to use Eclipse while viewing the source release, but Eclipse certainly isn't required.
  2.2 Operating Systems
BuzzSQL is a pure Java library and does not rely on any JNI native calls. It should function correctly on any operating system that supports the Java 1.5 JRE or higher.
  2.3 Databases
BuzzSQL was not written for any specific database system, although it has been extensively testing on MySQL and Oracle. It functions through JDBC, and does not rely on any unusual calls or direct database access. Therefore it should be compatible with any database that has a reliable JDBC driver.

Since BuzzSQL does not write SQL for you, it does not need to be told what type of database you are using. All inherent differences between various RDBMS systems are taken care of by the JDBC driver and your own SQL statements. However, it is sometimes useful to know what type of database you are accessing. This can be accomplished by querying java.sql.DatabaseMetaData as shown in the following code fragment.
Connection tempConn = DataSourceManager.getConnection();
String databaseType = tempConn.getMetaData().getDatabaseProductName();
DataSourceManager.releaseConnection(tempConn);
  3. Installation
Installation of BuzzSQL is as simple as dropping the appropriate JAR files and optional configuration files in your classpath or the appropriate WEB-INF directory. However, which 3rd party libraries you need depends on your particular setup. These details are explained in the following sections.
  3.1 Dependencies
BuzzSQL's dependency on 3rd party libraries varies depending on your environment; i.e stand-alone or an application server. It also depends on what database connection pool you prefer to use.

In a common J2SE stand-alone application using the default connection pool, BuzzSQL requires the following libraries;
  • Jakarta commons-logging (requires...)
    • Log4j (If using Log4j for logging)
  • Shiftone OOC JNDI Context (requires...)
    • Shiftone Arbor XML Unmarshaller
    • c3p0 database connection pool
In a J2EE application server environment, with an existing JNDI naming context, the only requirement is the Jakarta commons-logging library.

Websites for downloading dependencies;
BuzzSQL was tested with the following versions of these libraries, although earlier versions may work equally well;
  • commons-logging 1.1 - Required by BuzzSQL
  • Log4j 1.2.14 - Required if using Log4J for logging
  • Shiftone OOC 1.2 - Required if no JNDI naming context (J2SE environment)
  • Shiftone Arbor 1.4 - Required by Shiftone OOC
  • c3p0 0.9.1.2 - Required by Shiftone OOC if using c3p0 as the database connection pool
  • MySQL Connector/J 5.0.6 - Required by c3p0 if using MySQL
  • Oracle Thin Driver ojdbc14 - Required by c3p0 if using Oracle
  3.2 Included JARs
BuzzSQL comes packaged with all the required 3rd party libraries mentioned above.In a stand-alone J2SE environment you will likely need to include all the provided jars in the classpath. In a J2EE application server environment, most likely only the buzzsql jar will be needed.
  • buzzsql-<version>.jar - The BuzzSQL classes
  • commons-logging-1.1.jar - Jakarta commons-logging: Wrapper around a variety of logging APIs. Required by BuzzSQL and other libraries.
  • log4j-1.2.14.jar - Log4j: Elegant logging system. Required by commons-logging if you are using Log4j as your logging system.
  • shiftone-oocjndi.jar - Shiftone OOC: An in-memory JNDI service provider. Required by BuzzSQL if no JNDI naming context already exists, such as in a stand-alone J2SE application.
  • shiftone-arbor.jar - Shiftone Arbor XML Unmarshaller: A library for reading XML files. Required by Shiftone OOC to load the XML resource configuration.
  • c3p0-0.9.1.2.jar - c3p0: JDBC connection and statement pooling. Required by Shiftone OOC for database connection pooling if you are using c3p0 as your pool.
  3.3 Configuration Files
BuzzSQL uses at most 2 configuration files as described below. Both configuration files are optional, depending on your environment.
  3.3 BuzzSQL Properties (buzzsql.properties)
This is an optional configuration file that allows you to change defaults of the core BuzzSQL library. Most likely you will only need to provide this file if you are connecting to more than one database at the same time, or if you are using a J2EE application server that does not bind it's JDBC resources under the JNDI context java:comp/env/jdbc/.

This file is loaded as a system resource and therefore can be placed anywhere in your classpath. In a J2EE application server environment the appropriate location is the WEB-INF/classes directory of your web application.

buzzsql.properties may contain the following 3 configuration parameters;

  • rootNamespace
    • The root JNDI namespace to search for DataSources.
    • The stand-alone J2SE naming context will bind DataSources here, so you only need to specify this property if your J2EE application server binds the DataSource resources at a location different than the default.
    • Default: java:comp/env/jdbc
  • dataSourceNames
    • Specific name(s) of DataSources for the library to use.
    • BuzzSQL normally performs an automatic DataSource discovery process by searching the full JNDI path under your rootNamespace for DataSource objects. If you specify this property, the search process will NOT occur and BuzzSQL will ONLY lookup the names listed here. All names are relative to the rootNamespace property.
    • You may list multiple DataSource names separated by commas.
    • Default: none
  • defaultDataSourceName
    • The default dataSourceName to use when there are multiple DataSources available.
    • If you are using more than one DataSource, you must either provide the dataSourceName in your code to specify which DataSource you are referring to, or define this property.
    • If you define the dataSourceNames parameter but not this parameter also, the default will be the first DataSource listed. In any other case of multiple DataSources, the default is non-deterministic.
    • Default: none
  3.3.2 Database Connection Configuration (buzzsql-datasources.xml)
This file is used to setup an in-memory JNDI naming context to hold your database connections in a stand-alone J2SE application environment. It is somewhat similar to a typical resource configuration for most J2EE application servers.

This file is usually not needed in a J2EE application server environment. J2EE application servers will setup the JNDI naming context using on their own configuration files, so there is no need for this stand-alone configuration file.

This file is loaded as a system resource and therefore can be placed anywhere in your classpath.

Shiftone OOC provides a DataSource Factory implementation specifically for the c3p0 connection pool. Any pool that provides an implementation of a javax.naming.spi.ObjectFactory should be usable.

An example buzzsql-datasources.xml follows:
<initial-context>
 <context name="java:comp">
  <context name="env">
   <context name="jdbc">
    <reference name="mysql" classname="javax.sql.DataSource" 
     factoryclassname="org.shiftone.ooc.factory.PooledDataSourceObjectFactory">
     <refaddr name="driver" value="com.mysql.jdbc.Driver">
     <refaddr name="url" value="jdbc:mysql://localhost:3306/example1">
     <refaddr name="user" value="root">
     <refaddr name="password" value="mysql">
     <refaddr name="c3p0.initialPoolSize" value="1">
     <refaddr name="c3p0.minPoolSize" value="1">
     <refaddr name="c3p0.acquireIncrement" value="1">
     <refaddr name="c3p0.acquireRetryAttempts" value="1">
    </reference>
   </context>
  </context>
 </context>
</initial-context>
  3.4 BuzzSQL Logging
All BuzzSQL logs are written using the Jakarta commons-logging package. However, since BuzzSQL is a "low-level" library, it generates relatively little log output to any level other than DEBUG.
  3.4.1 DEBUG Level
DataSource Manager will output detailed information on the initialization of DataSources.

All SQL statements will be merged with their arguments and output in their raw format BEFORE the query is executed. Note; you should NOT use DEBUG level if you are writing any sensitive data to the database using BuzzSQL, as it will be written to the logs.
  3.4.2 INFO Level
No output is written at the INFO log level.
  3.4.3 WARN Level
DataSource Manager will generate warnings if it encounters any non-critical problems during initialization such as;
  • Non-existent DataSources named by dataSourceName properties in buzzsql.properties.
  • A non-existent DataSource named by defaultDataSourceName property in buzzsql.properties.
  • Multiple DataSources loaded without a defaultDataSourceName property set.
  • No DataSources found.
  • A NULL DataSource bound to a JDNI name; usually indicating failed JDBC driver initialization.
  3.4.4 ERROR Level
DataSource Manager will generate errors if it encounters any critical problems during initialization such as;
  • Failure to load any JNDI initial naming context.
  • Failure to lookup the JNDI root namespace.
  3.4.5 FATAL Level
DataSource Manager outputs a FATAL log if it fails to initialize due to any of the ERROR conditions listed above, or if it catches any unexpected error during initialization.

You can query the initialization state of DataSource Manager by calling DataSouceManager.initializationFailed(). initializationFailed will return true if a FATAL error was detected.
  3.5 3rd Party Library Logging
Shiftone OOC, Arbor, and c3p0 are relatively verbose in terms of log output compared to BuzzSQL.
  • OOC and Arbor will write extensive logs to DEBUG level while processing the buzzsql-datasources.xml file.
  • OOC will write JDNI context setup information to the INFO level during initialization.
  • c3p0 will write extensive information to the DEBUG level during connection setup, and more terse status information to the INFO level.
A sensible log4j.properties file is included as an example with BuzzSQL that will "tone down" the logging in these 3rd party libraries.
  4. Usage
 
  4.1 Constructors
Four different constructors are provided for each object to handle the different cases of how a connection to the database is obtained. See Connecting to the Database for more information on obtaining a connection to the database explicitly or automatically.
  • A zero argument constructor is provided for simplified operation with JavBeans, SOAP, and reflection scenarios where having such a constructor is necessary or convenient. At a minimum, you must call setSQL(String) before execution when using this constructor.
  • A single argument constructor that accepts your SQL statement and uses the default DataSource.
  • A dual argument constructor that accepts your SQL statement and the explicit name of a DataSource to use.
  • A dual argument constructor that accepts your SQL statement and a java.sql.Connection object. This constructor provides a great deal of flexibility by allowing the use of "explicit" connections that are supplied by the user rather than being obtained automatically by BuzzSQL. Using a explicit connection also allows BuzzSQL to support database transactions.
  4.2 SQL and Arguments
All BuzzSQL objects use an internal java.sql.PreparedStatement object that expects argument placeholders in the SQL as question marks (?). The SQL statement can be passed in via constructor or using the setSQL(String) method.

Arguments are set using the setArgs(Object...) or addArgs(Object...) methods, which are Java 5 variable arguments methods. Therefore you can call setArgs(Object...) and pass any type of object or primitive in any combination. The order of your arguments must only match the order of your question marks in the SQL statement. The difference between setArgs and addArgs is that setArgs will first clear an previously set values.

BuzzSQL does not handle quoting or escaping of any arguments; the decision to quote or not to quote is left up the JDBC driver. Therefore it is important to pass your arguments in setArgs(Object...) as the appropriate native Java type.

For example;
  • byte, short, int, long if the database type is numeric
  • float, double if the database type is numeric with precision
  • String, char if the database type is varchar based
  • java.util.Date, java.util.Calendar if the database type is a date/time based
  • com.buzzsurf.sql.OutParameter, com.buzzsurf.sql.InOutParameter if the database type is a stored procedure OUT or INOUT parameter. See Stored Procedure for more information.
  4.3 Execution
During execution a database connection is obtained (if needed), SQL and arguments are merged, and the PreparedStatement is executed against the database. execute() throws an exception if any of these steps fails for any reason.

Typical post-execution steps are slightly different depending on the object subtype. Select based objects will obtain a ResultSet and ResultSetMetaData, while Update based objects will query and save the updated row count to a local variable.

execute() returns a reference to the current object to support method chaining. See Method Chaining for more information. You can assume execution succeeded if no exception is thrown.
  4.4 Closing the Object
It is import to call close() after you have finished using any BuzzSQL object. close() will release any resources including the database connection if appropriate. It will never throw an exception, so it is always safe to call close().

You may reuse a SQL object after calling close().

The best practice to insure all BuzzSQL objects are closed is to put your call to close() in a finally block, as demonstrated in the following code fragment;
Update myUpdate = null;
try
{
 myUpdate = new Update(sql);
 myUpdate.setArgs(args);
 myUpdate.execute();
}
catch(Exception e)
{
 // handle the exception
}
finally
{
 if(myUpdate != null)
  myUpdate.close()
}
  4.5 SQL Objects
Every SQL object in BuzzSQL extends from the base class com.buzzsurf.sql.BuzzSQL, and therefore all operate in a very similar way as described below.
  4.5.1 Select (com.buzzsurf.sql.Select)
A Select object queries a database and can be iterated through to read results. It is a combination of the underlying JDBC classes;
  • java.sql.Connection
  • java.sql.PreparedStatement
  • java.sql.ResultSet
  • java.sql.ResultSetMetaData
After execution, you may iterate through the Select object using next(), and retrieve your results in any format using one of the variety of get methods. You must call next() at least once before any get call to set the index in the result set to the first result.

As an example, the following code fragment creates a Select object using the automatic default connection to the database. The SQL statement is passed via constructor, and the arguments are passed using the setArgs(Object...) method. execute() is called to execute the database call, and then results are iterated through using next(). The object is then closed to cleanup any resources and return the connection to the pool.
Select select = new Select();
select.setSQL("select col_pk, col_str, col_int from example.table_example1");
select.execute();
while (select.next())
 System.out.println(select.getLine());
select.close();
Note: This code does not handle exceptions. You normally should wrap your calls in try/catch/finally blocks to handle any problems. It is advisable to put your close() call in a finally block to insure the connection is always released.
  4.5.2 Update (com.buzzsurf.sql.Update)
An Update object modifies rows in a database and queries the number of rows updated. It is a combination of the underlying JDBC classes;
  • java.sql.Connection
  • java.sql.PreparedStatement
After execution, you may get the number of rows updated by calling getUpdateCount() or getRowCount().

As an example, the following code fragment creates an Update object using the automatic default connection to the database. The SQL statement is passed via constructor, and the arguments are passed using the setArgs(Object...) method. execute() is called to execute the database call, and then the update count is queries by calling getUpdateCount(). The object is then closed to cleanup any resources and return the connection to the pool.
Update update = new Update();
update.setSQL("update example.table_example1 set col_str = ? where col_pk = ?");
update.setArgs("asdf",1);
update.execute();
int updateCount = update.getUpdateCount();
update.close();
Note: This code does not handle exceptions. You normally should wrap your calls in try/catch/finally blocks to handle any problems. It is advisable to put your close() call in a finally block to insure the connection is always released.
  4.5.3 Insert (com.buzzsurf.sql.Insert)
An Insert object inserts new rows to a table and queries the number of rows inserted. It is a combination of the underlying JDBC classes;
  • java.sql.Connection
  • java.sql.PreparedStatement
After execution, you may get the number of rows inserted by calling getInsertCount() or getRowCount().

If the database table contains an auto increment column, the value can be retrieved using getGeneratedKey(). This method allows the retrieval of only the first auto increment column in the table, and only as an int. BuzzSQL always allows access to the underlying base JDBC object if you need more control, such as to retrieve other auto increment column values.

com.buzzsurf.sql.Insert extends com.buzzsurf.sql.Update, but add only minor functionality beyond that which is contained in the parent class; getGeneratedKey() being the primary addition. Therefore you may choose to use com.buzzsurf.sql.Update to perform inserts if it helps to streamline your object structure.

As an example, the following code fragment creates an Insert object using the automatic default connection to the database. The SQL statement is passed via constructor, and the arguments are passed using the setArgs(Object...) method. execute() is called to execute the database call, and then the primary key column value is retrieved using getGeneratedKey(). The object is then closed to cleanup any resources and return the connection to the pool.
Insert insert = new Insert("insert into example.table_example1(col_str, col_int) values (?,?)")
insert.setArgs("asdf", 123);
insert.execute();
int pk = insert.getGeneratedKey();
System.out.println(pk);
insert.close();
Note: This code does not handle exceptions. You normally should wrap your calls in try/catch/finally blocks to handle any problems. It is advisable to put your close() call in a finally block to insure the connection is always released.
  4.5.4 Delete (com.buzzsurf.sql.Delete)
An Delete object deletes rows from a database table and queries the number of rows deleted. It is a combination of the underlying JDBC classes;
  • java.sql.Connection
  • java.sql.PreparedStatement
After execution, you may get the number of rows deleted by calling getDeleteCount() or getRowCount().

com.buzzsurf.sql.Delete extends com.buzzsurf.sql.Update, but add only minor functionality beyond that which is contained in the parent class. Therefore you may choose to use com.buzzsurf.sql.Update to perform deletes if it helps to streamline your object structure.

As an example, the following code fragment creates an Delete object using the automatic default connection to the database. The SQL statement is passed via constructor, and the arguments are passed using the setArgs(Object...) method. execute() is called to execute the database call, and then the delete count is queries by calling getDeleteCount(). The object is then closed to cleanup any resources and return the connection to the pool.
Delete delete = new Delete();
delete.setSQL("delete from example.table_example1 where col_int = ?");
delete.setArgs(123);
delete.execute();
int deleteCount = update.getDeleteCount();
delete.close();
Note: This code does not handle exceptions. You normally should wrap your calls in try/catch/finally blocks to handle any problems. It is advisable to put your close() call in a finally block to insure the connection is always released.
  4.5.5 Stored Procedure (com.buzzsurf.sql.StoredProcedure)
A StoredProcedure object executes a stored program in a relational database. A StoredProcedure is similar to a Select object, as it can have a result set. It is also similar to an Update object, as it can have an update count. It is a combination of the underlying JDBC classes;
  • java.sql.Connection
  • java.sql.PreparedStatement
  • java.sql.ResultSet
  • java.sql.ResultSetMetaData
After execution, you may call hasResultSet() to find out of the StoredProcedure produced a result set. If it has a result set, you may iterate through the StoredProcedure object using next(), and retrieve your results in any format using one of the variety of get methods. You must call next() at least once before any get call to set the index in the result set to the first result. You may also get the number of rows updated by calling getUpdateCount() or getRowCount().

Some databases allow a stored procedure to return results in the form of OUT or INOUT parameters. BuzzSQL supports this through the use of the com.buzzsurf.sql.OutParameter and com.buzzsurf.sql.InOutParameter objects. For more detailed information see the sections on OutParameter and InOutParameter objects.

As an example, the following code fragment creates a StoredProcedure object using the automatic default connection to the database. The SQL statement is passed via constructor, and the arguments are passed using the setArgs(Object...) method. This example makes use of an OutParameter and an InOutParameter to demonstrate the usage of these classes. OUT and INOUT parameters are used only in conjunction with stored procedures. execute() is called to execute the database call, and then results are iterated through using next(). The object is then closed to cleanup any resources and return the connection to the pool.
OutParameter outParam = new OutParameter(java.sql.Types.VARCHAR);
InOutParameter inOutParam = new InOutParameter(java.sql.Types.INTEGER, 10);
StoredProcedure storedProc = new StoredProcedure("call test.storedproc_test(?, ?, ?)");
storedProc.setArgs("asdf", outParam, inOutParam);
storedProc.execute();
if (storedProc.hasResultSet())
{
 while (storedProc.next())
  System.out.println(storedProc.getLine());
}
System.out.println(outParam.getString());
System.out.println(inOutParam.getInt());
storedProc.close();
Note: This code does not handle exceptions. You normally should wrap your calls in try/catch/finally blocks to handle any problems. It is advisable to put your close() call in a finally block to insure the connection is always released.
  4.5.5.1 OutParameter (com.buzzsurf.sql.OutParameter)
OutParameter is a wrapper object used in conjunction with a StoredProcedure object to allow the return of a value from a stored procedure. OutParamer acts like a place holder in your SQL statement. You should create an OutParameter object, and then bind it to the StoredProcedure at the appropriate ? place holder like any other bind variable.

Since OutParameter is a wrapper around another object type, you are required to tell BuzzSQL what type of object it is wrapping. This is done in the constructor by passing an int value representing a SQL type as defined in java.sql.Types class. A partial list containing the most commonly used values follows;
  • java.sql.Types.DATE
  • java.sql.Types.INTEGER
  • java.sql.Types.DECIMAL
  • java.sql.Types.VARCHAR
Prior to execution, the OutParameter is an empty wrapper; the internal value is null. However, during execution of a StoredProcedure, BuzzSQL will look for any bound OutParameter objects and populate their value.

After execution, the value returned from the StoredProcedure can be retrieved in any format using one of the variety of get methods, similar to getting values from a Select object. You should take care however to retrieve the value as the same java.sql.Types value you specified for the object. For example, getInt() for a java.sql.Types.INTEGER or getString() for a java.sql.Types.VARCHAR.

See Stored Procedure for example code.
  4.5.5.2 InOutParameter (com.buzzsurf.sql.InOutParameter)
InOutParameter is a wrapper object used in conjunction with a StoredProcedure object to allow the a value to be passed to a stored procedure, and to allow the return of a value from the stored procedure.

InOutParameter extends OutParameter, and therefore inherits all it's methods. It function the same way with regard to returning a value from a StoreProcedure. However InOutParameter also allows you to pass a value to the stored procedure.

During execution, BuzzSQL will bind your "in" value to the SQL statement. After execution, it will retrieve the out value. See OutParameter more information regarding retrieving values from an OutParameter object.
  5. Connecting to the Database
BuzzSQL is particularly flexible in regards to connecting to a database. Specifically, BuzzSQL has the ability to obtain a connection in a stand-alone J2SE environment, in an J2EE application server environment, or to operate using a user supplied connection. The first 2 cases are related to DataSource Manager, as discussed below. The later is referred to as a "explicit" connection, and explained in detail below.
  5.1 DataSource Manager (com.buzzsurf.sql.DataSourceManager)
DataSource Manager handles loading javax.sql.DataSource objects from a JNDI naming context. This is done intelligently by examining any existing naming context. All database connections obtained automatically by BuzzSQL come from DataSource bound in a JNDI naming context

Note: DataSource Manager does not need to be used exclusively with BuzzSQL objects. It can be a valuable stand-alone tool for obtaining database connections. This is particularly true in a J2SE environment where no JNDI naming context is available. DataSource Manager will create a naming context for you and load and bind your dataSources conveniently.
  5.1.1 Modes of Operation
DataSource Manager can operate in 2 modes; "J2EE" or "J2SE".
  5.1.1.1 J2EE - Application Server Mode
In J2EE mode, a JNDI naming context already exists. This is usually the case when your application is running in a J2EE Application Server or Servlet Container. In J2EE mode, DataSource Manager expects that your database connections have already been configured by your J2EE application server and bound in the naming context. No BuzzSQL specific configuration files are required to use BuzzSQL in J2EE mode. DataSource Manager will examine your JNDI naming context looking for dataSources and make them available for use in BuzzSQL.
  5.1.1.2 J2SE - Stand-alone Mode
In J2SE mode, no JNDI naming context exists. This is normally the case when you are running a stand-alone Java application outside of a J2EE Application Server or Servlet Container. In J2SE mode, DataSource Manager will load it's own JNDI naming context and create and bind dataSources as configured in your buzzsql-datasources.xml file. In J2SE mode, buzzsql-datasources.xml is the only required configuration file. See Database Connection Configuration for more information on configuring your JNDI naming context and dataSource connection properties via buzzsql-datasources.xml.
  5.1.2 Initialization
DataSource Manager goes through an intelligent discovery process to search for and load dataSources bound in the JNDI naming context. The default root namespace it expects dataSources to be bound in is java:comp/env/jdbc/. You can change this path and a number of other configuration properties by including buzzsql.properties in the classpath.

In either mode, DataSource Manager will load the optional configuration file buzzsql.properties during initialization if it exists in the classpath. buzzsql.properties is not required unless you need to change some default behavior regarding dataSource lookups. See BuzzSQL Properties for more information on the parameters you may set using buzzsql.properties.

Note: DataSource Manager uses "lazy initialization" to create/lookup/load dataSource from the JNDI naming context. This can caused a problem in some cases, as the first request may be delayed as resources are loaded. To prevent this, a single simple call to the static method DataSourceManager.initialize() will result in pre-loading of all dataSources. You can query DataSource Manager on the status of initialization using the DataSourceManager.isInitialized() and DataSourceManager.initializationFailed() methods. These methods allow your application is determine if DataSource Manager is correctly initialized. All errors during initialization will be written to the common logging system. See BuzzSQL Logging for more information on DataSource Manager logging.
  5.1.3 DataSource Naming
DataSources are made available to BuzzSQL using a name that is based on the JNDI path. For example, a dataSource bound in your JNDI naming context at java:comp/env/jdbc/testDB would be named testDB, since java:comp/env/jdbc/ is the default root namespace search path.

All dataSources found under the root namespace are made available in DataSource Manager. This can create a problem if you have multiple dataSource bound in JNDI; the default dataSource is non-deterministic when there are multiple dataSources available. To fix this problem, you must either always specify a dataSourceName in the constructor of your BuzzSQL objects, call setDataSourceName(String) on your BuzzSQL objects, or include the buzzsql.properties file with the defaultDataSourceName property.

Example DataSource specification:
// DataSource bound in JNDI at java:comp/env/jdbc/testDB
Select select = new Select(sql, "testDB");
Or...
// DataSource bound in JNDI at java:comp/env/jdbc/testDB
Select select = new Select(sql);
select.setDataSourceName("testDB");
  5.2 Connection Pooling
BuzzSQL does not explicitly handle any type of database connection pooling. Connection pooling is the responsibility of the DataSource, or the factory class that is specified in your JNDI naming context. In a stand-alone J2SE environment, the default Shiftone OOC JNDI naming context will use by default the c3p0 database connection pool. See Installation for more information on Shiftone OOC JNDI and c3p0.

In a J2EE environment, your application server will usually provide transparent built-in connection pooling via JNDI bound dataSources.
  6. Miscellaneous Topics
 
  6.1 Explicit Connections
Explicit connections are an advanced feature of BuzzSQL that allows for greater flexibility in regards to opening and closing your database connection.

In normal use, BuzzSQL automatically accesses DataSource Manager to get a database connection when execute is called, and automatically releases this connection when close() is called. In contrast, an explicit connection is passed to the SQL object in the constructor, or using the setConnection(Connection con) method. BuzzSQL will not automatically commit or close an explicit connection. This allows the developer a greater amount of control to set connection specific parameters or use transactions. See Transactions for more information on using transactions in BuzzSQL.

You can query the type of connection a SQL object is using by calling usingExplicitConnection(). usingExplicitConnection() will return true if you pass a java.sql.Connection in via the constructor, or call setConnection(Connection con) with a non-null java.sql.Connection object. You can reset the BuzzSQL object's state to use an automatic connections by passing null to setConnection(Connection con).

The explicit java.sql.Connection can come from any source such as an external connection pool, a JNDI lookup, or BuzzSQL's DataSource Manager. It is common for an application to use BuzzSQL's automatic connection handling for 99% of the database access, but need to wrap a few specific calls in a transaction. In this case you can call DataSourceManager.getConnection() to obtain an explicit connection for the calls that need to be executed in a transaction, and allow BuzzSQL to use automatic connection handling for the rest.

Note: BuzzSQL's SQL objects can be used entirely with external connection with no ill effect by always setting an explicit connection from an external pool. In this case, DataSource Manager will never be initialized and the configuration files will not be read. In this way you can use BuzzSQL without the need of any configuration files.
  6.2 Transactions
As BuzzSQL's major design goal is to simplify JDBC, it does not explicitly provide support for database transactions. However, since BuzzSQL is also very flexible, you can still use transaction by utilizing BuzzSQL's explicit connection feature. See Explicit Connections for more information on External Connections.

The following code fragment demonstrates how to properly enclose updates inside a transaction.
Connection con = DataSourceManager.getConnection();
con.setAutoCommit(false);

Update update3 = null;
Update update4 = null;
boolean tranSuccess = true;

try
{
 update3 = new Update("update example1.table_example1 set col_str = ? where col_int = ?", con);
 update3.setArgs("tran", 234);
 update3.execute();

 update4 = new Update("update example1.table_example1 set col_str = ? where col_int = ?", con);
 update4.setArgs("tran", 234);
 update4.execute();
}
catch(Exception e)
{
 tranSuccess = false;
 e.printStackTrace();
}
finally
{
 if(update3 != null)
   update3.close();

 if(update4 != null)
  update4.close();

 try
 {
  if(tranSuccess)
   con.commit();
  else
   con.rollback();
 }
 catch(Exception e2)
 {
  e2.printStackTrace();
 }

 con.setAutoCommit(true);
 DataSourceManager.releaseConnection(con);
}
  6.3 Method Chaining
Method chaining is a style of coding in which methods that would normally return void instead return a reference to the object itself. This allows another method to immediately be called on the the same line of code; thus effectively chaining the method calls together.

Using method chaining is entirely optional and a matter of personal preference. The author of BuzzSQL finds that method chaining is ideally suited for the types of projects BuzzSQL is targeted towards. Method chaining can reduce the size of your code, make it more readable (in most cases), and reduce the number of temporary object references.

The concept is best described via an example of 2 fragments of code that produce the same results. This first fragment does not use method chaining;
Update update = new Update(sqlStr);
update2.setArgs(s,i);
update2.execute();
update2.close();
This fragment employs method chaining;
Update update = new Update(sqlStr).setArgs(s,i).execute().close();
The latter example can be further optimized by removing the likely unneeded variable "update" as follows:
new Update(sqlStr).setArgs(s,i).execute().close();
  6.4 Thread Safety
BuzzSQL's SQL objects (Select, Insert, Update, Delete, StoredProcedure) are not thread safe and should not be used by multiple threads at the same time.

DataSource Manager's methods are all synchronized, and it is therefore safe to use from multiple threads at the same time.
  6.5 Release Information (com.buzzsurf.sql.ReleaseInfo)
BuzzSQL includes a handy class which contains information on the version of BuzzSQL you are currently using. Using this class, you can query information such as product name, version, build number, and release date. An instance of the ReleaseInfo is obtained by calling BuzzSQL.getReleaseInfo(), as demonstrated in the following code fragment;
ReleaseInfo releaseInfo = BuzzSQL.getReleaseInfo();
System.out.println(releaseInfo.getWelcome());
System.out.println(releaseInfo.getVersionString());
System.out.println(releaseInfo.getProductName());
System.out.println(releaseInfo.getLicenseInfo());
System.out.println(releaseInfo.getReleaseDate());
System.out.println(releaseInfo.getWebsiteString());
System.out.println(releaseInfo.getMajorVersion());
System.out.println(releaseInfo.getMinorVersion());
System.out.println(releaseInfo.getBuildNumber());
  7. JavaDoc - API Documentation
Full JavaDoc generated API documentation is included with both the pre-built and source code releases of BuzzSQL in the /javadoc directory.
  8. Contacting the Author
BuzzSQL was written by Paul Cowan, a professional Java developer that resides in the area of Philadelphia, PA, USA.
  9. License
BuzzSQL is released under terms of the GNU Lesser General Public License. See LICENSE.txt for more information. The GNU Lesser General Public License can be found in the included file LGPL.txt .
  10. Change Log
  • 1.3.8 - 11/04/2007
    • Initial Release