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

Помогите Java & SQLite

Тема в разделе "Разработка плагинов для новичков", создана пользователем Korvinius, 9 май 2016.

  1. Shevchik

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

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

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

    Dereku Старожил

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

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

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

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

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

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

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

    Код:
    [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 Старожил

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

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

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

    Dereku Старожил

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

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

    Баллы:
    88
    Спасибо. С ошибкой я разобрался.[DOUBLEPOST=1463138139,1463134387][/DOUBLEPOST]Но, к сожалению с толкнулся с новой, решение к которой пока не могу найти. Суть в том, что когда база уже создана, но в ней еще нет записей, есть метод, который проверяет БД на наличие в ней определенной записи перед добавлением/обновлением. В результате получаю такую ошибку:
    Код:
    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]
    вот этот кусок кода:
    Код:
        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 Старожил Пользователь

    Баллы:
    123
    Имя в Minecraft:
    Reality_SC
    Код:
    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 Старожил Пользователь

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

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

    Баллы:
    88
    Спасибо большое, это решило мою проблему! Сделал так:
    Код:
                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 Старожил

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

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

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

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

    Dereku Старожил

    Баллы:
    173
    Skype:
    derek_unavailable
    Имя в Minecraft:
    _Dereku
    По доброму нужно.
     
  17. Reality_SC

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

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

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

    Баллы:
    88
    это как?
     
  19. hobabibs

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

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

    Dereku Старожил

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

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

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

Поделиться этой страницей