开发者

Is there a proper way to instantiate strongly typed objects in DAOs?

I'm trying to determine which is the right way to code a DAO for a class that contains a few primitive data types, and three strongly typed objects which have DAOs of their own.

Here's the class I'm implementing the DAO for, minus the getters/setters:

public class Course
{
    private int id;
    private int number;
    private String title;
    private Subject subject;
    private School school;
    private Instructor instructor;
    ...
}

The Subject, School, and Instructor classes all have DAOs of their own. So my initial thought was to use those DAOs to instantiate the Subject, School, and Instructor objects in the Course object (relevant code is in the try block):

public class CourseDAO
{
    public static Course selectCourse(int id)
    {
        ConnectionPool cp = ConnectionPool.getInstance();
        Connection c = cp.getConnection();
        PreparedStatement ps = null;
        ResultSet rs = null;

        Course course = null;

        String query = "select id, number, title, subjectId, schoolId, instructorId " +
                "from course " +
                "where id = ? " +
                "limit 1";

        try
        {
            ps = c.prepareStatement(query);
            ps.setInt(1, id);
            rs = ps.executeQuery();
            if (rs.next())
            {
                course = new Course();
                course.setId(rs.getInt(1));
                course.setNumber(rs.getInt(2));
                course.setTitle(rs.getString(3));
                course.setSubject(SubjectDAO.selectSubject(rs.getInt(4)));
                course.setSchool(SchoolDAO.selectSchool(rs.getInt(5)));
                course.setInstructor(InstructorDAO.selectInstructor(rs.getInt(6)));
            }
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        finally
        {
            DBUtil.closeResultSet(rs);
            DBUtil.closePreparedStatement(ps);
            cp.releaseConnection(c);
        }

        return course;
    }
}

The other DAOs look very similar to this one. Each gets a Connection from the ConnectionPool, uses a PreparedStatement to execute a simple query, closes the ResultSet and PreparedStatement, and releases the Connection back into the pool.

After implementing CourseDAO this way, I began to wonder if it would be better/more efficient to use a join in the query instead of calling SubjectDAO, SchoolDAO, and InstructorDAO, since each one use a Connection from the ConnectionPool. The query and try block would change as follows:

String query = "select course.id, course.number, course.title, " +
        "subject.id, subject.name, " +
        "school.id, school.name, school.abbreviation, school.type, school.city, school.region, school.country, " +
        "instructor.id, instructor.firstName, instructor.lastName " +
        "from course " +
        "inner join subject " +
        "on course.subjectId = subject.id " +
        "inner join school " +
        "on course.schoolId = school.id " +
        "inner join instructor " +
        "on course.instructorId = instructor.id " +
        "where course.id = ? " +
        "limit 1";

try
{
    ps = c.prepareStatement(query);
    ps.setInt(1, id);
    rs = ps.executeQuery();
    if (rs.next())
    {
        course = new Course();
        course.setId(rs.getInt(1));
        course.setNumber(rs.getInt(2));
        course.setTitle(rs.getString(3));

        Subject subject = new Subject();
        subject.setId(rs.getInt(4));
        subject.setName(rs.getString(5));

        School school = new School();
        school.setId(rs.getInt(6));
        school.setName(rs.getString(7));
        school.setAbbreviation(rs.getString(8));
        school.setType(rs.getString(9));
        school.setCity(rs.getString(10));
        school.setRegion(rs.getString(11));
        school.setCountry(rs.getString(12));

        Instructor instructor = new Instructor();
        instructor.setId(rs.getInt(13));
        instructor.setFirstName(rs.getString(14));
        instructor.setLastName(rs.getString(15));

        course.setSubject(subject);
        course.setSchool(school);
        course.setInstructor(instructor);
    }
}

In this case, which is the better choice? Use one database connection, join three tables, and return 15 fields? Or use four connections from the ConnectionPool (one for each DAO used), write less code, 开发者_StackOverflowand execute simple queries?


You should definitelly use the method with joins. Doing query for each property is highly inefficient, and if you have a lot of data it will cause miserable performance due to n+1 select type of problem (3n+1 in your case).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜