I overrode the ActionServlet's initOther() method and put this code in
there:
// this code runs when the servlet gets initialized
DataSource ds =
this.findDataSource("org.apache.struts.action.DATA_SOURCE");
Database.setSystemDatabase(new Database(ds));
// now anywhere in the system you can call:
// Database db = Database.getSystemDatabase();
// Connection conn = db.getConnection();
The Database's getConnection() method just calls its internal DataSource's
getConnection method. The getSystemDatabase method does not instantiate a
new Database, it just returns the one you passed in the setter.
I've added some things to your implementation below:
>There's a couple of pieces missing in my understanding of this:
>
>1. How do you get hold of the DataSource of the ActionServlet subclass?
>Is this what getSystemDatabase() does? If so, then how?
>2. Am I right in assuming that the getSystemDatabase() method
>instantiates a new Database class, finds the DataSource, then sets a
>property with a reference to the DataSource?
>
>My initial attempt at an implementation of this goes something like this:
>
>package au.com.sunesis.timesheets;
>
>import javax.sql.DataSource;
>import java.sql.Connection;
>import java.sql.SQLException;
>
>public class Database {
> private DataSource dataSource;
> // keep copy of system database here
> private static Database systemDatabase = null;
>
> public Database(DataSource dataSource) {
> // who/what calls this constructor?
// the servlet's initOther() method
> this.dataSource = dataSource;
> }
>
> public static void setSystemDatabase(Database db) {
> systemDatabase = db;
> }
> public static Database getSystemDatabase() {
> // mysterious - what must go in here to make this work?
> // just return the database set with setSystemDatabase()
> return systemDatabase;
> }
>
> // let caller deal with SQLException, we don't know what to // do
>with it here
> public Connection getConnection() throws SQLException{
> return dataSource.getConnection();
> }
>}
>
>
>Thanks
>
>Steve
>
>---
>
>
>Here's how I do it:
>I defined a Database class with a constructor that takes a Datasource
>object. It also has a static getSystemDatabase() method and a
>getConnection
>
>method. I subclassed the struts ActionServlet and get ahold of its
>DataSource (defined in struts-config.xml) and pass it into my Database
>object. Then anywhere in the system I can call
>Database.getSystemDatabase().getConnection() to get a connection to the
>database.
>
>This also works outside of webapps because the Database class just knows
>about DataSources and not struts stuff. Also, this lets your logic beans
>not know about servlets or struts which is much cleaner in my opinion.
>
>Hope that helps,
>Dave
>
>-----Original Message-----
>From: Steve McLeod
>Sent: Monday, 2 September 2002 10:10 AM
>To: '[EMAIL PROTECTED]'
>Subject: Database Connection in Logic Beans - pooling?
>
>I am using:
>Tomcat 4.0
>Struts 1.0.2
>
>The problem
>========
>
>I have successfully used the Struts database connection pooling in a trial
>web app, but as far as I can tell, a reference to the datasource can only
>be
>obtained from within an Action class (or directly within a JSP page but
>let's not think about that today).
>
>However I would like to have logic beans which handle database access,
>rather than have this in the Action class. But I can't get a reference to
>the datasource from the logic bean because it doesn't have a ServletContext
>to which I can get a handle.
>
>I have toyed with various ideas:
>- Initialise a logic bean by passing it a reference to the Servlet
>- Acquire a connection in the Action class and pass that to the bean
>
>But really, I would rather the logic bean know inherently how to acquire a
>database connection.
>
>My current workaround is to not use the Struts connection pooling, and
>rather to manually create a connection each time database access needs to
>be
>done, then destroy it. But this is clearly not suitable for our production
>environment.
>
>
>The context of my problem
>==================
>
>I want to use some code like this in a JSP:
>
><jsp:useBean id="abean" scope="page"
>class="au.com.sunesis.timesheets.ClientManager" />
><table border="1">
> <tr>
> <th>#</th>
> <th>Client</th>
> <th>Active</th>
> </tr>
><logic:iterate id="clientList" name="abean" property="clients"
>type="au.com.sunesis.timesheets.Client">
> <tr>
> <td><bean:write name="clientList" property="clientID"/></td>
> <td><bean:write name="clientList" property="clientName"/></td>
> <td><bean:write name="clientList" property="active"/></td>
> </tr>
></logic:iterate>
>
>
>The idea is that ClientManager is used to handle all general database tasks
>for the Client bean (which maps to a Client entity in the database).
>ClientManager.getClients() connects to the database, creates an ArrayList
>of
>Client objects, one for each row in the database, and returns the
>ArrayList.
>
>ClientManager has other methods, such as:
>- ClientManager.delete(Client c), which deletes the row in the
>database entity corresponding to the specified client.
>- ClientManager.findByPrimaryKey(int ID) which returns the Client
>which matches the specified ID
>- ClientManager.save(Client c), which stores the client in the
>database, creating or updating as necessary
>
>So an Action class can also call any of these directly, and it really
>shouldn't care about how these work and how they store to/retrieve from the
>database. But I can't think of the elegant way to do this and still be able
>to use the Struts connection pooling.
>
>Any thoughts?
>
>Thanks
>
>Steve McLeod
>
>
>
_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>