<?xml version="1.0"?>

<document url="./database.xml">

 <properties>
   <author>Craig R. McClanahan</author>
    <author>Mike Schachter</author>
    <author>Ted Husted</author>
    <author>Martin Cooper</author>
    <author>Ed Burns</author>
    <author>Anthony Kay</author>
  <title>Accessing a Database</title>
 </properties>

<body>
<chapter href="actionForm" name="How to Access a Database">

<section name="Accessing a Database" href="database">

    <p>
    Most developers would consider accessing a database part of the "business
    end" of an application. Most often, we don't access a databse for the sake
    of accessing a database. We use the database as part of a larger business
    transaction. So lets start with accessing business logic from Struts.
    </p>

    <p>
    The best thing is use the Action as a thin adaptor between the
    web/presentation-tier and your business classes (including those that
    access a database).
    </p>

    <p>
    So you first design a business API that uses plain Java classes.
    The best thing is to use objects that take ordinary Java types and return
    a JavaBean or collection of JavaBeans.
    The Action then calls these objects and passes the result back to the
    web/presentation tier.
    </p>

    <p>
    A common approach is to create an Action class for each of business
    transaction, or use case, in your application. A simple "CRUD"
    application might have a CreateAction, a RetrieveAction, an UpdateAction,
    and a DeleteAction. To complete each transaction, the Action can make
    whatever calls are needed to your business API classes.
    </p>

    <p>
    Ideally, all the database access code should be encapsulated behind the
    business API classes, so Struts doesn't know what persistent layer you
    are using (or even if there is a persistence layer).
    It just passes a key or search String and gets back a bean or collection
    of beans.
    This lets you use the same business API classes in other environments,
    and also to run unit tests against your business API outside of Struts or
    a HTTP environment.
    </p>

    <p>
    The MailReader example application bundled with Struts demonstrates
    how this is usually done. The MailReader uses the DAO (Data Access Object)
    pattern to separate the persistence layer from the (Struts) control layer.
    MailReader defines a DAO interface that the Actions can call, it then
    defines a implementation that uses a database stored in main memory.
    Other implementations could be defined and used instead, without
    changing any of the Struts Action classes.
    </p>

    <p>
    To get started, it's simplest to setup a 1:1 correspondence between the
    Actions and your application's use cases. Each use case may make one or
    more calls to your business API, but from the user's perspective, each
    use case is a single transaction.
    </p>

    <p>
    As you gain experience, you will find ways to combine your Action classes,
    say by using the DispatchAction.
    It's even possible to use a single "framework" Action to call all of your
    business classes, as is done with Scaffold ProcessAction in the contrib
    folder.
    </p>

    <p>
    Using fewer Actions does require a deeper understanding of how Struts and
    MVC frameworks operate.
    Don't hesitate to err on the side of creating more Action classes at first.
    The Struts configuration makes it easy to refactor your Actions later,
    since you can change the Action type without changing anything else in the
    application.
    </p>

    </section>

    <section name="Using DataSources" href="datasources">

    <p>
    When you use the DAO approach, all of the database access details are
    hidden behind the business interface. The implementation of the business
    classes handle all the gritty details, like using a <code>DataSource</code>
    to pool connections to the database.
    </p>

    <p>
    As a rule, you should always use a connection pool to access a database.
    The <code>DataSource</code> interface is the preferred way to implement a
    connection pool today. Many containers and database systems now bundle
    a DataSource implmentation that you can use. Most often, the DataSource
    is made available through JNDI. The JNDI approach makes it easy for your
    business classes to access the DataSource without worrying about who set it
    up.
    </p>

    </section>

    <section name="Persistence Franeworks" href="persistence">

    <p>
    There are many useful and mature persistence layer frameworks available.
    Before using raw JDBC or "rolling your own" solution, you should carefully
    review one or more of these packages. Here's a short list of packages
    most often mentioned on the Struts User list:
    </p>

    <ul>
        <li><a href="http://www.hibernate.org/">Hibernate</a></li>
        <li><a href="http://sourceforge.net/projects/ibatisdb">iBATIS</a></li>
        <li><a href="http://db.apache.org/ojb/">Object Relational Bridge</a></li>
        <li><a href="http://db.apache.org/torque/index.html">Torque / Peers</a></li>
    </ul>

    <p>
    For more, see the
    <a href="http://struts.sourceforge.net/community/models.html">Struts
    Community Resources area</a> on SourceForge.
    </p>

    </section>

    <section name="The Struts DataSource Manager" href="manager">

    <p>
    Ideally, the business logic layer should encapsulate the data access
    details, including acquiring a database connection.
    However, some older application designs expect that the caller be able to
    provide a database connection or DataSource instance.
    When you need to access a legacy design, the Struts DataSource manager can
    make it easy for your Action class to produce these resources on demand.
    </p>

    <p>
    <strong>NOTE:</strong> It is preferred that data connectivity be handled
    directly by the business classes, usually via JNDI. The Struts DataSource
    manager should only be used with legacy business classes that don't provide
    their own  connectivity. When possible, we <b>strongly</b> recommend use of
    the standard DAO pattern, so that the Action classes do not need to know
    anything about the persitence mechanism. <strong>The DataSource manager is being
    retained in Struts 1.x for backward compatibility but may not be retained
    in Struts 2.x or later.</strong>
    </p>

    <p>
    The Struts DataSource manager is configured as an element in the
    <a href="../userGuide/configuration.html#data-source_config">
    Struts configuration file</a> (struts-config.xml).
    The manager can be used to deploy any connection pool that implements the
    <code>javax.sql.DataSource</code> interface and is configurable totally
    from JavaBean properties.
    If your DBMS or container provides a connection pool that meets these
    requirements, then that component might be your first choice.
    </p>

    <p>
    The Jakarta Commons dbcp's BasicDataSource
    [<code>org.apache.commons.dbcp.BasicDataSource</code>] also works well
    with the DataSource manager, if a native component is not available.
    DBCP is not supplied as part of the Struts distribution. You can obtain 
    it from <a href="http://jakarta.apache.org/commons/dbcp/downloads.html">
    Commons DBCP</a>.
    </p>
    
    <p>
    <strong>Note:</strong> The Generic DataSource which was included with previous 
    versions of Struts has been removed as of release 1.2.0 in favor of 
    plugging in the BasicDataSource, or another DataSource implementation.
    </p>

    <p>
    This is how you would specify a DBCP BasicDataSource for your application:
    </p>

<pre><code><![CDATA[
<data-sources>
<!-- configuration for commons BasicDataSource -->
<data-source type="org.apache.commons.dbcp.BasicDataSource">
    <set-property
      property="driverClassName"
      value="org.postgresql.Driver" />
    <set-property
      property="url"
      value="jdbc:postgresql://localhost/mydatabase" />
    <set-property
      property="username"
      value="me" />
    <set-property
      property="password"
      value="test" />
    <set-property
      property="maxActive"
      value="10" />
    <set-property
      property="maxWait"
      value="5000" />
    <set-property
      property="defaultAutoCommit"
      value="false" />
    <set-property
      property="defaultReadOnly"
      value="false" />
    <set-property
      property="validationQuery"
      value="SELECT COUNT(*) FROM market" />
</data-source>
</data-sources>
]]></code></pre>

    <p>
    Note that you can define as many datasource objects as your application
    requires and refer to each using a logical name.
    This can be useful in providing better security or scalability, or even
    to test datasource implementations against each other.
    </p>

    <p>
    After a DataSource is defined, here is an example of using the
    manager to establish a connection from within an Action's
    <code>execute</code> method.
    </p>

<pre><code>
public ActionForward
       execute(ActionMapping mapping,
               ActionForm form,
               HttpServletRequest request,
               HttpServletResponse response) throws Exception
{
 javax.sql.DataSource dataSource;
 java.sql.Connection myConnection;
 try {
  dataSource = getDataSource(request);
  myConnection = dataSource.getConnection();
  // do what you wish with myConnection
 } catch (SQLException sqle) {
    getServlet().log("Connection.process", sqle);
 } finally {
    //enclose this in a finally block to make
    //sure the connection is closed
    try {
       myConnection.close();
    } catch (SQLException e) {
       getServlet().log("Connection.close", e);
    }
   }
}
</code></pre>

    <p>
    <em>Note: If you use the Commons BasicDataSource with Struts,
    the query you provide for the pingQuery attribute (if you choose to
    include it) must return at least one row.</em>
    </p>

    <p>
    <strong>Example:</strong> <code>SELECT COUNT(*) FROM VALIDTABLE</code>
    </p>

    <p>
    Just be sure you to replace "VALIDTABLE" with the name of a valid table
    in your database.
    </p>

</section>

<section name="Using Multiple Datasources" href="multi_dsrc">
    <p>
    If you need more than one data source in a module, you can include a key
    attribute in the data-source element:
    </p>
<pre><code><![CDATA[
<data-sources>
   <data-source key="A" type="org.apache.commons.dbcp.BasicDataSource">
      ... properties as before ...
   </data-source>
   <data-source key="B" type="org.apache.commons.dbcp.BasicDataSource">
      ... properties as before ...
   </data-source>
   ...
</data-sources>
]]></code></pre>

    <p>
    Which can then be accessed by including the key ("A" in this case) as an
    additional parameter to the Action.getDataSource() method.
    </p>

<pre><code>
   ...
   try {
      dataSourceA = getDataSource(request, "A");
      dataSourceB = getDataSource(request, "B");
   ...
</code></pre>

    <p>
    Each module can have as many data sources as it needs. The keys only
    need to be unique within a module since the struts module system maintains
    a name space for the items in each module to protect you from name
    clashes.
    </p>
 </section>

<section href="more" name="See Also">

    <p>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24621.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24621.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24709.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24709.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24626.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24626.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24331.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24331.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24102.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24102.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23501.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23501.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23455.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23455.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23375.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23375.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23321.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23321.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23098.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23098.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg22713.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg22713.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21974.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21974.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21026.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg21026.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg18323.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg18323.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14975.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14975.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14914.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14914.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14435.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg14435.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg01562.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg01562.html</a>
    </p>

    <p>
    Transformation/Data Transfer<br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24480.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg24480.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23623.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg23623.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10195.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10195.html</a><br/>
    <a href="http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10205.html">http://www.mail-archive.com/struts-user@jakarta.apache.org/msg10205.html</a>
    </p>

</section>


<section href="DynaResultSet" name="Rendering a dynamic result set">

    <p>
        The result of most queries will map to the ActionForms you are already using,
        and so you can render the ResultSet as a collection of ActionForms.
        But sometimes there are columns in a ResultSet that are not properties of an ActionForm,
        or even known in advance.
    </p>

    <p>
        Happily, the Struts tags don't care what type of bean you use with them.
        You could even output a ResultSet directly.
        But a ResultSet retains a connection to the database, and passing "all that" directly to a JSP gets messy.
        So what's a developer to do?
    </p>

    <p>
        Since Struts 1.1, the simplest option is to use a
        <a href="http://jakarta.apache.org/commons/beanutils/api/org/apache/commons/beanutils/ResultSetDynaClass.html">ResultSetDynaClass</a>
        to transfer the ResultSet into an ArrayList of DynaBeans.
        The Struts custom tags can use DynaBean properties as easily as they use conventional JavaBean properties.
        (See <strong>DynaActionForm classes</strong> in the Struts User Guide for details.)
    </p>

    <p>
        Since this is in the BeanUtils jar, you already have it on board, and just need to implement the transfer routine
        (see the ResultSetDynaClass link).
    </p>

</section>

</chapter>
</body>
</document>

