В Data Geekery мы любим Java. И так как мы действительно входим в свободный API jOOQ и запросы DSL , мы абсолютно взволнованы тем, что Java 8 принесет в нашу экосистему.
Ява 8 Пятница
Каждую пятницу мы показываем вам пару замечательных новых функций Java 8 в виде учебника, в которых используются лямбда-выражения, методы расширения и другие замечательные вещи. Вы найдете исходный код на GitHub .
JavaScript идет SQL с Nashorn и JOOQ
На этой неделе мы рассмотрим некоторые замечательные серверные сценарии SQL с Nashorn и Java 8. В Интернете можно найти лишь несколько вещей, касающихся использования JDBC в Nashorn. Но зачем использовать JDBC и заботиться о болезненном управлении ресурсами и составлении строк SQL, когда вы можете использовать jOOQ ? Все работает из коробки!
Давайте настроим небольшой пример файла JavaScript так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
var someDatabaseFun = function() { var Properties = Java.type("java.util.Properties"); var Driver = Java.type("org.h2.Driver"); var driver = new Driver(); var properties = new Properties(); properties.setProperty("user", "sa"); properties.setProperty("password", ""); try { var conn = driver.connect( "jdbc:h2:~/test", properties); // Database code here } finally { try { if (conn) conn.close(); } catch (e) {} }}someDatabaseFun(); |
Это почти все, что вам нужно для взаимодействия с JDBC и базой данных H2. Таким образом, мы могли бы выполнять операторы SQL с JDBC следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
try { var stmt = conn.prepareStatement( "select table_schema, table_name " + "from information_schema.tables"); var rs = stmt.executeQuery(); while (rs.next()) { print(rs.getString("TABLE_SCHEMA") + "." + rs.getString("TABLE_NAME")) }}finally { if (rs) try { rs.close(); } catch(e) {} if (stmt) try { stmt.close(); } catch(e) {}} |
Большая часть этой проблемы связана с обработкой ресурсов JDBC, поскольку, к сожалению, у нас нет оператора try-with-resources в JavaScript. Выше генерируется следующий вывод:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
INFORMATION_SCHEMA.FUNCTION_COLUMNSINFORMATION_SCHEMA.CONSTANTSINFORMATION_SCHEMA.SEQUENCESINFORMATION_SCHEMA.RIGHTSINFORMATION_SCHEMA.TRIGGERSINFORMATION_SCHEMA.CATALOGSINFORMATION_SCHEMA.CROSS_REFERENCESINFORMATION_SCHEMA.SETTINGSINFORMATION_SCHEMA.FUNCTION_ALIASESINFORMATION_SCHEMA.VIEWSINFORMATION_SCHEMA.TYPE_INFOINFORMATION_SCHEMA.CONSTRAINTS... |
Давайте посмотрим, сможем ли мы выполнить тот же запрос, используя jOOQ :
|
1
2
3
4
5
6
7
|
var DSL = Java.type("org.jooq.impl.DSL");print( DSL.using(conn) .fetch("select table_schema, table_name " + "from information_schema.tables")); |
Вот как вы можете выполнять простые операторы SQL в jOOQ, с гораздо меньшим раздуванием, чем в JDBC. Вывод примерно такой же:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
+------------------+--------------------+|TABLE_SCHEMA |TABLE_NAME |+------------------+--------------------+|INFORMATION_SCHEMA|FUNCTION_COLUMNS ||INFORMATION_SCHEMA|CONSTANTS ||INFORMATION_SCHEMA|SEQUENCES ||INFORMATION_SCHEMA|RIGHTS ||INFORMATION_SCHEMA|TRIGGERS ||INFORMATION_SCHEMA|CATALOGS ||INFORMATION_SCHEMA|CROSS_REFERENCES ||INFORMATION_SCHEMA|SETTINGS ||INFORMATION_SCHEMA|FUNCTION_ALIASES | ... |
Но сила jOOQ заключается не в его простых возможностях SQL, а в API DSL, который абстрагирует все тонкости SQL, специфичные для поставщика, и позволяет быстро составлять запросы (а также DML). Рассмотрим следующий оператор SQL:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// Let's assume these objects were generated// by the jOOQ source code generatorvar Tables = Java.type( "org.jooq.db.h2.information_schema.Tables");var t = Tables.TABLES;var c = Tables.COLUMNS;// This is the equivalent of Java's static importsvar count = DSL.count;var row = DSL.row;// We can now execute the following query:print( DSL.using(conn) .select( t.TABLE_SCHEMA, t.TABLE_NAME, c.COLUMN_NAME) .from(t) .join(c) .on(row(t.TABLE_SCHEMA, t.TABLE_NAME) .eq(c.TABLE_SCHEMA, c.TABLE_NAME)) .orderBy( t.TABLE_SCHEMA.asc(), t.TABLE_NAME.asc(), c.ORDINAL_POSITION.asc()) .fetch()); |
Обратите внимание, что в приведенном выше запросе очевидно нет безопасности типов, так как это JavaScript. Но я бы предположил, что создатели IntelliJ, Eclipse или NetBeans в конечном итоге обнаружат зависимости Nashorn от Java-программ и обеспечат автоматическое завершение и выделение синтаксиса, поскольку некоторые вещи можно анализировать статически.
Все становится еще лучше, если вы используете Java 8 Streams API от Nashorn. Давайте рассмотрим следующий запрос:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
DSL.using(conn) .select( t.TABLE_SCHEMA, t.TABLE_NAME, count().as("CNT")) .from(t) .join(c) .on(row(t.TABLE_SCHEMA, t.TABLE_NAME) .eq(c.TABLE_SCHEMA, c.TABLE_NAME)) .groupBy(t.TABLE_SCHEMA, t.TABLE_NAME) .orderBy( t.TABLE_SCHEMA.asc(), t.TABLE_NAME.asc())// This fetches a List<Map<String, Object>> as// your ResultSet representation .fetchMaps()// This is Java 8's standard Collection.stream() .stream()// And now, r is like any other JavaScript object// or record! .forEach(function (r) { print(r.TABLE_SCHEMA + '.' + r.TABLE_NAME + ' has ' + r.CNT + ' columns.'); }); |
Выше генерирует этот вывод:
|
1
2
3
4
5
6
7
8
9
|
INFORMATION_SCHEMA.CATALOGS has 1 columns.INFORMATION_SCHEMA.COLLATIONS has 2 columns.INFORMATION_SCHEMA.COLUMNS has 23 columns.INFORMATION_SCHEMA.COLUMN_PRIVILEGES has 8 columns.INFORMATION_SCHEMA.CONSTANTS has 7 columns.INFORMATION_SCHEMA.CONSTRAINTS has 13 columns.INFORMATION_SCHEMA.CROSS_REFERENCES has 14 columns.INFORMATION_SCHEMA.DOMAINS has 14 columns.... |
Если ваша база данных поддерживает массивы, вы даже можете получить доступ к таким столбцам массива по индексу, например,
|
1
|
r.COLUMN_NAME[3] |
Так что, если вы являетесь поклонником JavaScript на стороне сервера, скачайте jOOQ сегодня и начните писать потрясающий SQL на JavaScript прямо сейчас! Чтобы узнать больше о Nashorn, прочитайте эту статью здесь .
| Ссылка: | Java 8, пятница: JavaScript идет вместе с Nashorn и jOOQ от нашего партнера по JCG Лукаса Эдера из блога JAVA, SQL и AND JOOQ . |