blob: 6347a71e2e8130ce39233b97693855ed49fe9ebb [file] [log] [blame]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Using Databases in Apache Cocoon</title>
<link href="http://purl.org/DC/elements/1.0/" rel="schema.DC">
<meta content="Berin Loritsch" name="DC.Creator">
</head>
<body>
<h1>How do I choose my database?</h1>
<p>
Apache Cocoon is flexible in the way it allows you to make connections to
a database. There are basically two ways: by redefining all the connection
parameters in each page you use a database, or using a pooled connection.
The first method is slow and doesn't scale well. The second method is more
scalable, and depending on your database will realize true improvements.
</p>
<h2>Installing the Driver</h2>
<p>
Independent of how you choose to get and maintain your JDBC connections,
you have to load the driver so Cocoon can use it (unless you are using
a J2EE container--more on that later). This is an init parameter in
your web.xml file. The following snippet will show you how:
</p>
<pre class="code">
&lt;init-param&gt;
&lt;param-name&gt;load-class&lt;/param-name&gt;
&lt;param-value&gt;
&lt;!-- For PostgeSQL Database: --&gt;
postgresql.Driver
&lt;!-- For Oracle Database: --&gt;
oracle.jdbc.driver.OracleDriver
&lt;/param-value&gt;
&lt;/init-param&gt;
</pre>
<p>
You can place as many Driver classes in this parameter you want. They
are separated by white space or commas.
</p>
<h2>Defining a Data Source</h2>
<p>
Cocoon allows you to specify a pooled data source that you can use
for throughout the Cocoon system. There are two different types of
data sources: JDBC and J2EE. The difference is in who controls the
connection. The JDBC data source lets Cocoon handle all the pooling
logic. The J2EE data source tells Cocoon how to pull the DataSource
object from a J2EE container (thats Java 2 Enterprise Edition)--the
major caveat is that Cocoon must be installed as part of a Enterprise
Application.
</p>
<p>
The following snippet of cocoon.xconf shows the section where the
DataSourceComponent is specified. You can have more than one in
this location. The code will have one connection for the JDBC data
source, and one connection for the J2EE data source.
</p>
<pre class="code">
&lt;datasources&gt;
&lt;jdbc name="MyConnectionName"&gt;
&lt;pool-controller min="5" max="10"/&gt;
&lt;dburl&gt;jdbc:oracle:thin:@localhost:1521:mydatabase&lt;/dburl&gt;
&lt;user&gt;mylogin&lt;/user&gt;
&lt;password&gt;myPassword&lt;/password&gt;
&lt;/jdbc&gt;
&lt;j2ee name="MyJ2eeConnection"&gt;
&lt;dbname&gt;cocoonDB&lt;/dbname&gt;
&lt;/j2ee&gt;
&lt;/datasources&gt;
</pre>
<h3>The JDBC Connection Properties</h3>
<p>
The JDBC connection has up to five different properties--but only one
is absolutely required.
</p>
<ul>
<li>
dburl: This is absolutely required. Without it JDBC can't connect
to the database.
</li>
<li>
user: This is only required if the database admin requires you to
log in to the database.
</li>
<li>
password: This is only required if the database admin requires a
password to connect to the database.
</li>
<li>
pool-controller: This has two parameters with defaults. If it is
not specified, the defaults are used.
<ul>
<li>
min: The minimum number of connections the pool will keep
available at one time. Defaults to zero (0).
</li>
<li>
max: The maximum number of connections the pool will have
created at the same time. Defaults to three (3).
</li>
<li>
oradb: If you have an Oracle database, you should add the attribute
"oradb" and set it to true.
</li>
</ul>
</li>
<li>
auto-commit: If you need to ensure an autocommit is set to true or
false, then create the "auto-commit" element.
</li>
</ul>
<h3>The J2EE Connection Property</h3>
<p>
The J2EE connection has only one property and it is absolutely
required. Cocoon uses JNDI to look up the DataSource with the
name you specified in "dbname".
</p>
<h2>Using the Data Source Component</h2>
<p>
No matter how you defined your DataSourceComponent, you access
it the same way. Because The DataSourceComponent is a Component,
your class needs to implement the Avalon Serviceable interface. The
Avalon Framework will give your class a ServiceManager. At that
point, it is up to you how and when you pull the DataSourceComponent
out of the ServiceManager.
</p>
<pre class="code">
import org.apache.avalon.framework.service.ServiceManager;
import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.cocoon.Roles;
import org.apache.avalon.excalibur.datasource.DataSourceComponent;
import java.sql.Connection;
// .... Skip a lot of lines until we are in the method you use
// to initialize the DataSourceComponent ....
private DataSourceComponent datasource;
public void service(ServiceManager manager) {
ServiceSelector selector =
(ServiceSelector) manager.lookup(Roles.DB_CONNECTION);
this.datasource = (DataSourceComponent) selector.select("MyConnectionName");
}
// .... Skip more lines until we actually need to use the datasource
private void meMethod() {
Connection myConnection = this.datasource.getConnection();
// .... perform SQL code here
myConnection.close();
}
</pre>
<p>
Notice that once you obtained your connection, you did nothing out of the
ordinary to return the connection to the pool? This is by design, and a
result of the JDBC specification. Basically the JDBC specification states
that if a driver implements pooled connections, then it should not alter
the way those connections are used. This maintains the portability of
your code.
</p>
</body>
</html>