Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Java Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 4 5 [6] 7 8 9 10 .. 134   вперед  Ctrl
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
Лысый дядька
asv79,

Мозг начал ломаться на методе baseRead, которым ты делаешь ВНЕЗАПНО Insert запросы, продолжил ломаться на baseWrite, корорым ты селектишь, а потом я попробовал понять, зачем все это нужно и не осилил.

Ночью мозг уже не думал)перепутал названия.зачем это нужно?ну хваленый command патерн?инкапсуляция реализации-как по мне достаточно удобно.есть предложения как улучшить?не стесняйтесь я удовольсвием выслушаю.
26 мар 19, 13:36    [21843712]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
asv79, https://github.com/cudu/TeleBot/commit/3fdb4e79c7bf5848316b8f7bc2e0ee444806c922

начать надо с дизайна классов и поакетов. Я начал с примитивных изменений:
- убрать ресурсы из статик переменных ибо обращаться к ним могут даже если они не инициализированны
- все открывающиеся ресурсы вроде connection, resultset и etc - должны быть закрыты(хотя ява и обещает, то gc закрое, но, не всё и не всегда, особенно всякие стримы)
26 мар 19, 13:50    [21843730]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
mayton
Member

Откуда: loopback
Сообщений: 43280
Обычно
e.printStackTrace();

я заменяю на LOG.error() с публикацией стека. Это создает определённый дизайн лога
и позволяет его парсить по дате. В противном случае e.printStackTrace вываливает неинформативный
поток и логгер и дату.
26 мар 19, 14:00    [21843751]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
Озверин
asv79, https://github.com/cudu/TeleBot/commit/3fdb4e79c7bf5848316b8f7bc2e0ee444806c922

начать надо с дизайна классов и поакетов. Я начал с примитивных изменений:
- убрать ресурсы из статик переменных ибо обращаться к ним могут даже если они не инициализированны
- все открывающиеся ресурсы вроде connection, resultset и etc - должны быть закрыты(хотя ява и обещает, то gc закрое, но, не всё и не всегда, особенно всякие стримы)

Да по пакетам согласен.
Соnection и resultset если я закрываю то ничего не работает.
Просто не обрабатывает запрос протому что con.close если делать не статик переменные хотя бы тот же конекшн то тогда рушится все к чертям через 10 нажатий.
26 мар 19, 14:01    [21843752]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
asv79, так закрывать надо после использования.

https://github.com/cudu/TeleBot/commit/1661381b124eae21dce0e2cdaccdba9e046435c6

идем дальше - нежелательно держать открытым рекордсет, а значит данные надо получить, сохранить и закрыть его(Впрочем, он должен автоматически закрыться когда statement закроется).

Что делаем - сохраняем данные в map и уже с ними там работаем.
26 мар 19, 14:03    [21843759]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
Озверин,

Спсибо за такой развернутый ответ.да опыта совсем нет в проектировании .доберусь до ide буду ращбираться с вашим рефакторингом.спасибо большое за помощь,хоть увижу на примере саоей идеи настоящий код )
26 мар 19, 14:27    [21843797]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
asv79,

идем дальше: https://github.com/cudu/TeleBot/commit/cd29e55a2c5707accbb448f99994d8f33e162717

BotStart - имеет слишком длинный метод, у которого много if , который содержит дублирующий код и так далее. По хорошему, конечно, надо бы из него сделать 2-3 класса(парсер какой-нибудь, коммандер), но я пока что ставлю 2 цели:
-убрать огромной вложенности if
-вынести логику из основного метода во вспомогательные
26 мар 19, 14:56    [21843842]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
вадя
Member

Откуда: Екатеринбург
Сообщений: 16869
asv79,
это для чего?

    public Map<Integer, String> getData(String sql) throws SQLException {
        Map<Integer, String> data = new HashMap<>();
        try (Statement statement = con.createStatement()) {
            ResultSet res = statement.executeQuery(sql);
            res.next();
            ResultSetMetaData resultSetMetaData = res.getMetaData();
            for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
                data.put(i, res.getString(i));
            }
        }
26 мар 19, 15:02    [21843855]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
вадя, я хз, какие там данные, но чисто функционально чтобы не держать открытым рекордсет и не выносить его в переменные класса проще строку передать в виде мапы стрингов.
26 мар 19, 15:11    [21843871]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
вадя
asv79,
это для чего?

    public Map<Integer, String> getData(String sql) throws SQLException {
        Map<Integer, String> data = new HashMap<>();
        try (Statement statement = con.createStatement()) {
            ResultSet res = statement.executeQuery(sql);
            res.next();
            ResultSetMetaData resultSetMetaData = res.getMetaData();
            for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) {
                data.put(i, res.getString(i));
            }
        }

Я не знаю,это не мое)
26 мар 19, 15:21    [21843897]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
вадя
Member

Откуда: Екатеринбург
Сообщений: 16869
Озверин
но чисто функционально чтобы не держать открытым рекордсет
это не аргумент для этого...
Озверин
не выносить его в переменные класса проще строку передать в виде мапы стрингов.
это один из тормозов - сначала в мапу, потом использование.... и использование не по имени, а по номеру
но для нормального использования лучше уж сразу в мапу с нормальными именами, а не с индексами....
ну и это вернёт только одну строку - оно всегда так? возврат одной строки довольно редко нужен..

как по мнем - так лучше
 try (Connection con = dataSource.getConnection();
                CallableStatement proc = con.prepareCall("{call page4_yyy31()}")) {
            rs = proc.executeQuery();
            rs.next();
            userSession.getBasicRemote().sendText(String.format("yyy31|<tr data-id='%1s'><td class='num_doc_shipped_null'></td><td class='date_shipped_null'></td></tr>", rs.getString(1)));
        } catch (SQLException | IOException ex) {
            ex.printStackTrace();
        }
вырвано из контекста, но суть показана( возвращает одно значение, значит можно и по индексу)
коннекшен берётся из пула - мелочь, но экономия времени.
(вместо вызова хранимки можно использовать строку sql - это дело вкуса)
и вместо записи в мапу - сразу в нужное место .
26 мар 19, 15:38    [21843934]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
вадя,

чтобы не начинать (бесполезный с тобой) спор о производительности, здесь топик скорее про общие подходы. Когда вдруг человека начнет беспокоить производительность, он сразу же об этом напишет.

p.s. Нет, в данном случае со скоростью ничего случится, если я сложу все данные в мапу.
26 мар 19, 15:47    [21843947]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
вадя
Member

Откуда: Екатеринбург
Сообщений: 16869
Озверин
p.s. Нет, в данном случае со скоростью ничего случится, если я сложу все данные в мапу.
спорить не хочу, просто замечание.
таких мест накапливается множество, тут со скоростью ничего не случится, там ничего, а в итоге тормоз.
если это десктопное приложение - то да , может и не повлиять, а если нет? Был уже случай, показал человеку места , где можно ускорить, проверили... согласились, но переделывать проект было поздно - это было равносильно начать проект с нуля.....
26 мар 19, 16:02    [21843964]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
Озверин
asv79,

идем дальше: https://github.com/cudu/TeleBot/commit/cd29e55a2c5707accbb448f99994d8f33e162717

BotStart - имеет слишком длинный метод, у которого много if , который содержит дублирующий код и так далее. По хорошему, конечно, надо бы из него сделать 2-3 класса(парсер какой-нибудь, коммандер), но я пока что ставлю 2 цели:
-убрать огромной вложенности if
-вынести логику из основного метода во вспомогательные

ваш код нерабочий к сожалению
даже просто при запуске программы-ничего не нажимая вываливается вот такое))
EXCEPTION STACK TRACE:



** BEGIN NESTED EXCEPTION ** 

javax.net.ssl.SSLException
MESSAGE: closing inbound before receiving peer's close_notify

STACKTRACE:

javax.net.ssl.SSLException: closing inbound before receiving peer's close_notify
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:129)
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:117)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:308)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:255)
	at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:645)
	at java.base/sun.security.ssl.SSLSocketImpl.shutdownInput(SSLSocketImpl.java:624)
	at com.mysql.cj.protocol.a.NativeProtocol.quit(NativeProtocol.java:1312)
	at com.mysql.cj.NativeSession.quit(NativeSession.java:182)
	at com.mysql.cj.jdbc.ConnectionImpl.realClose(ConnectionImpl.java:1750)
	at com.mysql.cj.jdbc.ConnectionImpl.close(ConnectionImpl.java:720)
	at BaseDate.close(BaseDate.java:47)
	at BotStart.close(BotStart.java:233)
	at Main.main(Main.java:19)


** END NESTED EXCEPTION **
26 мар 19, 22:10    [21844319]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
я не с проста вынеc con в статик блок и не трогал его,любая попытка con.close приводит к подобной фигне.
26 мар 19, 22:12    [21844321]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
далее я убрал в вашем методе con.close и бот хотя бы запустися,но любое обращение к бд
выдает подобный стак трейс ерор
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
	at com.mysql.cj.jdbc.StatementImpl.checkForDml(StatementImpl.java:385)
	at com.mysql.cj.jdbc.StatementImpl.executeQuery(StatementImpl.java:1153)
	at BaseDate.update(BaseDate.java:28)
	at BotStart.help(BotStart.java:158)
	at BotStart.executeCommand(BotStart.java:181)
	at BotStart.onUpdateReceived(BotStart.java:24)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.telegram.telegrambots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
	at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:305)
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
	at com.mysql.cj.jdbc.StatementImpl.checkForDml(StatementImpl.java:385)
	at com.mysql.cj.jdbc.StatementImpl.executeQuery(StatementImpl.java:1153)
	at BaseDate.update(BaseDate.java:28)
	at BotStart.help(BotStart.java:155)
	at BotStart.executeCommand(BotStart.java:181)
	at BotStart.onUpdateReceived(BotStart.java:24)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.telegram.telegrambots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
	at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:305)
мар. 26, 2019 10:12:57 PM org.telegram.telegrambots.meta.logging.BotLogger severe
SEVERE: BOTSESSION
java.lang.NullPointerException
	at BotStart.onUpdateReceived(BotStart.java:21)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.telegram.telegrambots.meta.generics.LongPollingBot.onUpdatesReceived(LongPollingBot.java:27)
	at org.telegram.telegrambots.updatesreceivers.DefaultBotSession$HandlerThread.run(DefaultBotSession.java:305)
26 мар 19, 22:15    [21844323]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
 public  void update(String sql) throws SQLException  {
        try(Statement statement=con.createStatement()){
            statement.executeQuery(sql);
        }


    }

на вот метод ругается
вот этим
java.sql.SQLException: Can not issue data manipulation statements with executeQuery().
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
	at com.mysql.cj.jdbc.StatementImpl.checkForDml(StatementImpl.java:385)
	at com.mysql.cj.jdbc.StatementImpl.executeQuery(StatementImpl.java:1153)
	at BaseDate.update(BaseDate.java:28)
	at BotStart.help(BotStart.java:158)
	at BotStart.executeCommand(BotStart.java:181)
26 мар 19, 22:31    [21844331]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
cossack5
Member

Откуда:
Сообщений: 496
asv79,

executeQuery - для селектов, для insert/update/delete нужно использовать executeUpdate.
26 мар 19, 22:38    [21844336]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
cossack5
Member

Откуда:
Сообщений: 496
asv79,

Список команд на которые будет ругаться executeQuery. Теоретически, можно выполнить TRUNCATE TABLE (но скорее всего, упадает в другом месте).
26 мар 19, 22:46    [21844343]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
cossack5
Member

Откуда:
Сообщений: 496
Извиняюсь, не в тот драйвер посмотрел - в последней версии (которая у вас) checkForDml будет ругаться на все что не селект
26 мар 19, 22:59    [21844351]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
пофиксил эту ошибку ,но теперь при нажатии на любую кнопку нулпоинтер эксепшн
вообщем озверин,мало того что ваш код на четверть длинеей так еще и не рабочий
из того что я вижу просто пробежавшись по вашему коду в данный момент
BaseDate -полностью не рабочий
в ботстарте там черт ногу сломит,но в методе команд - вы делаете свитч кейс забывая одно что help and start тянутся из текста ,a остальные значения вытягиваются из callbackquery ,поэтому у вас ничего не работает кроме двух команд хелп и старт,тоже касается почти всех методов .
мапа гетДата тоже не рабочая

пытаетесь записать в базу методом executQuery и тд
26 мар 19, 23:09    [21844357]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
asv79
Member

Откуда: Тверь
Сообщений: 2735
cossack5
asv79,

Список команд на которые будет ругаться executeQuery. Теоретически, можно выполнить TRUNCATE TABLE (но скорее всего, упадает в другом месте).

я нашел почему в его коде ругается Он пытается селектить с помщью executeQuery ))
да там смотреть все равно не что ,так как код полностью не рабочий-оно даже не конектится к базе тут же вываливается
26 мар 19, 23:12    [21844360]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
mayton
Member

Откуда: loopback
Сообщений: 43280
asv79, твоя задача не в том чтобы критиковать код. А в том чтобы разобраться в
"новой магии" которую ты не знал и приспособить для себя как тебе удобно.

А магии этой много. Тебе предлагали code-review
и объясняли преимущества. Бери. Думай. Применяй.
26 мар 19, 23:54    [21844385]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
Озверин
Member

Откуда: Ростов-на-Дону
Сообщений: 5183
asv79, дык я ж не рабочий код даю(так как мне даже проверить его не на чем), а предлагаю, с чего начать рефакторинг и объясняю, почему я это так делаю. Я ошибки не проверяю как бе.
27 мар 19, 00:09    [21844398]     Ответить | Цитировать Сообщить модератору
 Re: Где взять опыт?)  [new]
cossack5
Member

Откуда:
Сообщений: 496
asv79
cossack5
asv79,

Список команд на которые будет ругаться executeQuery. Теоретически, можно выполнить TRUNCATE TABLE (но скорее всего, упадает в другом месте).

я нашел почему в его коде ругается Он пытается селектить с помщью executeQuery ))
да там смотреть все равно не что ,так как код полностью не рабочий-оно даже не конектится к базе тут же вываливается

Просто замените на executeUpdate, делов-то. Я бы вообще использовал jpa или jooq. Еще вместо строки command лучше завести enum Command
 enum Command {
        HELP,
        START;

        @Override
        public String toString() {
            return name().toLowerCase();
        }
    }

и можно сравнивать сравнивать так:
switch (command)
{
case HELP: //do something
break;
case START:  //do something 
break; 
 ...

Еще чтобы избежать свича можно создать мапу:
  public interface TriFunction<A, B, C, R> {
        R apply(A a, B b, C c);
    }

   private static final Map<Command, TriFunction<String, SendMessage, Long, Boolean>> COMMANDS =
            ImmutableMap.of(Command.HELP, 
                    (firstName, message, chatId) ->
                            help(firstName, message, chatId), Command.START,
                    (firstName, message, chatId) -> 
                            start(firstName, message, chatId)
                    /// ...
            );

    private static boolean start(String firstName, SendMessage message, Long chatId) {
        // helstartp
        return true;
    }

    private static boolean help(String firstName, SendMessage message, Long chatId) {
        // help
        return true;
    }

Дале сделать executeCommand таким:
    private boolean executeCommand(String firstName, Command command, SendMessage message, long chatId) {
        return Optional.ofNullable(COMMANDS.get(command))
                .map(c -> c.apply(firstName, message, chatId))
                .orElse(error(message, chatId)
        );

    }

    private boolean error(SendMessage message, long chatId) {
        //
        return true;
    }
27 мар 19, 00:11    [21844400]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 4 5 [6] 7 8 9 10 .. 134   вперед  Ctrl
Все форумы / Java Ответить