Хостинг серверов Minecraft playvds.com
  1. Вы находитесь в русском сообществе Bukkit. Мы - администраторы серверов Minecraft, разрабатываем собственные плагины и переводим на русский язык плагины наших собратьев из других стран.
    Dismiss Notice

Помогите Java & SQLite

Discussion in 'Разработка плагинов для новичков' started by Korvinius, May 9, 2016.

  1. Shevchik

    Shevchik Старожил Пользователь

    Trophy Points:
    173
    Имя в Minecraft:
    _Shevchik_
    Такой нет, потому что ссылка обновляется на onLoad.

    Проблема будет когда статическая ссылка присваивается тольк на статик инициализации класса.
     
  2. Хостинг MineCraft
    <
  3. Dereku

    Dereku Старожил

    Trophy Points:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Страшного в них нету ничего, спору нет. Но когда в коде ты видишь 2-3 ссылки на одно и то же - проиграть как раз плюнуть.
    Ну и как шевчик написал, синглтоны могут всё попортить (если что то пойдёт не так, разумеется), так что ссылку на основной класс приятнее передавать явно.
     
  4. Автор темы
    Korvinius

    Korvinius Активный участник Пользователь

    Trophy Points:
    88
    Эм, я дико извиняюсь, но, подскажите еще, что еще нужно прописать в "onEnable", чтобы можно было с этим работать :oops:?
     
  5. ql_Nik_lp

    ql_Nik_lp Старожил Девелопер Пользователь

    Trophy Points:
    173
    Skype:
    q-nik-p
    Имя в Minecraft:
    ql_Nik_lp
    Если я правильно понял - вызвать load()
     
  6. Автор темы
    Korvinius

    Korvinius Активный участник Пользователь

    Trophy Points:
    88
    вероятно я его не правильно вызывал, так как этот способ:
    Code:
        private SQLite sqlite;
    
        @Override
        public void onEnable() {   
    
            sqlite.load();
    приводит к ошибке:

    Code:
    [17:27:40 ERROR]: Error occurred while enabling Mystery v0.4/1 (Is it up to date?)
    java.lang.NullPointerException
            at net.wealth_mc.mystery.Mystery.onEnable(Mystery.java:106) ~[?:?]
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:292) ~[server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.craftbukkit.v1_9_R1.CraftServer.loadPlugin(CraftServer.java:361) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.craftbukkit.v1_9_R1.CraftServer.enablePlugins(CraftServer.java:321) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.t(MinecraftServer.java:411) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.l(MinecraftServer.java:376) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.a(MinecraftServer.java:331) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.DedicatedServer.init(DedicatedServer.java:269) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:527) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
    И 106-я строка, именно эта: sqlite.load();
     
  7. Dereku

    Dereku Старожил

    Trophy Points:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Ты пишешь "sqlite.load(); ", а в jvm оно выглядит как "null.load();".
     
  8. Автор темы
    Korvinius

    Korvinius Активный участник Пользователь

    Trophy Points:
    88
    а, блин, точно, забыл добавить sqlite = new SQLite(this); спасибо, с этим прошло, родило новые ошибки, походу что то я напартачил в самом SQL запросе, попробую сначала сам разобраться...
     
  9. Dereku

    Dereku Старожил

    Trophy Points:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    лайк.
     
  10. Автор темы
    Korvinius

    Korvinius Активный участник Пользователь

    Trophy Points:
    88
    Спасибо. С ошибкой я разобрался.[DOUBLEPOST=1463138139,1463134387][/DOUBLEPOST]Но, к сожалению с толкнулся с новой, решение к которой пока не могу найти. Суть в том, что когда база уже создана, но в ней еще нет записей, есть метод, который проверяет БД на наличие в ней определенной записи перед добавлением/обновлением. В результате получаю такую ошибку:
    Code:
    java.sql.SQLException: ResultSet closed
            at org.sqlite.RS.checkOpen(RS.java:63) ~[server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.sqlite.RS.markCol(RS.java:77) ~[server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.sqlite.RS.wasNull(RS.java:208) ~[server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.wealth_mc.mystery.db.MysterySQLite.getThisMysteryPlayerToNameDB(MysterySQLite.java:39) [Mystery.jar:?]
            at net.wealth_mc.mystery.Mystery.getConfigPlayerPrefix(Mystery.java:172) [Mystery.jar:?]
            at net.wealth_mc.mystery.Mystery.loadConfMystery(Mystery.java:128) [Mystery.jar:?]
            at net.wealth_mc.mystery.Mystery.onEnable(Mystery.java:83) [Mystery.jar:?]
            at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:292) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.craftbukkit.v1_9_R1.CraftServer.loadPlugin(CraftServer.java:361) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at org.bukkit.craftbukkit.v1_9_R1.CraftServer.enablePlugins(CraftServer.java:321) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.t(MinecraftServer.java:411) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.l(MinecraftServer.java:376) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.a(MinecraftServer.java:331) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.DedicatedServer.init(DedicatedServer.java:269) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at net.minecraft.server.v1_9_R1.MinecraftServer.run(MinecraftServer.java:527) [server11486.jar:git-Spigot-944aa20-8d16fc0]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_77]
    вот этот кусок кода:
    Code:
        public MysteryPlayer getThisMysteryPlayerToNameDB(String playername) {
            MysteryPlayer pl = null;
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            conn = getSQLConnection();
            try {
                ps = conn.prepareStatement("SELECT * FROM " + mystery_player_list
                        + " WHERE displayName = '" + playername.toLowerCase() + "';");
                rs = ps.executeQuery();
    
    /*MysterySQLite.java:39*/pl = new MysteryPlayer(UUID.fromString(rs.getString("uniqueId")), rs.getString("displayName"),
                        Gender.valueOf(rs.getString("gender")), Legacy.valueOf(rs.getString("legacy")),
                        rs.getInt("level"), rs.getInt("timeLevel"), rs.getInt("killLevel"),
                        rs.getInt("killTheirLegacy"), rs.getInt("killAlienLegacy"), rs.getInt("killNotLegacy"));
    
            } catch (SQLException ex) {
                plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
            } finally {
                try {
                    if (ps != null)
                        ps.close();
                    if (conn != null)
                        conn.close();
                } catch (SQLException ex) {
                    plugin.getLogger().log(Level.SEVERE, Errors.sqlConnectionClose(), ex);
                }
            }
            return pl;
        }
    я знаю, что ошибка из-за того, что запрос не может выполниться, так как в базе нет совпадений этому запросу, по сути в базе еще совсем нет записей, но как прервать метод, если строка не найдена?
    Пробовал : if (rs == null) return pl; не помогает, вероятно переменная не совсем пустая, а такие варианты:
    if (rs.wasNull()) return pl; или if (rs.first()) return pl; приводят к аналогичной ошибке на них-же, подскажите, как можно прервать выполнение этого метода, если искомая запись не найдена?
     
  11. Reality_SC

    Reality_SC Старожил Пользователь

    Trophy Points:
    123
    Имя в Minecraft:
    Reality_SC
    Code:
    at net.wealth_mc.mystery.db.MysterySQLite.getThisMysteryPlayerToNameDB
       (MysterySQLite.java:39)
    Это которая строка у тебя в коде выше? Тьфу, я слепой.[DOUBLEPOST=1463139347,1463139022][/DOUBLEPOST]Твоя переменная rs является не той самой единственной строкой результата, которую ты ждёшь, а кортежем строк (коих может быть в количестве от 0 до N).
    Нужно использовать rs.next(), и если оно даёт true, значит в rs загружена следующая непрочитанная строка. Вот, например, как я извлекаю все полученные строки. Правда, это MySQL, а не SQLite.

    Гуру БД при желании могут поправить меня, ибо я далеко не pro.
     
  12. Larin

    Larin Старожил Пользователь

    Trophy Points:
    103
    Ребят, читайте больше книг =)
    Это же JDBC! Видов реляционных БД много, а стандарт один.(Для noSQL не подойдёт!)
     
  13. Автор темы
    Korvinius

    Korvinius Активный участник Пользователь

    Trophy Points:
    88
    Спасибо большое, это решило мою проблему! Сделал так:
    Code:
                while(rs.next()){
                    if (rs.getString("displayName").equalsIgnoreCase(playername.toLowerCase())) {
                        pl = new MysteryPlayer(UUID.fromString(rs.getString("uniqueId")), rs.getString("displayName"),
                                Gender.valueOf(rs.getString("gender")), Legacy.valueOf(rs.getString("legacy")),
                                rs.getInt("level"), rs.getInt("timeLevel"), rs.getInt("killLevel"),
                                rs.getInt("killTheirLegacy"), rs.getInt("killAlienLegacy"),
                                rs.getInt("killNotLegacy"));
                    }
                }
    [DOUBLEPOST=1463908375,1463154001][/DOUBLEPOST]Еще хотел посоветоваться.

    1. Как практичнее, работать напрямую с БД или считывать с базы инфу в массив и там уже обрабатывать?

    2. Если работать напрямую с базой, то в отдельные потоки выводить абсолютно всю работу с ней или короткие запросы можно делать в основном, а запись и более сложные в дополнительном?

    3. Если все делать в дополнительных потоках, то частые запросы к БД (хоть и не сложные, просто получение инфы), то есть будет создаваться много потоков (конечно в зависимости от онлайна) не создадут ли они большой нагрузки на сервер?
     
  14. Dereku

    Dereku Старожил

    Trophy Points:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    Иногда уходит больше времени на создание потока, чем на его выполнение.

    Вообще лучше (имхо) вытащить всю инфу из бд в память и работать уже с памятью. И где то раз в 10 минут кидать в бд изменения.
     
  15. GoodCoder

    GoodCoder Активный участник Пользователь

    Trophy Points:
    76
    Можно пул потоков создать.
     
  16. Dereku

    Dereku Старожил

    Trophy Points:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    По доброму нужно.
     
  17. Reality_SC

    Reality_SC Старожил Пользователь

    Trophy Points:
    123
    Имя в Minecraft:
    Reality_SC
    Вызовы в БД — медленные. Если она удалённая, то особенно.
    Всё, что работает медленно, обязано работать в параллельном потоке. Единственное исключение — можно быстренько что-то запросить при загрузке сервера в onLoad или onEnable (менее желательно).
    Всё, что можно не вычислять, а хранить готовым локально — съест память, но ускорит работу.
    Таковы основные принципы.
     
  18. Автор темы
    Korvinius

    Korvinius Активный участник Пользователь

    Trophy Points:
    88
    это как?
     
  19. hobabibs

    hobabibs Новичок Пользователь

    Trophy Points:
    16
    Имя в Minecraft:
    bhtyujnbfyu8
    Создаешь пул (гугли как), после чего задачу, которую нужно выполнить асинхронно, выполняешь в пуле потоков, таким образом берется уже созданный поток, который стоит на паузе, в нем выполняется задача и он снова становится доступен для другой задачи.
     
  20. Dereku

    Dereku Старожил

    Trophy Points:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    3 ms ещё не медленно.
     
  21. Reality_SC

    Reality_SC Старожил Пользователь

    Trophy Points:
    123
    Имя в Minecraft:
    Reality_SC
    Если придерживаться мысли, что медленно, хуже не будет =)
     

Share This Page