Реформа SQL-ориентированного подхода в DAO

Комментарии (10)

  • 12 июня 2017 в 16:53 (комментарий был изменён)

    +1

    При наличии парсера запроса немного странным выглядит необходимость указания его типа (type = QT_SELECT). Его можно из запроса извлечь.


    А также, не пробовали получить названия параметров методов, чтобы явно не писать в аннотации TargetFilter имена? Вроде это можно.

    • 12 июня 2017 в 17:17

      0

      >Его можно из запроса извлечь

      В общем случае — нельзя. Хранимая процедура может возвращать результат как select, а может и нет. Узнать вы это можете —, но только при выполнении.

    • 12 июня 2017 в 17:42

      0

      А также, не пробовали получить названия параметров методов, чтобы явно не писать в аннотации TargetFilter имена

      В семерке, не знаю как в 8–9, есть такой аттрибут (речь про формат .class) MethodParameters в котором есть часть, отвечающая за имя параметра:
      MethodParameters_attribute {
             u2 attribute_name_index;
             u4 attribute_length;
             u1 parameters_count;
             {   u2 name_index;
                 u2 access_flags;
             } parameters[parameters_count];
         }
      

      name_index — это индекс указывает на значение в ConstantPool, где храниться имя параметра, но в описании этого элемента имеем:
      The value of the name_index item must either be zero or a valid index into
      the constant_pool table.
      На своем опыте скажу, что частенько встречал 0, вместо реально-ожидаемых значений. Поэтому, отвечая на Ваш 2ой вопрос, скажу НЕТ. Если же имеется альтернативный способ извлечения, подскажите, буду Вам признателен.
  • 12 июня 2017 в 16:58 (комментарий был изменён)

    +1

    Согласен и подумаю как справить. Сейчас это проблема связанна с тем, что выбор стратегии работы с типом SQL-запроса начинается задолго до непосредственного разбора самого запроса. промахнулся
  • 12 июня 2017 в 17:16

    +1

    >ограничить поддерживаемый набор SQL конструкций

    А вы уверены, что не потеряете при этом всю расширенную функциональность конкретной реализации?

    • 12 июня 2017 в 17:28

      0

      А вы уверены, что не потеряете при этом всю расширенную функциональность конкретной реализации?

      Да нет конечно. Вы только гляньте на примерный обзор возможных конструкций в том или ином диалекте. Здесь и десятка людей не хватит, чтобы их все поддерживать. Здесь возможен на мой взгляд только компромисс и точечный выбор специфичных, но ЧАСТО используемых вещей, вроде постраничной разбивки, определенных форматов тип данных (даты, время). Возможно что-то еще. Но в целом, если придерживаться стандарта SQL-92, то думаю можно поддерживать оговоренную функциональность

  • 12 июня 2017 в 17:49

    +1

    очень похоже на mybatis. и кстати, т.н. «динамические фильтры» идут там из коробки.
    • 12 июня 2017 в 18:10

      0

      Когда готовил статью, я погружался в парадигму того или иного существующего фреймворка, где-то, чтобы просто освежить память, с чем-то просто никогда не работал. Мне кажется, то, что Вы называете динамическими фильтрами в MyBatis суть Dynamic SQL и кодить там все же придется, но в xml. Из достоинств Dynamic SQL — достаточно неплохой язык выражений и допускает его быстрое расширение, если потребуется. Но ключевое слово здесь кодить. С похожестью, наверное я не соглашусь, он просто другой.
      • 12 июня 2017 в 19:25

        0

        Мне кажется, то, что Вы называете динамическими фильтрами в MyBatis суть Dynamic SQL и кодить там все же придется, но в xml

        Не понимаю, что в вашем представлении значит «кодить». Написание SQL к кодингу не относится?
        Есть ещё один известный мне способ делать запросы с динамической подстановкой параметров — Sql Provider:
        @InsertProvider(type=ContactMapperSqlProvider.class, method=ContactMapperSqlProvider.CREATE_CONTACT_QUERY_NAME)
        Long createContact(Contact contact);
        ...
        class ContactMapperSqlProvider{
                private static final String CREATE_CONTACT_QUERY_NAME = "createContact";
        
                public String createContact(Contact contact){
                    return new SQL() {{
                        INSERT_INTO("TUTORS");
                        VALUES("name", "#{name}").VALUES("surname", "#{surname}").VALUES("patronymic", "#{patronymic}").VALUES("description", "#{description}")
                            .VALUES("user_id", "#{user.id}");
                        if (contact.getBirthDate() != null)
                            VALUES("birthday", "#{birthday}");
                    }}.toString();
                }
            }
        

        Чем то похоже на Criteria API в JPA/Hibernate, но выглядит симпатичнее
        • 12 июня 2017 в 19:36

          0

          Да в том то и дело
               if (contact.getBirthDate() != null) VALUES("birthday", "#{birthday}");
          
          Под этим я и понимаю кодинг — именно наличие оператора if.
          Разумеется, указывать сам параметр и его значение в том или ином виде при любом подходе придется, другое дело для того же батиса, кто им мешал сделать так:
               // как вариант N1
               VALUES("birthday", "#{birthday}?");
               // или так как другой вариант N2
               VALUES("birthday", "#{birthday or nothing}");
          
          или еще, как-то, более декларативно, согласно их представлениям понятия краткости и лаконичности.
          Самое главное, я ни в коем случае не пытаюсь приуменьшить значение батиса для эко системы java, не подумайте или какого-либо другого фреймворка. Более того, я даже очень рад, что нам с Вами есть что сравнивать и из чего выбирать

© Habrahabr.ru