JDBC查询不会返回任何没有错误的值

时间:2019-01-20 15:16:15

标签: java mysql jdbc

我有一个运行MariaDB的本地SQL Server,需要使用Java和JDBC从数据库查询数据。我可以连接到数据库,也可以写数据,但是简单的SELECT无效。

我已经尝试使用不同版本的mysql-java-connector,并检查SQL-Server是否为最新版本。

连接到数据库:

//Check wether connection already exists
if(connection != null && !connection.isClosed()){
    return;
}
//Create new connection
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/statdb", "root", "");
System.out.println("Connected to Database");
//Update guilds from Database
updateGuildsInDatabase();

最后调用的方法如下:

private void updateGuildsInDatabase() throws SQLException {
    //Check for not existing connection
    if(connection == null || connection.isClosed()){
        init();
        return;
    }
    ArrayList<String> localInDb = new ArrayList<>();
    Statement qGStmt = connection.createStatement();
    //Execute Query
    ResultSet guilds = qGStmt.executeQuery("SELECT * FROM guilds;");
    guilds.first();
    //Adding results to List
    while(guilds.next()){
        localInDb.add(guilds.getString("guild_uid").toLowerCase());
    }
    System.out.println("Queried: " + localInDb.size());
    this.guildsInDb = localInDb;
}

数据库“ statdb”中的表“ guilds”具有两列,分别名为“ guild_uid”(主键,varchar)和“ display_name”(varchar)。我添加了一个值为“ guild_1”和“ Test Guild”的条目。

因为我在“行会”表中有一个条目,所以我希望控制台看起来像这样:

Connected to Database
Queried: 1

但是实际输出如下:

Connected to Database
Queried: 0

3 个答案:

答案 0 :(得分:2)

ResultSet#first()方法本身将光标移动到结果集的第一行。然后,ResultSet#next()方法将光标向前移动一个,并读取其中的任何记录(如果有记录的话)。

因此,使用模式将始终导致从结果集中跳过第一条记录。如果结果集恰好只有一条记录,那么记录数将显示为零。

您可能应该删除对ResultSet#first()的呼叫。改用它:

ResultSet guilds = qGStmt.executeQuery("SELECT * FROM guilds;");
while(guilds.next()) {
    localInDb.add(guilds.getString("guild_uid").toLowerCase());
}
System.out.println("Queried: " + localInDb.size());
this.guildsInDb = localInDb;

在逻辑上对新结果集调用ResultSet#next()的原因是,默认情况下,JDBC结果集实际上并未开始指向第一条记录。相反,我们通常会在第一次调用ResultSet#next()的情况下将其推进到第一条记录。

答案 1 :(得分:1)

我认为您不需要guilds.first()。尝试将其删除。

根据ResultSet JavaDoc:

  

ResultSet光标最初位于第一行之前;第一个对方法的调用接下来使第一行成为当前行;第二个调用使第二行成为当前行,依此类推。

我相信这里正在发生的事情是,guilds.first()将光标从before第一行设置为第一行。而while循环中的guilds.next()将光标移到更前一步。因此,您缺少第一行。

答案 2 :(得分:0)

另外两个答案是正确的,从结果集中检索时您将跳过第一行。正如他们所解释的,guilds.first();行不需要,结果集默认情况下自动指向第一行。

示例代码,取自ResultSet

以下是使用H2 Database Engine的完整示例。这显示了创建一个新的数据库(内存中,未持久存储到磁盘),添加一个表,用几行填充该表,然后通过ResultSet检索所有这些行。

关键行是while ( rs.next() ) {

package work.basil.example;

import java.sql.*;
import java.util.*;

import org.h2.jdbcx.JdbcDataSource;

import javax.sql.DataSource;

public class GuildDemo {

    public static void main ( String[] args ) {
        GuildDemo app = new GuildDemo();
        app.doIt();
    }

    private void doIt ( ) {

        DataSource dataSource = null;
        final String catalogName = "guild_demo_";
        final String tableName = "guild_";

        // Verify JDBC driver.
        try {
            Class.forName( "org.h2.Driver" );
            JdbcDataSource ds = new JdbcDataSource(); // The `javax.sql.DataSource` interface implemented by `org.h2.jdbcx.JdbcDataSource`.
            ds.setURL( "jdbc:h2:mem:" + catalogName + ";DB_CLOSE_DELAY=-1" );  // Set delay to -1 to keep in-memory database even after last connection closed.
            ds.setUser( "scott" );
            ds.setPassword( "tiger" );
            ds.setDescription( "Dummy database for demo showing how to retrieve rows from a ResultSet." );
            dataSource = ds;  // Generalize from the concrete class to the interface.
        } catch ( ClassNotFoundException e ) {
            e.printStackTrace();
            return;
        }

        // Connect, and create database.
        try (
                Connection conn = dataSource.getConnection() ;
        ) {
            String sql = null;

            // Create table.
            try ( Statement stmt = conn.createStatement() ; ) {
                sql = "CREATE TABLE " + "guild_" + " ( \n" +
                        " pkey_ UUID DEFAULT random_uuid() PRIMARY KEY , \n" +
                        " name_ VARCHAR NOT NULL \n" +
                        ") ; \n";
                System.out.println( "TRACE - SQL:\n" + sql );
                stmt.execute( sql );
            }

            // Add rows.
            sql = "INSERT INTO guild_ ( name_ ) \n" +
                    "VALUES ( ? ) " +
                    "; ";

            List < String > names = List.of( "Alpha" , "Beta" , "Gamma" , "Delta" ); // Insert a row for each of these names.
            System.out.println( "Inserting list of names: " + names );
            try (
                    PreparedStatement ps = conn.prepareStatement( sql ) ;
            ) {
                for ( String name : names ) {
                    ps.setString( 1 , name );
                    ps.executeUpdate();
                }
            }

            // Retrieve rows from a `ResultSet`.
            sql = "SELECT * FROM " + "guild_" + " ;";
            try (
                    Statement stmt = conn.createStatement() ;
                    ResultSet rs = stmt.executeQuery( sql ) ;
            ) {
                while ( rs.next() ) {
                    UUID pkey = rs.getObject( "pkey_" , UUID.class );
                    String name = rs.getString( "name_" );
                    System.out.println( "Row pkey_: " + pkey + " name_: " + name );
                }
            }


        } catch ( SQLException e ) {
            e.printStackTrace();
        }
    }

}

运行时。

  

插入名称列表:[Alpha,Beta,Gamma,Delta]

     

行pkey_:69908390-5fa6-4eee-8e12-40106db8d60d名称_:Alpha

     

行pkey_:3116acb9-fcce-427f-b222-99c78c6e752a名称_:Beta

     

行pkey_:b3fd0930-a2e7-461a-be70-f05124fc58de名称_:Gamma

     

行pkey_:dddb423a-5eb2-4e5e-be16-7bb0c27c0033名称_:Delta