<document>
  <header>
    <product>resin</product>
    <type>tutorial</type>
    <tutorial-startpage>basic</tutorial-startpage>
    <title>Using Dependency-Injection with JDBC Databases</title>
    <description>
    <p>This tutorial describes the standard pattern
for using a database in Resin, following the Dependency-Injection/Inversion-of-Control pattern using WebBeans annotations.</p>
    </description>
  </header>

  <body>
    <summary/>

<s1>
<p>Using a JDBC database is a three step process:</p>

<ul>
<li>Configuring the &lt;database&gt; in the resin-web.xml or resin.conf</li>
<li>Injecting the <code>DataSource</code> to a field with a <code>@javax.webbeans.Id</code> annotation.</li>
<li>Using a <code>Connection</code> from the <code>DataSource</code>
to execute the SQL.</li>
</ul>

<p>JDBC database access is based around the Factory pattern.
With JDBC, <code>javax.sql.DataSource</code> is the Factory object.
The &lt;database&gt; configures the <code>DataSource</code> and stores it
in the WebBeans directory.  The servlet will retrieve the
<code>DataSource</code> and use it as a factory to obtain
<code>Connection</code> objects, the main workhorse for using databases.</p>
</s1>

<s1 title="Files in this tutorial">
<deftable>
<tr>
  <td><viewfile-link file="WEB-INF/resin-web.xml"/></td>
  <td>resin-web.xml configuration</td>
</tr>
<tr>
  <td><viewfile-link file="WEB-INF/classes/example/BasicServlet.java"/></td>
  <td>The JDBC query servlet.</td>
</tr>
</deftable>
</s1>

<s1 title="Database Schema">

<example>
CREATE TABLE jdbc_basic_brooms (
  id INTEGER PRIMARY KEY auto_increment,

  name VARCHAR(128),

  cost INTEGER
);

INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('firebolt', 4000)
INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('nimbus 2001', 500)
INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('nimbus 2000', 300)
INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('cleansweep 7', 150)
INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('cleansweep 5', 100)
INSERT INTO jdbc_basic_brooms (name, cost) VALUES ('shooting star', 50)
</example>

</s1>

<s1 title="Database Configuration">

<p>In Resin 3.0, the &lt;database&gt; tag configures the database
pool and driver and saves the connection factory (DataSource) in
the Resin WebBeans directory.  WebBeans is an IoC (inversion-of-control)
configuration system, making it straightforward to separate resource
configuration from the application code.</p>

<p>The &lt;driver&gt; tag configures the database driver.  The database
vendor will make the driver classes available and describe the
configuration variables.  The <a href="doc|db-thirdparty.xtp">thirdparty database page</a> describes
several important database configurations.</p>

<p>The &lt;type&gt; tag is the most important driver configuration item.
It specifies the main Java driver class.  For many drivers, you will
have a choice of different drivers following different internal JDBC
APIs.  If you have a choice, you should try the drivers in the
following order, after checking your database vendor's recommendations:</p>

<ol>
<li>JCA - Java Connection Architecture - this is a common driver
interface for more than just JDBC.  If possible, it's generally the
best to choose.</li>
<li>ConnectionPoolDataSource - JDBC driver which has extra hooks to
help Resin pool the connections.</li>
<li>Driver - old-style JDBC driver.  Its main benefit is that it's
generally always available as a fallback.</li>
</ol>

<example>
&lt;web-app xmlns="http://caucho.com/ns/resin"&gt;
  &lt;database jndi-name="jdbc/basic"&gt;
    &lt;driver type="com.caucho.db.jca.ConnectionFactory"&gt;
      &lt;url&gt;resin:WEB-INF/db&lt;/url&gt;
    &lt;/driver&gt;
  &lt;/database&gt;
&lt;/web-app&gt;
</example>

<p>The &lt;url&gt; specifies the location of the database. Each
database driver will have a unique URL formal.  In this case,
the &lt;url&gt; specifies a directory for the database files.  Other
databases may specify a host and port.</p>

<s2 title="com.caucho.db.jca.ConnectionFactory">

<p>The specific driver for this example,
<code>com.caucho.db.jca.ConnectionFactory</code> is a simple database
intended for examples and testing.</p>

</s2>

</s1>

<s1 title="Servlet Initialization">

<p>The servlet is configured with a <code>DataSource</code> to
access JDBC.  Resin allows two styles of configuration: Dependency Injection
using WebBeans injection and standard servlet &lt;init-param&gt;
configuration with JNDI lookups.  The Dependency Injection style is
simpler, cleaner and makes the application more testable and robust.</p>

<example>
import javax.webbeans.In;

public class BasicServlet extends HttpServlet {
  @In private DataSource _ds;

  ...
}
</example>

<s2 title="Dependency Injection configuration">

<p>Using dependency injection to configure servlets has some advantages
over the init-param method:</p>

<ol>
<li>The configuration is type-safe.  Resin's dependency injection will
check the DataSource type before injecting the value.  Resin will also
inform you of any conflicts, e.g. configuration of multiple matching
databases.</li>
<li>The servlet initialization code is simpler.
The servlet doesn't need JNDI code.</li>
<li>The configured values can be more complicated than the string-limitation of &lt;init-param&gt;.</li>
<li>The DataSource itself isn't tied to JNDI, although JNDI will certainly
remain the primary registry.
</li></ol>

<p>Enabling the Dependency Injection pattern is trivial: just
add the <code>@javax.webbeans.In</code> annotation to your
<code>DataSource</code> field.</p>

<example title="resin-web.xml">
&lt;servlet servlet-name="my-servlet"
         servlet-class="example.BasicServlet"&gt;
&lt;/servlet&gt;
</example>

</s2>

</s1>

<s1 title="Using the Database">

<p>The most important pattern when using JDBC is the
following try/finally block.  All database access should follow this pattern.
Because connections are pooled, it's vital to close the connection no
matter what kind of exceptions may be thrown   So the
<code>conn.close()</code> must be in a finally block.</p>

<example title="Connection try ... finally block">
Connection conn = _ds.getConnection();
try {
  ...
} finally {
  conn.close();
}
</example>

<p>The full example splits the database access into two methods to
clarify the roles.  The <code>service</code> retrieves the output
writer from the servlet response and wraps any checked exceptions
in a <code>ServletException</code>.  Splitting the servlet method
simplifies the <code>doQuery</code> method, so it can concentrate
on the database access.</p>

<example>
public void service(HttpServletRequest req, HttpServletResponse res)
  throws java.io.IOException, ServletException
{
  PrintWriter out = res.getWriter();

  try {
    doQuery(out);
  } catch (SQLException e) {
    throw new ServletException(e);
  }
}

private void doQuery(PrintWriter out)
  throws IOException, SQLException
{
  Connection conn = _ds.getConnection();

  try {
    String sql = "SELECT name, cost FROM jdbc_basic_brooms ORDER BY cost DESC";
      
    Statement stmt = conn.createStatement();

    ResultSet rs = stmt.executeQuery(sql);

    out.println("&lt;table border='3'&gt;");
      
    while (rs.next()) {
      out.println("&lt;tr&gt;&lt;td&gt;" + rs.getString(1));
      out.println("    &lt;td&gt;" + rs.getString(2));
    }

    out.println("&lt;/table&gt;");
      
    rs.close();
    stmt.close();
  } finally {
    conn.close();
  }
}
</example>

</s1>

<s1 title="See also">

<ul>
  <li><a href="doc|config-database.xtp">Database configuration</a> reference</li>
  <li><a href="doc|db-thirdparty.xtp">Sample configurations</a> for several database drivers</li>
  <li>Using <a href="../db-jdbc-ioc/index.xtp">Dependency Injection for Databases</a></li>
  <li>The <a href="../ioc-injection/index.xtp">Dependency Injection</a> (or Assembly Line) pattern.</li>
</ul>

</s1>

  </body>
</document>
