Sie sind auf Seite 1von 30

Transbase

R
JDBC Driver 3.0

Transaction Software GmbH


Willy-Brandt-Allee 2
D-81829 München
Germany
Phone: +49-89-62709-0
Fax: +49-89-62709-11
Email: info@transaction.de
http://www.transaction.de

Version 6.8.1.40
November 02, 2010
Contents

1 Transbase JDBC Driver 3.0 3


1.1 Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3.1 Installation with Java SDK 1.3.x and above . . . . . . . . . 4
1.4 Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4.1 Import the JDBC classes . . . . . . . . . . . . . . . . . . . 4
1.4.2 Register the Transbase JDBC driver . . . . . . . . . . . . . 5
1.4.3 Open a JDBC connection . . . . . . . . . . . . . . . . . . . 5
1.4.4 Escape processing . . . . . . . . . . . . . . . . . . . . . . . 6
1.4.4.1 String functions . . . . . . . . . . . . . . . . . . . 7
1.4.4.2 Time and date functions . . . . . . . . . . . . . . 8
1.4.4.3 System functions . . . . . . . . . . . . . . . . . . . 9
1.5 Proprietary features . . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.5.1 Connection properties . . . . . . . . . . . . . . . . . . . . . 10
1.5.2 Type mapping . . . . . . . . . . . . . . . . . . . . . . . . . 10
1.5.3 Proprietary data types . . . . . . . . . . . . . . . . . . . . . 12
1.5.4 Query plans and profiling . . . . . . . . . . . . . . . . . . . 14
1.5.5 TCP/IP socket options . . . . . . . . . . . . . . . . . . . . 15
1.5.6 Asynchronous rollback . . . . . . . . . . . . . . . . . . . . . 15
1.5.7 Positioned updates and deletes . . . . . . . . . . . . . . . . 16
1.5.8 Named parameters . . . . . . . . . . . . . . . . . . . . . . . 17
1.5.9 JDBC logging . . . . . . . . . . . . . . . . . . . . . . . . . . 18

2
CONTENTS 3

1.6 Applets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.7 Common problems and FAQs . . . . . . . . . . . . . . . . . . . . . 19
1.7.1 Transbase versions minor than 4.3 cause problems with pre-
pared statements . . . . . . . . . . . . . . . . . . . . . . . . 19
1.7.2 Usage with JBuilder . . . . . . . . . . . . . . . . . . . . . . 20

2 Transbase JDBC extension package 21


2.1 Basics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.2 JNDI support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.3 Environment set-up . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.4 Connection pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.5 Data source properties . . . . . . . . . . . . . . . . . . . . . . . . . 29
Chapter 1

Transbase JDBC Driver 3.0

The Transbase JDBC driver is a pure Java JDBC driver, that implements the
standard JDBC (Java Database Connectivity) interface.
For detailed information on JDBC, please consult http://java.sun.com/.
This documentation describes installation and basic usage of the driver. Addi-
tionally includes an overview over proprietary features exceeding the standard
functionality.

1.1 Structure
The Transbase JDBC driver is a pure Java driver. It operates as a standalone
Transbase client, i.e. no additional software client installation is required for
running Java-based applications or applets.
The driver is delivered as two separate JAR files, where each one represents a
complete and independent implementation of the driver. The implementations
differs as follows:

tbjdbc.jar This Java archive contains the release version of a driver implementing
the JDBC 3.0 core API. This driver may be used for standalone applications
and Applets. Applets using this driver version however will work with Java
1.3 and above. Additionally, this archive also contains an implementation of
the JDBC 2.0 extension API, as described under 2.
This archive is highly optimized and stripped of all unnecessary function
calls. In particular JDBC Logging is completely removed from the code.
tbjdbc g.jar This archive is functionally identical to the tbjdbc.jar, but it con-
tains additional debug information, such as line number tables. Thus it
provides richer exception stack information.
This archive is also suitable for logging JDBC API calls.

4
1.2. REQUIREMENTS 5

1.2 Requirements

The driver can be used with Java JDKs of version 1.3 and above. The driver should
work with all Java virtual machine implementations. However it is recommended
to use the Java plug-in software (or Java runtime environment) delivered by Sun
Microsystems.

1.3 Installation

For a client installation only the JAR file containing the classes for the Transbase
JDBC driver is required. The JAR file has to be copied to a path, that is per-
manently reachable. (For Applets the JAR file can be located on a HTTP server.
Details for applets are discussed later.)

1.3.1 Installation with Java SDK 1.3.x and above

To ensure that each application can find the Transbase JDBC driver, one pos-
sibility is to copy the JAR file delivered with this documentation (tbjdbc.jar or
tbjdbc g.jar) into the lib/ext subdirectory of your JRE (Java runtime environ-
ment) directory. After this procedure the JAR file is automatically found without
the necessity of adding the filename to your CLASSPATH environment variable.
Finding the JAR files in the lib/ext directory causes them to be treated as installed
extensions to the Java base classes already installed on your computer.
If you do not want to install the JAR archives as extensions, you can specify the
class path containing the archive locations with the ”-classpath” option of the
Java command line tools.

1.4 Usage

The JDBC driver is accessed using the Java interfaces, that are defined in the
package of java. sql.*. However there are a few preparatory steps, that have
to be performed, before you can access a Transbase database. These steps are
explained in the next paragraphs, because they might slightly differ for different
Java drivers. Reading this article gives you only a clue about using the driver
with the DriverManager. For using the driver with naming services please see
”Transbase JDBC extension package”.

1.4.1 Import the JDBC classes

You have to import the package with the JDBC interface definition. Add the
following code to the import section of your class.
6 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

import java.sql.*;

1.4.2 Register the Transbase JDBC driver

The Transbase JDBC driver must be registered by the driver manager. The driver
manager has to know, which drivers can be used on your system. The registration
is done like proposed in the Java specification, by adding the following line to your
code.

Class.forName("transbase.jdbc.Driver");

Please notice that this might not work with the Microsoft Virtual Machine. For
Microsoft’s VM replace the call from above with:

DriverManager.registerDriver(new transbase.jdbc.Driver());

1.4.3 Open a JDBC connection

In order to open a connection you have to know the URL of the database, a
user name and the users password. Transbase JDBC supports two different
structures for the database URL. However every Transbase URL begins with
jdbc:transbase:. Let us assume we would like to connect to a database named
DB located on the server named MYSERVER. In the first native prototype the URL
was build up as follows:
jdbc:transbase:DB@MYSERVER
This old structure is very similar to the connect strings that are known from the
Transbase client programs. However, this way of writing has the disadvantage,
that you cannot specify a port address for the connection.
For this reason you can rewrite the same URL in a way, that looks more like an
internet address: jdbc:transbase://MYSERVER/DB
Of course you can use an IP address instead of a hostname, too. Additionally
you can specify a port address to be used. If no port address is specified the
port 2024 is used. This is the port address you normally defined for tbkernel in
TBWin.ini. The setting for tbserver is not currently used by the JDBC driver,
because the driver does not support distributed transactions.
If you would like to rewrite the previous URL using an IP address and a port
number (4444 instead of 2024), it would look like this:
jdbc:transbase://172.16.1.1:4444/DB
If now you would like to connect to the database as "tbadmin" with password ""
add the following line to your code:
1.4. USAGE 7

Connection conn = DriverManager.getConnection


("jdbc:transbase://172.16.1.1:4444/DB", "tbadmin", "");

Example program for printing the names of the table systable

import java.sql.*;

class JdbcTest {
public static void main (String args [])
throws SQLException, ClassNotFoundException {

// Load Transbase driver, this might throw a ClassNotFoundException


Class.forName("transbase.jdbc.Driver");
String dburl = "jdbc:transbase://172.16.1.1:4444/DB";
String uname = "tbadmin";
String pw = "";

Connection conn = DriverManager.getConnection(url, uname, pw);

// Query systable
Statement stmt = conn.createStatement ();
ResultSet rset = stmt.executeQuery ("select tname from systable");

// Print the name out


while (rset.next ())
System.out.println (rset.getString (1));
}
}

1.4.4 Escape processing

Transbase supports the JDBC escape syntax. Escape processing is on by de-


fault. You can turn it off by using the method setEscapeProcessing() of the
Statement class.
The following escape sequences are supported:
{ d yyyy-mm-dd } is mapped to DATETIME[YY:DD](yyyy-mm-dd).
{ t hh:mm:ss } is mapped to DATETIME[HH:SS](hh:mm:ss).
{ ts yyyy-mm-dd hh:mm:ss.f } is mapped to DATETIME[YY:MS](yyyy-mm-dd
hh:mm:ss.f).
The fractals of the timestamp can be omitted. Note that Transbase supports only
milliseconds. If nanoseconds are used as a fractal value, the value is rounded to
milliseconds.
{ oj outer-join } is mapped to outer join.
8 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

This writing is accepted for compatibility only. As Transbase supports exactly


the outer join syntax proposed by the SQL standard you can use the outer join
clauses as defined in the Transbase SQL manual.
{ escape c }
You can use this syntax to specify an escape character for LIKE expressions. Note
that this sequence must always stand at the very end of a statement. Although the
Transbase database system allows a subquery or some other complex expression
on the right side of a LIKE clause, the usage of this escape sequence will only
work for LIKE clauses that use a single string literal.
{ fn functionname(parameters, ...) }
This escape sequence is used for JDBC scalar functions that are automatically
mapped to the Transbase pendants.
{ call procedure name[(?, ...)] }
This statement will by passed unmodified to the database, apart from the removal
of the curly braces. If the optional parameter list is missing then ”()” will be
appended.
{ ? = call procedure name[(?, ...)] }
Since Transbase Stored Procedures never return a value, this statement will be
modifies in such way that the result parameter (ordinal number: 1) will be moved
to the parameter list as first parameter. This change will create a statement
complying this the first syntax while preserving the original parameter numbering.

1.4.4.1 String functions

CONCAT(string1, string2)
Character string formed by appending string2 to string1

INSERT(string1, start ,length, string2)


A character string formed by deleting length characters from string1 be-
ginning at start, and inserting string2 into string1 at start

LCASE(string)
Convert string to lowercase characters

LEFT(string, count)
The count leftmost characters from string

LENGTH(string)
Number of characters in string
1.4. USAGE 9

LOCATE(string1, string2[, start])


Position in string2 of the first occurrence of string1, searching from the
beginning of string2; if start is specified, the search begins from position
start.

LTRIM(string)
Characters of string with leading blank spaces removed

REPEAT(string, count)
A character string formed by repeating string for count times.

REPLACE(string1, string2, string3)


Replaces all occurrences of string2 in string1 with string3

RIGHT(string, count)
The count rightmost characters in string

RTRIM(string)
The characters of string with no trailing blanks

SPACE(count)
A string consisting of count spaces

SUBSTRING(string, start, length)


A string formed by extracting length characters from string beginning at
start

UCASE(string)
Converts all lowercase characters in string to uppercase

1.4.4.2 Time and date functions

CURDATE()
The current date as a date value

CURTIME()
The current local time as a time value

DAYNAME(date)
A character string representing the day component of date

DAYOFMONTH(date)
An integer from 1 to 31 representing the day of the month in date

DAYOFWEEK(date)
An integer from 1 to 7 representing the day of the week in date; 1 represents
Sunday
10 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

HOUR(time)
An integer from 0 to 23 representing the hour component of time

MINUTE(time)
the minute component of time

MONTH(date)
the month component of date

MONTHNAME(date)
A character string representing the month component of date

NOW()
A timestamp value representing the current date and time

QUARTER(date)
An integer from 1 to 4 representing the quarter in date

SECOND(time)
the second component of time

TIMESTAMPADD(interval,count,timestamp)
A timestamp calculated by adding count number of interval(s) to time-
stamp; interval may be one of the following:

SQL_TSI_FRAC_SECOND
SQL_TSI_SECOND
SQL_TSI_MINUTE
SQL_TSI_HOUR
SQL_TSI_DAY
SQL_TSI_WEEK
SQL_TSI_MONTH
SQL_TSI_QUARTER
SQL_TSI_YEAR

YEAR(date)
An integer representing the year component of date

1.4.4.3 System functions

IFNULL(expression, value)
Same as COALESCE in Transbase but restricted to two parameters

USER()
User name
1.5. PROPRIETARY FEATURES 11

1.5 Proprietary features

In addition to the implementation of the JDBC Driver interface, the Transbase


JDBC driver offers several proprietary extensions.

1.5.1 Connection properties

Normally a user will prefer to connect to the database as shown in the example
above. However there exist possibilities to specify some additional connection
properties, that can be used together with the getPropertyInfo() method of the
Transbase JDBC driver. For a detailed description for opening a connection this
way please consult the JDBC driver specification.
The properties made available through getPropertyInfo() are:
user the name of the database user
password the database password of the user
characterencoding This property is only provided for backward compatibility to
Transbase Versions before 5.3. It specifies the encoding that is expected from the
connected database. Transbase Versions 5.3 and higher determine the required
character encoding from the server, i.e. data from a UTF-8 coded database is
converted from UTF-8 to Unicode, while data from a ASCII coded database is
converted from single byte ASCII to Unicode and vice versa.
For older versions of Transbase, the property can be set explicitly: If you submit an
empty string or a null value for the property, the bytes received from the database
are converted according to the platform dependent encoding. The parameter
should be used by an applet or an application to represent Transbase data the
same way on different platforms. Valid values are of type java.lang.String. Every
value is accepted that can be used for String constructors to build a String from a
byte array. The value has effects on how String values (eg. SQL statements) are
sent to the database and on how character typed values are read or sent to the
database when reading a ResultSet or when using a PreparedStatement instance.
We recommend to use only single byte encodings that are compatible with ASCII
7 Bit. This is to ensure, SQL statements can be interpreted correctly by the
Transbase database kernel. On the other hand inserting multibyte strings into
Transbase CHAR and VARCHAR columns will prevent the pattern matcher from
working correctly. This means that LIKE statements using patterns can not be
evaluated in a correct way, if multibyte encoding is used.

1.5.2 Type mapping

Mapping from JDBC types to Transbase types as delivered by DatabaseMeta-


Data.getTypeInfo(). Note that there might be more possibilities for mapping a
12 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

JDBC type to a Transbase type. In this case the first mapping is considered
better.
JDBC Type Transbase Type
TINYINT TINYINT
NUMERIC(3)
SMALLINT SMALLINT
NUMERIC(5)
INTEGER INTEGER
NUMERIC(10)
BIGINT NUMERIC(30)
NUMERIC NUMERIC
DECIMAL NUMERIC
DOUBLE DOUBLE
FLOAT DOUBLE
REAL FLOAT
CHAR CHAR
BINCHAR
VARCHAR VARCHAR
CHAR(*)
BINCHAR(*)
DATE DATETIME[YY:DD]
TIME DATETIME[HH:SS]
TIMESTAMP DATETIME[YY:MS]
LONGVARBINARY BLOB
BIT BOOL
TINYINT
Mapping from Transbase types to JDBC types by ResultSetMetaData. All Trans-
base types not contained in the list are considered to be JDBC Types.OTHER.
1.5. PROPRIETARY FEATURES 13

Transbase Type JDBC Type


TINYINT TINYINT
SMALLINT SMALLINT
INTEGER INTEGER
NUMERIC NUMERIC
FLOAT REAL
DOUBLE DOUBLE
CHAR(*) VARCHAR
VARCHAR VARCHAR
CHAR CHAR
DATETIME[YY:DD] DATE
DATETIME[HH:SS] TIME
DATETIME[YY:MS] TIMESTAMP
BOOL BIT
BINCHAR(*) VARCHAR
BINCHAR CHAR
BLOB LONGVARBINARY
User defined type mapping is currently not supported by the Transbase JDBC
driver.

1.5.3 Proprietary data types

In addition to the standard data types, Transbase possesses proprietary data types.
Consequently, these data types are not supported by the standard JDBC getter
and setter methods. This shortcoming is circumvented, by using the ResultSet.
getObject() / PreparedStatement.setObject() methods for handling these
data types.
Non-standard types are represented as instances of the following class definitions.
TBDatetime is the exact equivalent to the Transbase DATETIME SQL type. In addi-
tion to mappings to Java types java.sql.Time, java.sql.Date, and java.sql.
Timestamp, this class allows to set and retrieve individual DATETIME components,
and it also allows exact representation of DATETIME[YY:MO] or DATETIME[HH] val-
ues.

public class transbase.tbx.types.TBDatetime {


public TBDatetime();
public java.sql.Date getDate();
public java.sql.Date getDate(java.util.Calendar);
public int getField(int);
public int getHighField();
public int getLowField();
public java.lang.String getString();
public java.sql.Time getTime();
14 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

public java.sql.Time getTime(java.util.Calendar);


public java.sql.Timestamp getTimestamp();
public java.sql.Timestamp getTimestamp(java.util.Calendar);
public boolean isNull();
public void setDate(java.sql.Date);
public void setDate(java.sql.Date, java.util.Calendar);
public void setField(int, int);
public void setHighField(int);
public void setLowField(int);
public void setNull();
public void setString(java.lang.String);
public void setTime(java.sql.Time);
public void setTime(java.sql.Time, java.util.Calendar);
public void setTimestamp(java.sql.Timestamp);
public void setTimestamp(java.sql.Timestamp, java.util.Calendar);
}

TBTimespan represents a time interval corresponding to the Transbase TIMESPAN


SQL type. It extends TBDatetime, hence inheriting the same public interface.
In contrast to TBDatetime, TBTimespan is a signed data type, necessiating the
following extensions to the former’s interface.

public class transbase.tbx.types.TBTimespan


extends transbase.tbx.types.TBDatetime {
public TBTimespan();
public int getSign();
public void setSign(int);
}

Information on these data types is provided via extensions to the ResultSetMeta-


Data and ParameterMetaData interfaces. The method getNativeType() retrieves
the Transbase type, as declared in transbase.tbx.TBConst, e.g. TB__DATETIME,
TB__TIMESPAN, TB__BITSS, etc.
The methods getLowField() and getHighField() are used the retrieve exact
type boundaries of DATETIME and TIMESPAN data. They return values correspond-
ing to the constants TB__YY, TB__MO, TB__DD etc. in transbase.tbx.TBConst.

public class transbase.jdbc.ResultSetMetaData {


public int getLowField(int);
public int getHighField(int);
public int getNativeType(int);
}

public class transbase.jdbc.ParameterMetaData {


public int getLowField(int);
public int getHighField(int);
public int getNativeType(int);
}
1.5. PROPRIETARY FEATURES 15

To access these methods, the following objects have to be casted to proprietary


subclasses:

java.sql.ResultSetMetaData -> transbase.jdbc.ResultSetMetaData


java.sql.ParameterMetaData -> transbase.jdbc.ParameterMetaData

Finally, TBBits is corresponding to the Transbase SQL types for bit arrays, i.e.
BITSS and BITSS2.

public class transbase.tbx.types.TBBits {


public TBBits();
public void addSingleBit(int);
public void delSingleBit(int);
public byte[] getBitArray();
public int getLength();
public java.lang.String getString();
public boolean isNull();
public int getMaxBitPos();
public void setBytes(byte []);
public void setNull();
public void setString(java.lang.String);
public int testBit(int);
}

1.5.4 Query plans and profiling

With the following methods, it is possible the retrieve a String representations


of query execution plans and query profiling data. To access these methods, the
following objects have to be casted to proprietary subclasses:

java.sql.Connection -> transbase.jdbc.Connection


java.sql.Statement -> transbase.jdbc.Statement
java.sql.PreparedStatement -> transbase.jdbc.PreparedStatement
java.sql.ResultSetMetaData -> transbase.jdbc.ResultSetMetaData

Proprietary interface:

void transbase.jdbc.Connection.setPlans(int)

will activate / deactivate query plan output. The parameter must be one of
PLANS_ON, PROFILES_ON, and PLANS_OFF as defined in transbase.tbx.TBConst.
Use

String transbase.jdbc.Statement.getPlan()
String transbase.jdbc.PreparedStatement.getPlan()
String transbase.jdbc.ResultSetMetaData.getPlan()

to retrieve plans or profiling data after the query was executed.


16 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

1.5.5 TCP/IP socket options

It is possible to configure the TCP/IP socket options that are used to establish
JDBC connections. The following system properties reflect default setting and
possible settings, where the system default is used.

transbase.tbx.java.TBXJavaConnection.SO_LINGER_ENABLED = "true"
transbase.tbx.java.TBXJavaConnection.SO_LINGER = 50
transbase.tbx.java.TBXJavaConnection.SO_RCVBUF = 65536
transbase.tbx.java.TBXJavaConnection.SO_SNDBUF = 65536
transbase.tbx.java.TBXJavaConnection.TCP_NODELAY =
<"true"|"false", uses System default>
transbase.tbx.java.TBXJavaConnection.SO_KEEPALIVE =
<"true"|"false", uses System default>
transbase.tbx.java.TBXJavaConnection.SO_REUSEADDR =
<"true"|"false", uses System default>
transbase.tbx.java.TBXJavaConnection.IPTOS =
<Type of service / Traffic Class / uses System default>
transbase.tbx.java.TBXJavaConnection.SO_TIMEOUT
<not configurable, set by JDBC>

Consult java.net.Socket for information on the meaning of the various options.


SO SNDBUF and SO RCVBUF are buffer sizes for sending and receiving data.
Reduce these to overcome TCP/IP problems on some systems, e.g. ”No buffer
space available”. Properties must be set via System.setProperty() prior to
loading the JDBC Driver to take effect.

1.5.6 Asynchronous rollback

JDBC offers the possibility to asynchronously cancel a single Statement during ex-
ecution using the cancel() methods of the java.sql.Statement and java.sql.
PreparedStatement classes. Additionally, Transbase can rollback an entire trans-
action that is currently in progress.
This functionality is a proprietary feature of the Transbase JDBC driver. It be-
comes available if you cast an
java.sql.Connection object to transbase.jdbc.Connection.
This class provides an extended interface, comprising the proprietary method
rollbackOutband(). The call is typically executed from a second thread, that
shares the connection object with the original thread.
Sample call:
((transbase.jdbc.Connection)myConnection).rollbackOutband();
1.5. PROPRIETARY FEATURES 17

This method will rollback the current transaction, even if a Statement is currently
executed by the kernel. If a Statement is executing when rollbackOutband() is
called, then that thread will be interrupted and throws an SQLException. If the
connection is currently idle, the call will behave like a conventional rollback.

1.5.7 Positioned updates and deletes

The Transbase JDBC driver supports positioned updates and deletes on an open
ResultSet instance. In order to use this feature you have to execute a ”select
for update” statement on a table. In order to reference the result set you have
to call the method setCursorName() of the PreparedStatement/Statement in-
stance. The cursor name can be used to reference the result set of this (prepared)
statement from another (prepared) statement. This is the reason, why each cur-
sor name must be unique within one connection. If no cursor name is specified,
a cursor name is assigned by the JDBC driver and can be evaluated by calling
getCursorName().
The cursor of the ”select for update” query is moved to the row that has to
be changed. This is done by calling ResultSet.next(). Now a second (pre-
pared) statement object can be used to do the positioned update or delete. The
WHERE section of this second statement must contain only the clause ”CURRENT
OF <cursorname>”.
The following code fragment is an example for an update positioned. The value
of column i in the first row of table t is updated by using an update positioned
via a prepared statement It is assumed, that conn is an instance of java.sql.
Connection that has previously been opened.

public void update_positioned() throws SQLException {

// prepare update statement


PreparedStatement prepStat = conn.prepareStatement(
"UPDATE t SET i=? WHERE CURRENT OF mycursor");

// create query and open cursor


Statement stat = conn.createStatement();
stat.setCursorName("mycursor");

ResultSet res = stat.executeQuery("SELECT i FROM t FOR UPDATE");

// position on first row


res.next();
18 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

// set the parameter for the prepared statement


prepStat.setInt(1, 10);

// execute the update positioned


prepStat.executeUpdate();

// close the cursor. If we are in auto commit mode,


// the commit happens right now
res.close();
}

1.5.8 Named parameters

The JDBC standard does not support named parameters in prepared SQL queries.
Therefore, a JDBC program must use the ’ ?’ placeholder for parameters in SQL
queries. Parameters are set using the PreparedStatement’s setXXX methods.

java.sql.PreparedStatement prepStat = conn.prepareStatement(


"INSERT INTO t VALUES(?,?,?)");

prepStat.setInt(1, 10);
prepStat.setInt(2, 0);
prepStat.setInt(3, 10);

prepStat.executeUpdate();

The example above may be implemented using named parameters:

transbase.jdbc.PreparedStatement prepStat =
(transbase.jdbc.PreparedStatement)conn.prepareStatement(
"INSERT INTO t VALUES(:param_name,:other_value,:param_name)");

prepStat.setInt("param_name", 10);
prepStat.setInt("other_value", 0);

prepStat.executeUpdate();

The proprietary interface routines are made accessible by casting the java.sql.
PreparedStatement to transbase.jdbc.PreparedStatement.
Note that multiple occurrences of parameters with the same name are explicitly
allowed. Parameters of identical name are all set in one single setXXX call.
Conversely, the ParameterMetaData class was also extended for providing access
to parameter names of a prepared statement.
1.5. PROPRIETARY FEATURES 19

transbase.jdbc.ParameterMetaData paramMetaData =
(transbase.jdbc.ParameterMetaData) prepStat.getParameterMetaData();
for(int i=paramMetaData.getParameterCount();i>0;i--)
System.out.println(paramMetaData.getParameterName(i));

1.5.9 JDBC logging

The debugable version of the JDBC driver (tbjdbc g.jar) supports logging of JDBC
API calls and network traffic to the Transbase server. Logging is concentrated in
the class transbase.jdbc.TBJDBCLog and controlled via its public interface:

public static void setLogStream(java.io.PrintWriter outStream);


public static void setJDBCCallLogging(boolean enabled);
public static void setJDBCReturnValueLogging(boolean enabled);
public static void setJDBCRequestLogging(boolean enabled);

Hence, logging is activated by configuration of the TBJDBCLog class.

// configure JDBC logging output and scope


try {
transbase.jdbc.TBJDBCLog.setLogStream(new java.io.PrintWriter(
new java.io.FileOutputStream("/tmp/tbjdbc.log", true)));
} catch (Exception e) {}
transbase.jdbc.TBJDBCLog.setJDBCCallLogging(true);
transbase.jdbc.TBJDBCLog.setJDBCReturnValueLogging(false);
transbase.jdbc.TBJDBCLog.setJDBCRequestLogging(true);

// finally load Transbase JDBC driver


Class.forName("transbase.jdbc.Driver);

Alternatively, it is possible to enable logging by setting the Java system property


transbase.jdbc.Driver.LOGGING to point to a target file, e.g. on the command
line:

java -Dtransbase.jdbc.Driver.LOGGING=c:\tbjdbc.log -cp=<classpath> ...

This will activate the complete logging facilities and direct its output into the
appointed file. In other environments (J2EE, Tomcat, etc.) system properties are
usually set via various configuration files. Make sure the system property is set
before the Transbase JDBC driver is loaded.
20 CHAPTER 1. TRANSBASE JDBC DRIVER 3.0

1.6 Applets

As mentioned in the introduction the Transbase JDBC driver is suited for Java
applets because it is implemented using pure Java code. There is no need to
access local resources, which would cause security problems because of the sandbox
environment of the applet. The database, the applet connects to, must be installed
on the same host the applet itself came from. Connections to other hosts will cause
a security exception. Future versions of the Java SDK however should provide
some mechanism to grant special privileges to signed applets.
To make the JDBC driver available for an applet there are two possibilities:

• The TB JDBC JAR file is installed on each client an therefore accessible


through the local CLASSPATH. The advantage are faster downloads of the
applet and less security problems, because local classes are not affected from
the strong security restrictions of the sandbox. A big disadvantage is the
high installation and maintenance (updates) effort.
• The TB JDBC JAR is downloaded from the HTTP server just like the major
part of the applet.
All archives that have to be transferred for an applet must be named in the
HTML applet tag:

<APPLET CODE = "myClass.class"


CODEBASE = "."
ARCHIVE = "my.jar, tbjdbc.jar"
WIDTH = 980
HEIGHT = 550
NAME = "TestApplet"
ALIGN = middle
VSPACE = 0
HSPACE = 0>
</APPLET>

In order to use just one Java archive you might prefer to unpack the tbjdbc.jar
archive and pack it together with your applets class files.

1.7 Common problems and FAQs

1.7.1 Transbase versions minor than 4.3 cause problems with pre-
pared statements

Transbase versions older than 4.3 do not provide information about the count
and type of parameters for a prepared statement. This causes problems with the
1.7. COMMON PROBLEMS AND FAQS 21

setXXX methods of the PreparedStatement class. All methods to set column


values to stream contents will result in a parameter of type BLOB. As streams can
normally be used to set character types too, this can cause problems. In addition
to this minor problems, the method setObject will not work at all, because the
destination type for a conversion cannot be retrieved.

1.7.2 Usage with JBuilder

JBuilder from Inprise provides the programmer with a library to perform database
access via a JDBC driver. You should use only uppercase table names and upper-
case column names for your database objects, if you want to be able to access them
by using those libraries. The libraries generate (prepared) statements, that are
used to access and manipulate table contents. The statements are generated with
uppercase table and column identifiers, which causes problems using a Transbase
kernel that treats those identifiers case sensitive.
Chapter 2

Transbase JDBC extension


package

The Transbase JDBC extension package will work on Java SDK 1.3 and above.
The package implements features of the JDBC 2.0 standard extension API. This
document describes the usage of those features. For a description of the installation
and usage of the core functions of the Transbase JDBC driver please consult
”Transbase pure JDBC driver” 1.
For detailed information on JDBC, please consult http://java.sun.com/.

2.1 Basics

The JDBC standard extension API provides special features that are mainly im-
portant for enterprise applications. The Transbase classes that implement the
JDBC standard extension API are contained in the java archive file tbjdbc.jar. In
order to use the extension API you have to install the JAR archive on your com-
puter. The installation is done the same way like for tbjdbc.jar. For installation
hints see 1.3.

2.2 JNDI support

JNDI (Java Naming and Directory Interface) is part of the Java enterprise edition
and is therefore not contained in the standard development kits. Before using the
JNDI functions of the Transbase JDBC driver you have to download the JNDI
packages from Sun Microsystems. The JNDI package defines only an interface to
existing naming and directory services (eg. LDAP based service). For the sup-
port of such a service additional packages might be necessary. Generally naming

22
2.3. ENVIRONMENT SET-UP 23

services are a sort of database that allow to identify an object by using a logical
name. Using JNDI with JDBC means the usage of a logical name to identify a
data source. The motivation for this procedure is the independence from driver
specific URLs, driver names and driver settings during deployment of an appli-
cation. For this purpose a Java object is delivered by the JNDI when resolving
the logical name of a data source. This object is used to open connections to a
database. The interface of the object is defined by javax.sql.DataSource that
is part of the JDBC standard extension API.
What follows is an example for using the naming and directory service for Trans-
base data sources. The program registers a data source with an LDAP service
and, in a second step, uses the logical name to open a connection to the Transbase
database.

2.3 Environment set-up

A hash table is used to hold the key/value pairs of the environment variables.
Note that the information could also be defined by command line arguments or
by real environment variables of your operating system. Several parameters are
used to define the behavior of the JNDI sub system. The information specifies
the subsystem to use (in this case LDAP), the provider URL (a machine at Alpin,
Italy), a LDAP authentication mode, user and password for adding a new service.
Note that a couple of environment settings depends from the subsystem.

Hashtable env = new Hashtable(5, 0.75f);


env.put(Context.INITIAL_CONTEXT_FACTORY,
System.getProperty("java.naming.factory.initial"));
env.put(Context.PROVIDER_URL, "ldap://ntrier/o=alpin.it");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL,
"uid=admin,ou=Administrators,ou=TopologyManagement,o=NetscapeRoot");
env.put(Context.SECURITY_CREDENTIALS, "password");

Get the initial context


The naming service supports contexts and sub contexts (like directories and sub-
directories in a file system). There is an initial root context, that is used as a
starting point for the lookup of logical names. All logical names are relative to
the root context.

DirContext ctx = new InitialDirContext(env);

Create a sub context


Optionally we could now define a new sub context for our data sources.
24 CHAPTER 2. TRANSBASE JDBC EXTENSION PACKAGE

try {
ctx.createSubcontext("cn=jdbc");
} catch (NameAlreadyBoundException ex) {
System.out.println("Name jdbc already bound, do nothing");
}

Create a data source object and bind it to a logical name


Now we create an instance of the Transbase JDBC data source class. The set-
methods of the object are used to define the properties of the data source. The
properties are driver specific, for this reason different JDBC drivers can support
different set and get methods. The setup of the properties is normally done by
a systems administrator who knows about the requirements of a specific JDBC
driver. The end user, that is the consumer of a data source, is not required to know
about the set- and get-methods of a data source object, therefore those methods
are not contained in the interface defined in javax.sql.DataSource. A list of
supported data source properties can be found in Data source properties.

transbase.jdbcx.DataSource vds = new transbase.jdbcx.DataSource();


vds.setServerName("NTRIER");
vds.setDatabaseName("db");
vds.setDescription("db@ntrier");
try {
ctx.bind("cn=db, cn=jdbc",vds);
} catch (NameAlreadyBoundException ex) {
System.out.println("Name jdbc/db already bound, do nothing");
}

Lookup a data source


The consumer will lookup a data source object by using its logical name. Note
that the end user must also get the initial context, before looking for the data
source object.

DataSource ds = (DataSource)ctx.lookup("cn=dbPoolModule, cn=jdbc");

Open a connection using the data source


Now a connection is opened to the Transbase database referenced by the data
source object. The connection can be made by specifying a user name and a
password. If a user name and a password has been defined in the data source
object, the parameterless version of getConnection() could also be used to get a
connection.

Connection con = ds.getConnection("user", "password");


2.4. CONNECTION POOLING 25

2.4 Connection pooling

Connection gives you the possibility to reuse physical connections instead of


closing them and reopening them. As described in Sun’s Standard Extension
API specification the driver vendor delivers only the tools necessary to imple-
ment a connection pooling strategy and the classes implementing the strategy.
For this purpose the Transbase JDBC extension package offers the class trans-
base.jdbcx.ConnectionPoolDataSource. This class is a special data source that
creates PooledConnection objects. The JDBC standard extension API specifica-
tion contains information on how to implement a connection pooling mechanism.
The class transbase.jdbcx.SimpleConnectionPoolModule is a sample implementa-
tion for connection pooling. Note that no support will be provided for the sample.

package transbase.jdbcx;
import javax.sql.*;
import javax.naming.*;
import java.util.Properties;
import java.sql.SQLException;
import java.io.PrintWriter;
import transbase.jdbcx.pooling.ConnectionCache;
import transbase.jdbc.TBJDBCLog;
public class SimpleConnectionPoolModule implements javax.sql.DataSource,
Referenceable, java.io.Serializable {
private int mMaxConnections = 10;
private String mDataSourceName = "";
private String mDescription = "";
private String mUser = "";
private String mPassword = "";
public final static String PROPS_MAX_CONNECTIONS = "maxConnections";
public final static String PROPS_DATA_SOURCE_NAME = "dataSourceName";
public final static String PROPS_DESCRIPTION = "description";
public final static String PROPS_USER = "user";
public final static String PROPS_PASSWORD = "password";

private ConnectionCache mCache = new ConnectionCache();

public SimpleConnectionPoolModule() {
mLog.logJDBCMethodCall(this, null, null);
mLog.logJDBCReturnValue(this, null, null);
}

public void setDescription(String aDescription) {


final String methodName = "setDescription";
mLog.logJDBCMethodCall(this, methodName, new Object[] {aDescription});
mDescription = aDescription;
mLog.logJDBCReturnValue(this, methodName, null);
}
26 CHAPTER 2. TRANSBASE JDBC EXTENSION PACKAGE

public void setMaxConnections(int aMaxConnections) {


final String methodName = "setMaxConections";
mLog.logJDBCMethodCall(this, methodName,
new Object[] {new Integer(aMaxConnections)});
mMaxConnections = aMaxConnections;
mLog.logJDBCReturnValue(this, methodName, null);
}

public void setDataSourceName(String aDataSourceName) {


final String methodName = "setDataSourcename";
mLog.logJDBCMethodCall(this, methodName,
new Object[] {aDataSourceName});
mDataSourceName = aDataSourceName;
mLog.logJDBCReturnValue(this, methodName, null);
}

public void setPassword(String aPassword) {


final String methodName = "setPassword";
mLog.logJDBCMethodCall(this, methodName, new Object[] {"xxx"});
mPassword = aPassword;
mLog.logJDBCReturnValue(this, methodName, null);
}

public void setUser(String aUser) {


final String methodName = "setUser";
mLog.logJDBCMethodCall(this, methodName, new Object[] {aUser});
mUser = aUser;
mLog.logJDBCReturnValue(this, methodName, null);
}

public int getMaxConnections() {


final String methodName = "getMaxConnections";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName, new Integer(mMaxConnections));
return mMaxConnections;
}

public String getDataSourceName() {


final String methodName = "getDataSourceName";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName, mDataSourceName);
return mDataSourceName;
}

public String getDescription() {


final String methodName = "getDescription";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName, mDescription);
return mDescription;
2.4. CONNECTION POOLING 27

public String getPassword() {


final String methodName = "getPassword";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName, "xxx");
return mPassword;
}

public String getUser() {


final String methodName = "getUser";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName, mUser);
return mUser;
}

public Reference getReference() throws NamingException {


final String methodName = "getReference";
mLog.logJDBCMethodCall(this, methodName, null);
Reference ref = new Reference(this.getClass().getName(),
"transbase.jdbcx.naming.TBPoolModuleFactory", null);
ref.add(new StringRefAddr(PROPS_DATA_SOURCE_NAME, getDataSourceName()));
ref.add(new StringRefAddr(PROPS_DESCRIPTION, getDescription()));
ref.add(new StringRefAddr(PROPS_MAX_CONNECTIONS,
Integer.toString(getMaxConnections())));
ref.add(new StringRefAddr(PROPS_USER, getUser()));
ref.add(new StringRefAddr(PROPS_PASSWORD, getPassword()));
mLog.logJDBCReturnValue(this, methodName, ref);
return ref;
}

public java.sql.Connection getConnection()


throws SQLException {
final String methodName = "getConnection";
mLog.logJDBCMethodCall(this, methodName, null);
java.sql.Connection aRetValue = getConnection(getUser(), getPassword());
mLog.logJDBCReturnValue(this, methodName, aRetValue);
return aRetValue;
}

public java.sql.Connection getConnection(String user, String password)


throws SQLException {
final String methodName = "getConnection";
mLog.logJDBCMethodCall(this, methodName, new Object[] {user, "xxx"});
synchronized (mCache) {
javax.sql.PooledConnection aConnection =
(PooledConnection) mCache.lookup(user);
if (aConnection == null) {
// No Connection found in pool
28 CHAPTER 2. TRANSBASE JDBC EXTENSION PACKAGE

// Checking for reaching maximum connections goes here


try {
Context ctx = new InitialContext();
ConnectionPoolDataSource cpds =
(ConnectionPoolDataSource) ctx.lookup(getDataSourceName());
aConnection = cpds.getPooledConnection(user, password);
} catch (NamingException ex) {
throw new SQLException(ex.getMessage());
}

mCache.addConnection(aConnection, user);
mCache.setUsed(aConnection, true);
aConnection.addConnectionEventListener(mCache);
} else {
mCache.setUsed(aConnection, true);
}
java.sql.Connection aRetValue = aConnection.getConnection();
mLog.logJDBCReturnValue(this, methodName, aRetValue);
return aRetValue;
}
}

// Required methods and Properties for DataSource implementations

private PrintWriter mLogStream = null;


private int mLoginTimeout = 0;
private transient TBJDBCLog mLog = new TBJDBCLog();

public void setLoginTimeout(int seconds) throws SQLException {


final String methodName = "setLoginTimeout";
mLog.logJDBCMethodCall(this, methodName,
new Object[] {new Integer(seconds)});
mLoginTimeout = seconds;
mLog.logJDBCReturnValue(this, methodName, null);
}

public int getLoginTimeout() throws SQLException {


final String methodName = "getLoginTimeout";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName,
new Integer(mLoginTimeout));
return mLoginTimeout;
}

public void setLogWriter(PrintWriter out) throws SQLException {


final String methodName = "setLogWriter";
mLog.logJDBCMethodCall(this, methodName, new Object[] {out});
mLogStream = out;
2.4. CONNECTION POOLING 29

mLog.setDSLogStream(out);
mLog.logJDBCReturnValue(this, methodName, null);
}

public PrintWriter getLogWriter() throws SQLException {


final String methodName = "getLogWriter";
mLog.logJDBCMethodCall(this, methodName, null);
mLog.logJDBCReturnValue(this, methodName, mLogStream);
return mLogStream;
}

Here is the code for the sample factory that is used to create the referenceable
object:

package transbase.jdbcx.naming;
import javax.naming.*;
import javax.naming.spi.*;
import java.util.Hashtable;
import transbase.jdbcx.*;
public class TBPoolModuleFactory implements ObjectFactory {
public Object getObjectInstance(Object refObj, Name name,
Context nameCtx, Hashtable env) throws Exception {
Reference ref = (Reference)refObj;
// Check if the class name is recognized as Transbase DataSource
if (ref.getClassName().equals(
"transbase.jdbcx.SimpleConnectionPoolModule")) {
SimpleConnectionPoolModule aDataSource =
new SimpleConnectionPoolModule();
// Setting properties of the DataSource by using more general class
aDataSource.setDataSourceName(
(String)ref.get(SimpleConnectionPoolModule.PROPS_DATA_SOURCE_NAME)
.getContent());
aDataSource.setDescription(
(String)ref.get(SimpleConnectionPoolModule.PROPS_DESCRIPTION)
.getContent());
aDataSource.setMaxConnections(Integer.parseInt(
(String)ref.get(SimpleConnectionPoolModule.PROPS_MAX_CONNECTIONS)
.getContent()));
aDataSource.setUser(
(String)ref.get(SimpleConnectionPoolModule.PROPS_USER)
.getContent());
aDataSource.setPassword(
(String)ref.get(SimpleConnectionPoolModule.PROPS_PASSWORD)
.getContent());

return aDataSource;
30 CHAPTER 2. TRANSBASE JDBC EXTENSION PACKAGE

} else {
return null;
}
}
}

2.5 Data source properties

This chapter describes the properties available for Transbase data sources. The
properties can be changed by using the set and get methods of the transbase.
jdbcx.DataSource class. If a property is named ”property”, the set method would
be named ”setProperty” and the get method would be named ”getProperty”.
Property name Description
databaseName The name of a Transbase database. This is the
same name as used in the Transbase connect
string. (eg. db for db@hostname)
dataSourceName description
password The password used for a connection
portNumber The port number of the Transbase tbkernel ser-
vice (in most cases 2024)
serverName The host name of the machine running the
Transbase database
user A user name used for connections
escapeSyntax The escape syntax known from the core docu-
mentation 1.4.4
characterEncoding The character encoding known from core docu-
mentation 1.5.1

Das könnte Ihnen auch gefallen