Статьи

Java 8 пятничные вкусности: лямбды и SQL

В Data Geekery мы любим Java. И так как мы действительно входим в свободный API jOOQ и запросы DSL , мы абсолютно взволнованы тем, что Java 8 принесет в нашу экосистему. Мы пару раз писали о приятных вкусностях Java 8 , и теперь мы чувствуем, что пришло время начать новую серию блогов,…

Ява 8 Пятница

Каждую пятницу мы показываем вам пару замечательных новых функций Java 8 в виде учебника, в которых используются лямбда-выражения, методы расширения и другие замечательные вещи. Вы найдете исходный код на GitHub .

Java 8 Goodie: лямбды и SQL

Если вы привыкли писать на Groovy, это может показаться вам «так 2003». Мы знаем. Groovy с самого начала знал очень полезный способ написания SQL на основе строк. Вот пример, написанный на Groovy ( см. Официальные документы здесь ):

1
2
3
4
5
6
7
8
9
import groovy.sql.Sql
sql = Sql.newInstance(
    'jdbc:h2:~/test', 'sa', '',
    'org.h2.Driver' )
sql.eachRow(
    'select * from information_schema.schemata'
) {
    println "$it.SCHEMA_NAME -- $it.IS_DEFAULT"
}

Обратите внимание также на встроенную в Groovy строковую интерполяцию, где вы можете помещать выражения в строки. Но мы находимся в среде Java, и с Java 8 дела обстоят лучше и в интеграции Java / SQL, если мы будем использовать сторонние библиотеки вместо JDBC напрямую.

В следующих примерах мы рассмотрим, как извлекать данные из базы данных H2 и отображать записи в пользовательские POJO / DTO с помощью этих трех популярных библиотек:

Как всегда, источники также доступны на GitHub . Для этих тестов мы создаем небольшой POJO / DTO, чтобы обернуть метаинформацию схемы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
class Schema {
    final String schemaName;
    final boolean isDefault;
 
    Schema(String schemaName, boolean isDefault) {
        this.schemaName = schemaName;
        this.isDefault = isDefault;
    }
 
    @Override
    public String toString() {
        return "Schema{" +
               "schemaName='" + schemaName + '\'' +
               ", isDefault=" + isDefault +
               '}';
    }
}

Наш основной метод получит соединение H2 через DriverManager :

1
2
3
4
5
6
7
8
9
Class.forName("org.h2.Driver");
try (Connection c = getConnection(
        "jdbc:h2:~/test", "sa", "")) {
 
  String sql = "select schema_name, is_default "+
               "from information_schema.schemata "+
               "order by schema_name";
  // Library code here...
}

Теперь, как Java 8 улучшает API jOOQ при использовании SQL на основе строк? Сильно! Проверьте следующий маленький запрос:

1
2
3
4
5
6
7
DSL.using(c)
   .fetch(sql)
   .map(r -> new Schema(
       r.getValue("SCHEMA_NAME", String.class),
       r.getValue("IS_DEFAULT", boolean.class)
   ))
   .forEach(System.out::println);

Так должно быть, верно? Обратите внимание, что нативные API jOOQ также могут отображать Record базы данных непосредственно в ваш POJO, как таковой:

1
2
3
4
DSL.using(c)
   .fetch(sql)
   .into(Schema.class)
   .forEach(System.out::println);

Вещи выглядят так же хорошо, когда делают то же самое с Spring JDBC и RowMapper (обратите внимание, что следующие броски проверяют SQLException s):

1
2
3
4
5
6
7
8
new JdbcTemplate(
        new SingleConnectionDataSource(c, true))
    .query(sql, (rs, rowNum) ->
        new Schema(
            rs.getString("SCHEMA_NAME"),
            rs.getBoolean("IS_DEFAULT")
        ))
    .forEach(System.out::println);

… и если вы используете Apache DbUtils , вы можете сделать почти то же самое:

1
2
3
4
5
6
7
8
new QueryRunner()
    .query(c, sql, new ArrayListHandler())
    .stream()
    .map(array -> new Schema(
        (String) array[0],
        (Boolean) array[1]
    ))
    .forEach(System.out::println);

Вывод

Все три решения более или менее эквивалентны и достаточно просты. Суть в том, что Java 8 улучшит все существующие API. Чем больше однозначных (несколько перегрузок!) Методов, принимающих аргументы SAM (одиночные абстрактные типы методов), тем лучше для интеграции с Java 8.

На следующей неделе мы увидим несколько вещей, которые значительно улучшатся при использовании API java.util.Map .

Ссылка: Java 8 Friday Goodies: Lambdas и SQL от нашего партнера по JCG Лукаса Эдера в блоге JAVA, SQL и AND JOOQ .