commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Harish Krishnaswamy <hkrishnasw...@comcast.net>
Subject Re: [HiveMind] Question about DAO creation
Date Fri, 03 Oct 2003 14:12:37 GMT
Here's what I have done in my project, I am using iBatisDB and I love 
it, I suppose you can do the same with JDBC too.

I have a super DataAccessService...

public class DataAccessServiceImpl implements DataAccessService, 
Initializable
{
    // This will be a configuration provided in the module descriptor
    // In JDBC, this will probably be the JNDI path to the DataSource
    public void setResourcePath(String path)
    {
        _resourcePath = path;
    }

    // This is used to build the SqlMap, kind of registry for all sql 
statements.
    // In a plain JDBC env, this is probably where I would get the 
DataSource (from JNDI typically) and store it locally.
    public void initializeService(Object service)
    {
        try
        {
            Reader reader = Resources.getResourceAsReader(_resourcePath);
            _sqlMap = XmlSqlMapBuilder.buildSqlMap(reader);
            reader.close();
        }
        catch (Exception ex)
        {
            throw new ApplicationRuntimeException("Error Initializing 
DAS :" + ex);
        }
    }

    // Generic statement executions
    public List getList(String statementName, Object parameterObject) 
throws DaoException
    {
       // executeQuery()
    }

    public Object getObject(String statementName, Object 
parameterObject) throws DaoException
    {
       // executeQuery()
    }

    public int update(String statementName, Object parameterObject) 
throws DaoException
    {
       // executeUpdate()
    }
}

And I have other DataAccess services compose the super DataAccessService 
which will be provided by HiveMind as specified in the module descriptor.

For example...

public class ClientDASImpl implements ClientDAS
{
    private DataAccessService _das;
   
    public void setDataAccessService(DataAccessService das)
    {
        _das = das;
    }
   
    public List getClients()
    {
        List list = null;
       
        try
        {
            list = _das.getList("getClients", new Client());
        }
        catch (DaoException e)
        {
            throw new ApplicationRuntimeException(e);
        }
       
        return list;
    }
}

And what I store in the Global is just the registry. That's one thing I 
noticed in your code, you seem to be building the registry eveytime a 
service is requested. Here my Global...

public class Global
{
    private Registry _registry;

    public Global()
    {
        ClassResolver resolver = new DefaultClassResolver();
        RegistryBuilder builder = new RegistryBuilder();

        builder.processModules(resolver);

        _registry = builder.constructRegistry(Locale.getDefault());
    }

    public LookupService getLookupService()
    {
        return (LookupService) 
_registry.getService(ServiceTokens.LOOKUP, LookupService.class);
    }
    ...
}

I use DBCP for DB connection pooling, that way you externalize all the 
connection stuff out of the service.

I hope this will be helpful. If you need more info, I will be glad to 
provide what ever I can.

-Harish


Bill Lear wrote:

>I've been using hivemind to build a DAO factory.  I think I may be
>using this in a rather crude way that undoes some of the good hivemind
>has done, so I thought I'd ask for some advice.  I have a second question
>regarding JDBC connections.
>
>First, in Tapestry, I store my DAO object in the Global class, but
>I seem to have reverted to the singleton pattern instead of
>doing things the hivemind way:
>
>public class Global {
>    private static DAO dao;
>
>    private static Object daoMutex = new Object();
>
>    public DAO getDAO() throws DAOException {
>        synchronized (daoMutex) {
>            if (dao == null) {
>                dao = createDAO();
>            }
>        }
>        return dao;
>    }
>
>    private DAO createDAO() throws DAOException {
>        DAOFactory f = (DAOFactory) Services.getService(DAOFactory.class);
>        return f.createDAO();
>    }
>}
>
>Services is a wrapper around Hivemind that gets a service based on a
>class name:
>
>public class Services {
>    public static Object getService(Class theClass) {
>        ClassResolver resolver = new DefaultClassResolver();
>        RegistryBuilder builder = new RegistryBuilder();
>
>        builder.processModules(resolver);
>
>        Registry registry = builder.constructRegistry(Locale.getDefault());
>
>        return registry.getService(theClass.getName(), theClass);
>    }
>}
>
>My hivemodule looks like this:
>
><module id="com.foobar.eci.dao" version="1.0.0">
>    <service-point id="DAOFactory"
>                   interface="com.foobar.eci.dao.DAOFactory">
>        <invoke-factory service-id="hivemind.BuilderFactory">
>            <construct
>	        class="com.foobar.eci.dao.mysql.MySQLDAOFactory">
>                <set property="name" value="eci"/>
>                <set property="protocol" value="mysql"/>
>                <set property="driver"
>		     value="org.gjt.mm.mysql.Driver"/>
>                <set property="host" value="localhost"/>
>                <set property="port" value="3906"/>
>                <set property="user" value="bogon"/>
>                <set property="password" value="foobar"/>
>            </construct>
>        </invoke-factory>
>    </service-point>
></module>
>
>I'm not quite sure how to have hivemind construct both the Global
>object and DAO object, and set the DAO object in the Global object.
>
>
>Second question: I use a command pattern to separate the implementation of
>different methods in the DAO class.  So, if I have a DAO that looks like
>this:
>
>public interface DAO {
>    Employee getEmployee(Integer employeeID) throws DAOException;
>
>    Employee[] getEmployees(String sortColumn) throws DAOException;
>
>    void insertEmployee(Employee employee) throws DAOException;
>}
>
>I implement this with a class to expose this interface, and three
>classes to implement each of the commands.  Notice the MySQLDAO
>class stores the JDBC connection object and passes it to each
>of the command classes it constructs:
>
>public class MySQLDAO implements DAO {
>    void init(Connection connection) throws DAOException {
>        try {
>            getEmployee = new GetEmployee(connection);
>            getEmployees = new GetEmployees(connection);
>            insertEmployee = new InsertEmployee(connection);
>        } catch (SQLException sex) {
>            LOG.error(sex.toString());
>            throw new DAOException(sex.toString());
>        }
>    }
>
>    private GetEmployee getEmployee;
>
>    public Employee getEmployee(Integer employeeID) throws DAOException {
>        return getEmployee.execute(employeeID);
>    }
>
>    private GetEmployees getEmployees;
>
>    public Employee[] getEmployees(String sortColumn) throws DAOException {
>        return getEmployees.execute(sortColumn);
>    }
>
>    private InsertEmployee insertEmployee;
>
>    public void insertEmployee(Employee employee) throws DAOException {
>        insertEmployee.execute(employee);
>    }
>}
>
>The factory is what I have Hivemind creating:
>
>public class MySQLDAOFactory implements DAOFactory {
>    private String name;
>    private String protocol;
>    private String driver;
>    private String host;
>    private String port;
>    private String user;
>    private String password;
>
>    public DAO createDAO() throws DAOException {
>        MySQLDAO dao = new MySQLDAO();
>
>        try {
>            String connURL = "jdbc:" + protocol + "://";
>
>            if (host.length() == 0) {
>                connURL += name;
>            } else {
>                connURL += host + ":" + port + "/" + name;
>            }
>
>            // This ensures no timeouts for MySQL after default idle period
>            connURL += "?autoReconnect=true";
>
>            Class.forName(driver);
>            dao.init(DriverManager.getConnection(connURL, user, password));
>        } catch (SQLException sex) {
>            throw new DAOException(sex);
>        } catch (ClassNotFoundException ex) {
>            throw new DAOException(ex);
>        }
>
>        return dao;
>    }
>
>    // Get-Set methods for private variables elided ...
>}
>
>So, what I'm wondering is: I have embedded a JDBC connection object in
>the each of the three command objects.  This seems too direct and
>inflexible, but I don't know what other alternatives to use.  Also, I
>would like to be able to unit-test each of the three command classes,
>but I would prefer to be able to use hivemind to construct the JDBC
>connection for me, in which case, I might re-factor things in the
>MySQLDAO class itself to also take advantage of hivemind to get the
>connection object (but then, what about pooling?  Can hivemind create
>a JDBC connection?  Is this desirable?).
>
>Finally, when testing the DAO, I need to be able to clear the database
>before each test case method is run.  I would prefer to use the same
>connection that the DAO has, but exposing that in the DAO interface
>seems a bit lame (Connection getConnection()) and too concrete.
>
>In any case, if anyone has comments or suggestions to share on managing
>JDBC connections, I'd appreciate it.
>
>
>Bill
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
>For additional commands, e-mail: commons-dev-help@jakarta.apache.org
>
>
>  
>


---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message