【问题标题】:Is there a proper way to instantiate strongly typed objects in DAOs?是否有适当的方法在 DAO 中实例化强类型对象?
【发布时间】:2011-05-30 23:07:00
【问题描述】:

我正在尝试确定哪种方法是为包含一些原始数据类型和三个具有自己的 DAO 的强类型对象的类编写 DAO 的正确方法。

这是我正在为其实现 DAO 的类,减去 getter/setter:

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

Subject、School 和 Instructor 类都有自己的 DAO。所以我最初的想法是使用那些 DAO 来实例化 Course 对象中的 Subject、School 和 Instructor 对象(相关代码在 try 块中):

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;
    }
}

其他 DAO 看起来与这个非常相似。每个都从 ConnectionPool 中获取一个 Connection,使用 PreparedStatement 执行简单查询,关闭 ResultSet 和 PreparedStatement,然后将 Connection 释放回池中。

以这种方式实现 CourseDAO 后,我开始怀疑在查询中使用联接是否会更好/更有效,而不是调用 SubjectDAO、SchoolDAO 和 InstructorDAO,因为每个都使用来自 ConnectionPool 的 Connection。查询和尝试块将更改如下:

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);
    }
}

在这种情况下,哪个是更好的选择?使用一个数据库连接,连接三个表,返回15个字段?还是使用 ConnectionPool 中的四个连接(每个使用的 DAO 一个),编写更少的代码并执行简单的查询?

【问题讨论】:

    标签: java mysql dao


    【解决方案1】:

    您绝对应该使用带有连接的方法。对每个属性进行查询是非常低效的,如果您有大量数据,由于 n+1 选择类型的问题(在您的情况下为 3n+1)会导致性能不佳。

    【讨论】:

    • n+1 选择问题类型是什么意思?
    • 没关系,我正在阅读这里What is the n+1 selects problem?
    • 谢谢!我在考虑使用多个连接到数据库的效率低下,但没有考虑到必须做出 4 个选择语句的效率低下。使用 join 显然是这里的最佳选择。
    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 2010-12-13
    相关资源
    最近更新 更多