DAO Class size
Hi,
I am using the DAO pattern in the data tier of an app. I am writing.
The DAO Im using to represent customers is CustomerDAO.
The trouble is, I have quite a few operations in the CustomerDAO and the class is getting too large to manage. ie. findCustomer, updateCustomer, insertCustomer etc. etc.
Have I misunderstood the pattern or is this a familiar problem? What is the best way to fix it? Should I try and split CustomerDAO into more DAO's or encapsulate the behaviours?
Adam
[519 byte] By [
adamreida] at [2007-10-3 2:47:14]

> Hi,
>
> I am using the DAO pattern in the data tier of an
> app. I am writing.
>
> The DAO Im using to represent customers is
> CustomerDAO.
>
> The trouble is, I have quite a few operations in the
> CustomerDAO and the class is getting too large to
> manage. ie. findCustomer, updateCustomer,
> insertCustomer etc. etc.
three methods is large?
I'd envision that interface looking like this:
package dao;
public interface CustomerDao
{
public List<Customer> findAll();
public Customer findById(Long id);
public List<Customer> findByLastName(String lastName);
public void saveOrUpdate(Customer c);
public void delete(Customer c);
}
The number of methods = # of finders + 2
What's the problem? You've gotta implement CRUD ops, which means 3 or 4 at a minimum.
Sounds like you've misunderstood the pattern.
%
Im talking about the implementation of the interface you have described.ie. all of the SQL, looping through resultsets etc.
Normally my longest classes are DAOs. But how long are we talking about?There might be several ways to break up the code into other objects and methods.Maybe you could post some of the code?
zadoka at 2007-7-14 20:36:00 >

> Im talking about the implementation of the interface
> you have described.
>
> ie. all of the SQL, looping through resultsets etc.
This is where good plumbing really helps.
If you're talented with SQL, Java, and JDBC, you can help yourself by writing some framework code to handle the repetitive tasks for you. After you've written enough JDBC you'll notice that the code keeps repeating itself:
(1) Obtain necessary resources
(2) Execute SQL
(3) If DML, return # of affected rows; if DQL, map ResultSet to return object
(4) Close resources
You can write some classes that will minimize the amount of repetitive code you have to write.
If you're not as talented as Rod Johnson, you can use the JDBC plumbing that he wrote in Spring. You'll be amazed to see how clean and small those methods become.
http://www.springframework.org
%
> Normally my longest classes are DAOs.
Those are my shortest, thanks to Spring and Hibernate. Usually 1 line per method, never more than 10.
> But how long
> are we talking about?There might be several ways
> to break up the code into other objects and methods.
Indeed. Start thinking about either writing your own JDBC scaffolding or using something good like Spring.
>Maybe you could post some of the code?
Maybe not...
%
This is one of the methods on the DOA. I have a few of these operations so yuo can see the class gets big quicky. I cant alter the SQL as its all procedures.
There will also be others that return data so I will to loop over a Recordset too.
How about just static classes holding the SQL and the binding operations?
public void addBasicApplication(ApplicantVO app) throws SQLException {
logger.info("addBasicApplication() :"+applicantVO);
Connection con = DAOFactory.createConnection();
CallableStatement cs = null;
SqlAction action = null;
try {
action = SqlActionFactory.findAction(SqlActionFactory.INSERT_BASIC);
String sql = "{CALL usp_encrypt_str(?,?)}";
cs = con.prepareCall(sql);
cs.setString(1, app.getTitle());
cs.setString(2, app.getFirstName());
cs.setString(3, app.getLastName());
cs.setString(4, app.getDateOfBirth());
cs.setString(5, app.getWebLogonName());
cs.setString(6, app.getWebPassword());
cs.setString(7, app.getEmailAddress());
cs.setString(8, app.getCostCentre());
cs.setString(9, "");
cs.setString(10, "");
cs.setString(11, app.getNI());
cs.registerOutParameter(12, Types.INTEGER);
cs.setString(13, "");
cs.setInt(14, app.getAgencyId().intValue());
cs.setString(15, app.getPreferredContact());
cs.getString("@test");
logger.info("executing query: "+sql);
cs.executeUpdate();
} catch (IllegalAccessException iaex){
logger.severe(iaex.getMessage());
} catch (InstantiationException iex){
logger.severe(iex.getMessage());
}
}
> This is one of the methods on the DOA. I have a few
> of these operations so yuo can see the class gets big
> quicky. I cant alter the SQL as its all procedures.
>
> There will also be others that return data so I will
> to loop over a Recordset too.
Better plumbing will help.
> How about just static classes holding the SQL and the
> binding operations?
Not sure how to answer. Some things can be static, others should not.
I see a couple of problems with this codeL
(1) You create the Connection right in the method. You can't participate in a transaction (perhaps not a problem, since this is a query). I'd pass it into the method or inject it.
(2) No closing of ANY resources that I can see.
(3) SQLException still leaves the user with a lot of work to figure out what when wrong. Spring maps database error codes to more expressive runtime exceptions. I think that's helpful.
%