簡體   English   中英

為什么 MySQL 數據庫返回空 ResultSet 雖然數據應該是正確的

[英]Why does MySQL database return empty ResultSet although data should be correct

上下文:我的數據庫中有 2 個不同的表。 第一個是動作塊(Java 中的 ActionBlock),第二個是位置(Java 中的 PermanentLocation)。 ActionBlock class 需要一個位置才能工作,因此為了讓代碼工作,它首先加載包含所需位置的 ActionBlock 數據,然后代碼加載必要的位置。 (是的,我知道下面的代碼會垃圾加載位置查詢)

問題:使用與 ActionBlock 加載器相同的 DB 連接加載位置會給出空的 ResultSet

我試過的:

  1. 使用不同的連接:沒有區別
  2. 驗證密鑰是否相同(id 和 uuid):它們是
  3. 在數據庫中測試查詢:在 DBMS 中創建 select 查詢返回 1 個特定行,但將完全相同的查詢代碼復制到 Java 仍會導致空 ResultSet(對於此測試,PreparedStatement 已更改為 Statement)
  4. 驗證我使用的是正確的數據庫:動作塊從數據庫加載正常,我使用相同的連接來加載位置
  5. 代碼中的其他連接是否關閉?:是
  6. 控制台中的錯誤是什么?:沒有錯誤打印到控制台

“無法加載位置”始終打印到控制台(因為加載程序返回 null) ActionBlock 加載代碼

/**
 * Loads the blocks from the database. All registerClass calls must be called before this
 */
public void loadBlocksFromDatabase() {
    Connection conn = null;
    try {
        conn = KaranteeniCore.getDatabaseConnector().openConnection();
        PreparedStatement stmt = conn.prepareStatement(
                "SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?;");
        stmt.setString(1, KaranteeniCore.getServerIdentificator());
        ResultSet set = stmt.executeQuery();

        // loop all the blocks from the database
        while(set.next()) {
            String uuidStr = set.getString(1);
            String permission = set.getString(2);
            String classType = set.getString(3);

            UUID uuid = UUID.fromString(uuidStr);

            // check if loaded block is a block or a sign
            for(Class<? extends ActionBlock> clazz : subBlockClasses)
            if(clazz.getName().equals(classType)) {
                // load the location of the block
                PermanentLocation loc = PermanentLocation.loadLocation(conn, uuid);
                if(loc == null) {
                    Bukkit.getLogger().log(Level.WARNING, "Could not load location " + uuid.toString() + ". Has it been deleted from database?");
                    continue;
                }

                Block block = loc.getLocation().getBlock();
                try {
                    // try to create a new class out of this block
                    if(permission != null) {
                        Constructor<? extends ActionBlock> cstr = clazz.getConstructor(Block.class, UUID.class, String.class);
                        ActionBlock aBlock = cstr.newInstance(block, uuid, permission);
                        aBlock.onLoad();
                        registerBlock(aBlock); // register created class
                    } else {
                        Constructor<? extends ActionBlock> cstr = clazz.getConstructor(Block.class, UUID.class);
                        ActionBlock aBlock = cstr.newInstance(block, uuid);
                        aBlock.onLoad();
                        registerBlock(aBlock); // register created class
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            // load all signs
            for(Class<? extends ActionSign> clazz : subSignClasses)
            if(clazz.getName().equals(classType)) {
                // load the location of the block
                Block block = PermanentLocation.loadLocation(uuid).getLocation().getBlock();
                try {
                    // try to create a new class out of this block
                    if(permission != null) {
                        Constructor<? extends ActionSign> cstr = clazz.getConstructor(Block.class, UUID.class, String.class);
                        ActionBlock aBlock = cstr.newInstance(block, uuid, permission);
                        aBlock.onLoad();
                        registerBlock(aBlock); // register created class
                    } else {
                        Constructor<? extends ActionSign> cstr = clazz.getConstructor(Block.class, UUID.class);
                        ActionBlock aBlock = cstr.newInstance(block, uuid);
                        aBlock.onLoad();
                        registerBlock(aBlock); // register created class
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    } catch(SQLException e) {
        e.printStackTrace();
        // ignored
    } finally {
        try {
            if(conn != null)
                conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

PermanentLocation 加載代碼

/**
 * Loads a permanent location from database using the given uuid
 * @param conn Connection to the database
 * @param uuid uuid of the location
 * @return location loaded or null if none found
 */
public static PermanentLocation loadLocation(Connection conn, UUID uuid) {
    PermanentLocation location = null;
    try {
        PreparedStatement st = conn.prepareStatement("SELECT world, x, y, z, pitch, yaw FROM location WHERE id = ? AND serverID = ?;");
        st.setString(1, uuid.toString());
        st.setString(2, KaranteeniPlugin.getServerIdentificator());
        ResultSet set = st.executeQuery();
        if(set.next()) {
            String w = set.getString(1);
            double x = set.getDouble(2);
            double y = set.getDouble(3);
            double z = set.getDouble(4);
            float pitch = set.getFloat(5);
            float yaw = set.getFloat(6);

            World world = Bukkit.getWorld(w);
            if(world == null)
                return null;
            else
                Bukkit.getLogger().log(Level.SEVERE, "Could not find world " + w);

            Location loc = new Location(world, x,y,z,pitch,yaw);

            location = new PermanentLocation(uuid, loc);
        }
        else
            location = null;
    } catch(SQLException e) {
        Bukkit.getLogger().log(Level.SEVERE, e.getMessage());
    }

    return location;
}

sys.statements_with_errors_or_warnings (插入到動作塊中的是 indev 代碼,它有一個小錯誤) sys.statements_with_errors_or_warnings

來自(我假設)Java 的查詢從 Java 收到的查詢

位置表中的內容數據庫位置表內容

動作塊表中的內容動作塊表內容

需要更多信息? 本帖來源於Spigot論壇帖子

編輯:重新啟動數據庫或系統不會影響結果

我猜問題只是錯字,請換行

  "SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?;");

"SELECT uuid,permission,classtype FROM actionblock WHERE serverID = ?");

希望我有幫助;

找到答案:服務器啟動時無法加載位置,因為其他類只有在完全啟動后才能找到必要的信息(世界)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM