我有一个运行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
答案 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