提问者:小点点

结果集自动关闭


我的音乐机器人不和谐。 我想在跟踪ist启动时发送一个嵌入消息,但是ResultSet总是关闭。 所以它不能通过if查询。

下面是我的代码(类“TrackScheduler”):

try {
                
                file = new URL("https://img.youtube.com/vi/" + videoID + "/hqdefault.jpg").openStream();
                builder.setImage("attachment://thumbnail.png");
                
                System.out.println("4");
                
                ResultSet set = LiteSQL.onQuery("SELECT * FROM musicchannel WHERE guildid = " + guildid);
                
                try {
                    System.out.println("3");
                    
                    if(set.next()) {
                        long channelid = set.getLong("channelid");
                                                
                        TextChannel channel;
                        
                        System.out.println("2");
                        
                        if((channel = guild.getTextChannelById(channelid)) != null) {
                            
                            System.out.println("1");
                            
                            channel.sendTyping().queue();
                            channel.sendFile(file, "thumbnail.png").embed(builder.build()).queue();
                        }                   
                    }

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

My Litesql.onQuery(类“Litesql”):

private static Connection c;
    
    private static Statement s;

public static ResultSet onQuery(String sql) {
        
        try {
            
            return s.executeQuery(sql);
        }
        catch(SQLException e) {
            e.printStackTrace();
        }
        
        return null;
    }

错误如下:

ava.sql.SQLException: ResultSet closed
        at org.sqlite.core.CoreResultSet.checkOpen(CoreResultSet.java:76)
        at org.sqlite.jdbc3.JDBC3ResultSet.findColumn(JDBC3ResultSet.java:39)
        at org.sqlite.jdbc3.JDBC3ResultSet.getLong(JDBC3ResultSet.java:423)
        at de.nameddaniel.bot.musik.TrackScheduler.onTrackStart(TrackScheduler.java:79)
        at com.sedmelluq.discord.lavaplayer.player.event.AudioEventAdapter.onEvent(AudioEventAdapter.java:72)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayer.dispatchEvent(DefaultAudioPlayer.java:368)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayer.startTrack(DefaultAudioPlayer.java:117)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayer.playTrack(DefaultAudioPlayer.java:80)
        at de.nameddaniel.bot.musik.AudioLoadResult.trackLoaded(AudioLoadResult.java:20)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItemOnce(DefaultAudioPlayerManager.java:443)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.checkSourcesForItem(DefaultAudioPlayerManager.java:419)
        at com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager.lambda$createItemLoader$0(DefaultAudioPlayerManager.java:218)
        at java.util.concurrent.FutureTask.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

我是新来的,所以如果有什么遗漏的信息,请告诉我。 同样,我也为糟糕的格式感到抱歉。

你好,丹尼尔:)


共2个答案

匿名用户

不要在语句连接字段上使用静态

>

  • 此代码存在安全漏洞。 查找SQL注入。 基本要旨是:声明几乎完全无用。 您希望PreparedStatement,并且您希望SQL查询仅为字符串文本。 永远不要通过将用户输入串联在一起来“创建查询字符串”。 查询字符串应该是,例如,select*FROM musicchannel,其中guildid=?(是的,字符串中有一个文字问号),然后使用PreparedStatementsetInt方法来设置公会ID。 或者更好的是,由于JDBC API并不是真正为这样的消费而设计的,所以使用类似JDBI的东西。

    这是错误的异常处理。 如果您不知道该做什么,正确的“I dont know”catch块是抛出新的RuntimeException(“uncatch”,e);,而不是e.PrintStackTrace();。 更好的是,让这些方法只抛出SQLException; 显然做DB事情的方法应该抛出它。 注意,您的main方法可以(也应该)声明为抛出异常。

    Connection,PreparedStatement和ResultSet都是资源,需要通过try-with-Resources打开。 不这样做意味着你的应用程序有漏洞,如果它运行的时间足够长,就会破坏一些东西。 对于DB代码,DB最终会耗尽连接,变得完全无法访问,直到你关闭Java应用程序。 这就是为什么你需要尝试资源。

    只有一个语句和连接(字段是静态的)。 想必你的discord bot可以接收不止一条消息,所以如果你试图发送不止一条消息,系统就会陷入火海。 这里不要用“static”。 您粘贴的代码本身并不包含任何会关闭ResultSet的内容,但是通过重新设计而不是静态的,这个问题很可能会自行解决。

  • 匿名用户

    (除了另一个答案,这其实都是非常好的建议,你应该遵循)我推测以下是问题所在:

                return s.executeQuery(sql);
    

    如果它是静态的,并且被其他对象多次使用,我认为这是行不通的。 它最终会被清理干净的。 而不是在那里这样做,您应该只返回一个带有所需数据的对象。 查找DAO类模式。