当前位置: 首页 > 知识库问答 >
问题:

测试jdbc查询和准备好的语句

漆雕升
2023-03-14

我有一个类,其中我使用旧的jdbc方法创建了到h2数据库的连接,该方法编写url并获取连接,我在数据库中创建了一个表,这个表不是java对象,所以我用尽了聪明的方法来为我的方法编写测试

//above would be the url and driver connection

//我还创建了一个表app_user公共void addUser(连接连接,字符串登录,字符串密码,字符串描述)抛出SQLException{

        System.out.println(String.format("Add user : %s", login));

        String newUSer = "INSERT INTO app_user(login, password, description) VALUES (?,?,?)";

        try (PreparedStatement preparedStatement = connection.prepareStatement(newUSer)) {

            preparedStatement.setString(1, login);
            preparedStatement.setString(2, password);
            preparedStatement.setString(3, description);

            // returns number of changed column
            preparedStatement.executeUpdate();
        }
    }

而我的测试方法看起来像这样,有没有办法让它不那么整洁,更简单,我试图用mockito来嘲笑,但我的app_user表不是类的对象App_user,所以我写了这个

@Test
    public void addUser() throws SQLException, ClassNotFoundException {


        Class.forName("org.h2.Driver");
        try (Connection connection = DriverManager.getConnection(URL, "sa", "")) {

            String createTable =
                    "CREATE TABLE app_user(" +
                            "user_id INT NOT NULL AUTO_INCREMENT," +
                            "login VARCHAR (255) NOT NULL ," +
                            "password VARCHAR (255) NOT NULL ," +
                            "description VARCHAR (255) NULL," +
                            "PRIMARY KEY (user_id))";

            try (Statement statement = connection.createStatement()) {
                statement.executeUpdate(createTable);
                Assert.assertNotNull(statement);
            }

            String addUser = "INSERT INTO app_user(login, password, description) VALUES (1234,'valentine','javaMan')";
            PreparedStatement statement = connection.prepareStatement(addUser);
            int rowAffected = statement.executeUpdate();

            Assert.assertNotNull(rowAffected);
            Assert.assertEquals(rowAffected,1);
        }

但我不喜欢在我的测试中再次创建连接的事实,注意——出于某种原因,我不能使用对象作为表格。

共有2个答案

经兴安
2023-03-14

就创建JDBC连接而言,我认为有一种优雅的方法可以最大限度地减少您的努力。我建议不要每次都创建一个连接,而是编写一个表示JDBC连接的单例类。这将避免您一遍又一遍地做的一些工作。

类似于以下代码的内容。(跳过异常和更多细节)

class Database{
    Connection jdbc;
    //Can store username, url , password etc as private fields here
    private Database(){
        if(jdbc == null){
            Class.forName("org.h2.Driver");
            jdbc = DriverManager.getConnection("URL", "sa", "");
        }
    }
    Connection getConnection(){
        if(jdbc == null){
            this();
        }
        return jdbc;
    }
};
爱博达
2023-03-14

我个人认为最好的方法是创建一个静态类< code>TestUtils并添加一个静态方法来打开和查询db,另一个方法来关闭连接。连接本身是类的成员。要搜索的SQL查询是一个字符串参数,结果集是一个要返回的值。

下面是班级。

public class TestUtils {
    private static Connection conn = null;
    private static java.sql.Statement stmt = null;
    private static ResultSet rs;

    public static ResultSet readDB(String sql) throws ClassNotFoundException, SQLException {
        //lettura ladder da db insieme a configs
        // JDBC driver name and database URL
        final String DB_URL = "jdbc:mysql://localhost/sportservicelive";

        //  Database credentials
        final String USER = "root";
        final String PASS = "root";

        //STEP 2: Register JDBC driver
        Class.forName("com.mysql.jdbc.Driver");

        //STEP 3: Open a connection

        conn = DriverManager.getConnection(DB_URL, USER, PASS);

        //STEP 4: Execute a query

        stmt = conn.createStatement();
        rs = stmt.executeQuery(sql);

        return rs;
    }

    public static void closeDB() throws SQLException {
        stmt.close();
        conn.close();
        rs.close();
    }
    [...]
}

当然,它包含对单元测试有用的各种其他方法。

 类似资料:
  • 我正在尝试使用准备好的语句和TABLE_CATALOG和table_schema的参数来选择默认模式'public'中的所有表。当我创建一个准备好的语句时,系统会返回一个错误,这没有任何意义。如果我指定了TABLE_CATALOG而不指定TABLE_SCHEMA,它可以很好地工作。另外,如果指定TABLE_SCHEMA而不指定TABLE_CATALOG,它也可以正常工作。我是不是做错什么了? 线程

  • 问题内容: 假设我们有一个查询: 以及要获取的ID数组: 预处理语句它劝准备一个语句,并调用它多次: 但是现在我必须手动对结果进行排序。我有其他不错的选择吗? 问题答案: 您可以这样进行: 使用此方法,您将为每个id调用bind_param,并且已由mysql完成排序。

  • 我正在使用JDBC执行Oracle语句,如下所示: 我在Java找到了几种称呼上面的声明的方法,主要是: > 使用OraclePreparedStatement: 使用CallableStatement: > 方法#2抛出“SQLException:Not all return parameters registered”,但是,如果我将SQL语句包装为“begin..end;”-那么方法2就很好

  • 我有一个遗留代码,不允许使用预先准备好的语句。它使用Spring JDBC和更新查询。要求更新100000行。我有一张地图,上面有行号和需要在特定列中更新的值。 下面是我的当前代码: 我需要将其更改为批量执行,以便在for循环之后,我可以在一次DB命中中执行它。 对于这个需求,使用spring JDBC批处理更新的最佳方式是什么?