Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中静态数据库工厂方法的替代方法_Java_Jdbc_Instance_Static Methods_Instance Methods - Fatal编程技术网

Java中静态数据库工厂方法的替代方法

Java中静态数据库工厂方法的替代方法,java,jdbc,instance,static-methods,instance-methods,Java,Jdbc,Instance,Static Methods,Instance Methods,我一直在阅读Java中的静态与实例方法(特别是因为我在单元测试中遇到了难点),并试图找出如何编写与数据库交互的工厂。我知道有很多相关的问题;但我的具体案例似乎非常普遍,如果能了解DB工厂的替代方案,那就太好了。我目前的做法(附带一个常见用例的简化示例): 这允许我使用User User=UserFactory.getUser(1)获取一个用户。但是,我不能嘲笑它,除非我使用类似的东西,这使得测试更烦人。另外,许多人认为编写代码是这样的。 另一种选择可能是: public class UserFa

我一直在阅读Java中的静态与实例方法(特别是因为我在单元测试中遇到了难点),并试图找出如何编写与数据库交互的工厂。我知道有很多相关的问题;但我的具体案例似乎非常普遍,如果能了解DB工厂的替代方案,那就太好了。我目前的做法(附带一个常见用例的简化示例):

这允许我使用
User User=UserFactory.getUser(1)获取一个用户。但是,我不能嘲笑它,除非我使用类似的东西,这使得测试更烦人。另外,许多人认为编写代码是这样的。

另一种选择可能是:

public class UserFactory {
    // ** This class is identical to the class
    // above except this method is not static. **
    public User getUserById(Integer userId) throws SQLException {
        Connection c = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        User user = null;

        try {
            c = ConnectionFactory.getConnection(); // Uses java.sql.DriverManager to get a connection to our DB

            stmt = c.prepareStatement(STATEMENT);
            stmt.setInt(1, userId);
            rs = stmt.executeQuery();
            if (rs.next()) {
                user = new User();
                // Set user properties
            }
        } finally {
            ConnectionFactory.closeConnection(c, stmt, rs); // Calls .close() on c, stmt and rs
        }

        return user;
    }
}
要现在获得一个用户,我必须执行类似于
User User=new UserFactory().getUser(1)。当然,我可以实例化一个
UserFactory
对象并重用它(我甚至可以传递它和/或将它注入到其他类中;但我们经常与各种这样的工厂交互,因此在许多情况下,我们需要在许多工厂中注入/传递,这似乎很笨拙):

这将使测试变得简单(例如,使用),因为我可以只创建一个
UserFactory
的模拟实例(我想这意味着
newuserfactory().getUser(1)
示例用法不会很有帮助——我需要将一个实例传递给我正在测试的任何对象,对吗?)。似乎没有必要使用
UserFactory
的实例来实现我的目标(从数据库中检索用户),但我喜欢它使测试更容易(不希望单元测试击中数据库)


我错过了什么?我没有考虑的其他选择和优点/缺点是什么?我目前的做法是一种“糟糕”的做法,仅仅是因为它使测试变得烦人还是出于其他(更重要的)原因?

我真的建议查看
尝试使用
资源,使您的代码更干净,而不需要
最后的
块。@Nexevis,这很酷!我不知道那是件事。我得进一步调查一下--谢谢!非常方便的是,
连接
准备语句
(通过
语句
)和
结果集
都扩展了
自动关闭
。在某一点上可能需要进行更多的重构:d我希望的设计类似于:
接口UserFactory{…}
类userfactorympl实现UserFactory{public userfactorympl(ConnectionFactory ConnectionFactory){…}
,也就是说,
ConnectionFactory
还应该基于实例方法,而不是静态方法,并且
ConnectionFactory
应该在创建时传递到
UserFactory
。(它也应该有一个接口/实现对。)我真的建议您研究
并尝试使用
资源,以使您的代码更干净,而不需要
最终
块。@Nexevis,这很酷!我不知道那是件事。我得进一步调查一下--谢谢!非常方便的是,
连接
准备语句
(通过
语句
)和
结果集
都扩展了
自动关闭
。在某一点上可能需要进行更多的重构:d我希望的设计类似于:
接口UserFactory{…}
类userfactorympl实现UserFactory{public userfactorympl(ConnectionFactory ConnectionFactory){…}
,也就是说,
ConnectionFactory
还应该基于实例方法,而不是静态方法,并且
ConnectionFactory
应该在创建时传递到
UserFactory
。(它也应该有一个接口/实现对。)
public class UserFactory {
    // ** This class is identical to the class
    // above except this method is not static. **
    public User getUserById(Integer userId) throws SQLException {
        Connection c = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        User user = null;

        try {
            c = ConnectionFactory.getConnection(); // Uses java.sql.DriverManager to get a connection to our DB

            stmt = c.prepareStatement(STATEMENT);
            stmt.setInt(1, userId);
            rs = stmt.executeQuery();
            if (rs.next()) {
                user = new User();
                // Set user properties
            }
        } finally {
            ConnectionFactory.closeConnection(c, stmt, rs); // Calls .close() on c, stmt and rs
        }

        return user;
    }
}
UserFactory userFactory = new UserFactory();
User user = userFactory.getUser(1);