Есть некоторые незначительные потенциальные опасности, связанные с ключевым словом def Groovy. Руководства по стилю и языку для Groovy для Java-разработчиков содержат некоторые предупреждения об использовании def . В этом сообщении в блоге я продемонстрирую преимущество более явного ввода при использовании Groovy SQL с базой данных Oracle, чтобы избежать потенциального исключения SQLException « Недопустимый индекс столбца », поскольку я сталкивался с этой проблемой несколько раз.
Следующий скрипт Groovy предоставляет комментарии к таблицам базы данных Oracle, соответствующим заданной строке поиска. В этом случае действия сценария не так важны, как просмотр кода, определяющего строку запроса SQL (строки 18-21).
searchDbComments.groovy (используя def без ввода String или как String)
|
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
|
#!/usr/bin/env groovy// searchDbComments.groovythis.class.classLoader.rootLoader.addURL( new URL("file:///C:/oraclexe/app/oracle/product/11.2.0/server/jdbc/lib/ojdbc6.jar"))if (args.length < 1){ println "USAGE: searchDbComments.groovy <searchString>" System.exit(-1)}def searchString = args[0].toUpperCase()import groovy.sql.Sqldef sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr", "oracle.jdbc.pool.OracleDataSource")def dbTableCommentsQry = """SELECT table_name, table_type, comments FROM user_tab_comments WHERE UPPER(comments) LIKE '%${searchString}%'"""sql.eachRow(dbTableCommentsQry){ println "${it.table_name} (${it.table_type}): ${it.comments}"} |
Когда приведенный выше код выполняется, генерируется следующая ошибка:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
WARNING: Failed to execute: SELECT table_name, table_type, comments FROM user_tab_comments WHERE UPPER(comments) LIKE '%?%' because: Invalid column indexCaught: java.sql.SQLException: Invalid column indexjava.sql.SQLException: Invalid column index at oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.java:5303) at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8323) at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8259) at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9012) at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:8993) at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:230) at searchDbComments.run(searchDbComments.groovy:23) |
Адресация «недопустимого индекса столбца» SQLException проста. Одним из решений является изменение «def» в строках 18-21 на явный тип «String». Другое решение, показанное в следующем листинге кода, состоит в том, чтобы использовать ключевое слово « as » в Groovy, чтобы явно использовать «def» и dbTableCommentsQry переменная dbTableCommentsQry была напечатана как String.
searchDbComments.groovy (используется как строка)
|
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
|
#!/usr/bin/env groovy// searchDbComments.groovythis.class.classLoader.rootLoader.addURL( new URL("file:///C:/oraclexe/app/oracle/product/11.2.0/server/jdbc/lib/ojdbc6.jar"))if (args.length < 1){ println "USAGE: searchDbComments.groovy <searchString>" System.exit(-1)}def searchString = args[0].toUpperCase()import groovy.sql.Sqldef sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr", "oracle.jdbc.pool.OracleDataSource")def dbTableCommentsQry = """SELECT table_name, table_type, comments FROM user_tab_comments WHERE UPPER(comments) LIKE '%${searchString}%'""" as Stringsql.eachRow(dbTableCommentsQry){ println "${it.table_name} (${it.table_type}): ${it.comments}"} |
Использование только «def» или отсутствие «def» без типа приводит к вышеуказанной ошибке. Явное определение переменной String, используемой в запросе посредством статической типизации или использования ключевого слова « as », позволяет коду выполняться правильно. Можно использовать статическую типизацию с «def», но это считается избыточным.
В использовании « def » нет ничего плохого, но нужно быть осторожным с его применением. Гийом Лафорж писал, что «def подходит для тел методов или для определенных динамических аспектов, но для всего, что является« контрактом »(сигнатуры методов, свойства и т. Д.), Лучше использовать явные типы».