다른 사람들이 말했듯이 외부 try
는 필요하지 않지만 코드는 기본적으로 정확합니다 . 몇 가지 생각이 더 있습니다.
DataSource
여기의 다른 답변은 bpgergo 의 허용되는 답변 과 같이 정확하고 좋습니다 . 그러나 현대 자바에서의 DataSource
사용보다 일반적으로 권장 되는의 사용을 보여주지는 않습니다 DriverManager
.
완성도를 높이기 위해 데이터베이스 서버에서 현재 날짜를 가져 오는 전체 예제가 있습니다. 여기에 사용 된 데이터베이스는 Postgres 입니다. 다른 데이터베이스도 비슷하게 작동합니다. 사용을 데이터베이스 org.postgresql.ds.PGSimpleDataSource
에 DataSource
적합한 구현으로 대체하십시오 . 해당 경로로 이동하면 특정 드라이버 또는 연결 풀에서 구현이 제공 될 수 있습니다.
DataSource
구현은 필요 하지 가 "오픈 없다"결코 때문에 폐쇄 될 수있다. A DataSource
는 리소스가 아니며 데이터베이스에 연결되어 있지 않으므로 데이터베이스 서버의 네트워킹 연결이나 리소스를 보유하지 않습니다. A DataSource
는 데이터베이스 서버의 네트워크 이름 또는 주소, 사용자 이름, 사용자 암호 및 연결시 원하는 다양한 옵션을 사용하여 데이터베이스에 연결할 때 필요한 정보입니다. 따라서 DataSource
구현 객체는 리소스 사용 시도 괄호 안에 들어 가지 않습니다 .
중첩 된 리소스 사용 가능
코드는 중첩 된 try-with-resources 문을 올바르게 사용합니다.
아래 예제 코드에서 try-with-resources 구문을 두 번 사용 하고 하나는 다른 하나 안에 중첩되어 있습니다. 외부는 try
두 가지 자원을 정의 Connection
하고 PreparedStatement
. 내부 try
는 ResultSet
리소스를 정의합니다 . 이것은 일반적인 코드 구조입니다.
내부 예외에서 예외가 발생하여 발견되지 않으면 ResultSet
자원이 자동으로 닫힙니다 (있는 경우 null이 아님). 그 후에 는 닫히고 PreparedStatement
마지막으로 Connection
닫힙니다. 리소스는 try-with-resource 문에서 선언 된 순서와 반대로 자동으로 닫힙니다.
여기 예제 코드는 지나치게 단순합니다. 작성된 것처럼, 단일 try-with-resources 문으로 실행될 수 있습니다. 그러나 실제 작업에서는 중첩 된 try
통화 쌍간에 더 많은 작업을 수행 할 수 있습니다 . 예를 들어, 사용자 인터페이스 또는 POJO에서 값을 추출한 후 메소드 ?
호출을 통해 SQL 내에서 자리 표시자를 이행하도록 값을 전달할 수 PreparedStatement::set…
있습니다.
구문 메모
세미콜론 후행
try-with-resources의 괄호 안에 마지막 자원 설명 뒤에 오는 세미콜론은 선택 사항입니다. 일관성과 완성도를 높이고 줄 끝 세미콜론에 대해 걱정할 필요없이 여러 줄을 쉽게 복사하여 붙여 넣을 수 있습니다. IDE는 마지막 세미콜론을 불필요한 것으로 플래그 지정할 수 있지만, 그대로두면 아무런 해가 없습니다.
Java 9 – try-with-resources에서 기존 변수 사용
Java 9의 새로운 기능은 리소스를 사용하여 시도하는 구문이 향상되었습니다. 이제 try
문장 의 괄호 밖에서 리소스를 선언하고 채울 수 있습니다 . 나는 이것이 JDBC 자원에 유용하다는 것을 아직 알지 못했지만 자신의 작업에서 명심하십시오.
ResultSet
자체를 닫아야하지만 그렇지 않을 수 있습니다
이상적인 세계 ResultSet
에서는 문서가 약속 한대로 닫힙니다.
ResultSet 오브젝트는이를 생성 한 Statement 오브젝트가 닫히거나 다시 실행되거나 여러 결과 시퀀스에서 다음 결과를 검색하는 데 사용될 때 자동으로 닫힙니다.
불행하게도, 과거에 일부 JDBC 드라이버는이 약속을 이행하지 못한 것으로 악명 높았습니다. 그 결과, 많은 JDBC 프로그래머는 다음과 같은 명시 적으로 가까운 모든 JDBC 리소스에 배운 Connection
, PreparedStatement
및 ResultSet
도. 현대의 리소스에 대한 try-with-resources 구문을 사용하면보다 쉽고 간단한 코드를 사용할 수 있습니다. Java 팀은으로 표시하는 것을 귀찮게 ResultSet
했으며이를 AutoCloseable
활용하는 것이 좋습니다. 모든 JDBC 자원 주위에 자원 사용 시도를 사용하면 의도와 관련하여 코드를 자체 문서화 할 수 있습니다.
코드 예
package work.basil.example;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.Objects;
public class App
{
public static void main ( String[] args )
{
App app = new App();
app.doIt();
}
private void doIt ( )
{
System.out.println( "Hello World!" );
org.postgresql.ds.PGSimpleDataSource dataSource = new org.postgresql.ds.PGSimpleDataSource();
dataSource.setServerName( "1.2.3.4" );
dataSource.setPortNumber( 5432 );
dataSource.setDatabaseName( "example_db_" );
dataSource.setUser( "scott" );
dataSource.setPassword( "tiger" );
dataSource.setApplicationName( "ExampleApp" );
System.out.println( "INFO - Attempting to connect to database: " );
if ( Objects.nonNull( dataSource ) )
{
String sql = "SELECT CURRENT_DATE ;";
try (
Connection conn = dataSource.getConnection() ;
PreparedStatement ps = conn.prepareStatement( sql ) ;
)
{
… make `PreparedStatement::set…` calls here.
try (
ResultSet rs = ps.executeQuery() ;
)
{
if ( rs.next() )
{
LocalDate ld = rs.getObject( 1 , LocalDate.class );
System.out.println( "INFO - date is " + ld );
}
}
}
catch ( SQLException e )
{
e.printStackTrace();
}
}
System.out.println( "INFO - all done." );
}
}
try (ResultSet rs = ps.executeQuery()) {
므로 inner가 필요하지 않습니다.