Есть некоторые незначительные потенциальные опасности, связанные с ключевым словом 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.groovy this . 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.Sql def 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 index Caught: java.sql.SQLException: Invalid column index java.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.groovy this . 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.Sql def 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 String sql.eachRow(dbTableCommentsQry) { println "${it.table_name} (${it.table_type}): ${it.comments}" } |
Использование только «def» или отсутствие «def» без типа приводит к вышеуказанной ошибке. Явное определение переменной String, используемой в запросе посредством статической типизации или использования ключевого слова « as », позволяет коду выполняться правильно. Можно использовать статическую типизацию с «def», но это считается избыточным.
В использовании « def » нет ничего плохого, но нужно быть осторожным с его применением. Гийом Лафорж писал, что «def подходит для тел методов или для определенных динамических аспектов, но для всего, что является« контрактом »(сигнатуры методов, свойства и т. Д.), Лучше использовать явные типы».