在Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。
Java 8星期五
每个星期五,我们都会向您展示一些不错的教程风格的Java 8新功能,这些功能利用了lambda表达式,扩展方法和其他好东西。 您可以在GitHub上找到源代码 。
JavaScript与Nashorn和jOOQ一起使用SQL
本周,我们将研究使用Nashorn和Java 8的一些很棒的服务器端SQL脚本。在Web上,关于Nashorn中使用JDBC的信息很少。 但是,当可以使用jOOQ时,为什么还要使用JDBC并处理痛苦的资源管理和SQL字符串组成呢? 开箱即用!
让我们像这样建立一个样本JavaScript文件:
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数据库进行互操作所需要的全部。 因此,我们可以使用JDBC运行SQL语句,如下所示:
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资源处理,因为不幸的是我们在JavaScript中没有try-with-resources语句。 上面产生了以下输出:
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
INFORMATION_SCHEMA.VIEWS
INFORMATION_SCHEMA.TYPE_INFO
INFORMATION_SCHEMA.CONSTRAINTS
...
让我们看看是否可以使用jOOQ运行相同的查询:
var DSL = Java.type("org.jooq.impl.DSL");
print(
DSL.using(conn)
.fetch("select table_schema, table_name " +
"from information_schema.tables")
);
这就是您可以在jOOQ中执行普通SQL语句的方法,其膨胀程度远低于JDBC。 输出大致相同:
+------------------+--------------------+
|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功能,而在于DSL API,该API提取了所有特定于供应商的SQL细节,并允许您流畅地编写查询(以及DML)。 考虑以下SQL语句:
// Let's assume these objects were generated
// by the jOOQ source code generator
var 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 imports
var 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程序的依赖关系,并提供语法自动完成和突出显示功能,因为可以对某些内容进行静态分析。
如果您使用Nashorn的Java 8 Streams API,情况将会变得更好。 让我们考虑以下查询:
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.');
});
上面产生了这个输出:
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.
...
如果您的数据库支持数组,您甚至可以按索引访问此类数组列,例如
r.COLUMN_NAME[3]
因此,如果您是服务器端JavaScript爱好者,请立即下载jOOQ ,然后立即开始用JavaScript编写出色的 SQL! 有关Nashorn的更多信息,请考虑在此处阅读此文章 。
翻译自: https://www.javacodegeeks.com/2014/06/java-8-friday-javascript-goes-sql-with-nashorn-and-jooq.html