Статьи

Расширенный Java Trickery для Typesafe Query DSL

Просматривая  Hacker News , я недавно наткнулся на наиболее интересную попытку Бенджи Вебера по  созданию безопасных взаимодействий баз данных с Java 8 . Бенджи создал тип DSL безопасного запроса, несколько похожий на  jOOQ,  с тем важным отличием, что он использует  ссылки  на методы Java 8 для самоанализа POJO и вывода из него элементов запроса. Это лучше всего объяснить на примере:

Optional<Person> person = 
    from(Person.class)
        .where(Person::getFirstName)
        .like("%ji")
        .and(Person::getLastName)
        .equalTo("weber")
        .select(
            personMapper, 
            connectionFactory::openConnection);

Приведенный выше запрос может быть преобразован в следующий оператор SQL:

SELECT * FROM person 
WHERE first_name LIKE ? AND last_name = ?

Это действительно очень интересный подход, и мы видели подобные идеи раньше. Наиболее заметно, что такие идеи были реализованы в:

  • JaQu , еще один очень интересный конкурентный продукт  jOOQ , созданный Томасом Мюллером, сопровождающим популярную  базу данных H2
  • LambdaJ , попытка перенести лямбда-выражения в Java задолго до Java 8
  • OhmDB , новое хранилище данных NoSQL с быстрым запросом DSL

Новым в подходе Бенджи является тот факт, что  ссылки на методы Java 8  можно использовать вместо обращения к  CGLIB  и другим видам хитрости байт-кода с помощью инструментария. Примером такого трюка является экспериментальный самоанализ байт-кода JaQu для преобразования сложных логических выражений Java в SQL,  называемый «естественным синтаксисом» :

Timestamp ts = 
  Timestamp.valueOf("2005-05-05 05:05:05");
Time t = Time.valueOf("23:23:23");

long count = db.from(co).
    where(new Filter() { public boolean where() {
        return co.id == x
            && co.name.equals(name)
            && co.value == new BigDecimal("1")
            && co.amount == 1L
            && co.birthday.before(new Date())
            && co.created.before(ts)
            && co.time.before(t);
        } }).selectCount();

Хотя с этими идеями, безусловно, очень интересно играть, мы сомневаемся, что такие преобразования языка и байт-кода приведут к надежным результатам. Люди критикуют  использование Hibernate прокси  в  различных сообщениях в блогах .

Мы предпочитаем   подход WYSIWYG, при котором потребители API полностью контролируют происходящее. Что вы думаете о таких умных идеях?