Seperti yang telah dinyatakan orang lain, kode Anda pada dasarnya benar meskipun bagian luar try
tidak diperlukan. Ini beberapa pemikiran lagi.
DataSource
Jawaban lain di sini benar dan bagus, seperti yang diterima oleh bpgergo. Tapi tidak ada yang menunjukkan penggunaan DataSource
, lebih sering direkomendasikan daripada penggunaan DriverManager
di Jawa modern.
Jadi demi kelengkapan, berikut adalah contoh lengkap yang mengambil tanggal saat ini dari server database. Basis data yang digunakan di sini adalah Postgres . Basis data lain mana pun akan bekerja dengan cara yang sama. Anda akan mengganti penggunaan org.postgresql.ds.PGSimpleDataSource
dengan implementasi yang DataSource
sesuai dengan database Anda. Suatu implementasi kemungkinan disediakan oleh pengemudi khusus Anda, atau kumpulan koneksi jika Anda pergi rute itu.
Sebuah DataSource
implementasi perlu tidak ditutup, karena tidak pernah “dibuka”. A DataSource
bukan sumber daya, tidak terhubung ke database, jadi ia tidak memegang koneksi jaringan atau sumber daya pada server database. A DataSource
hanyalah informasi yang diperlukan ketika membuat koneksi ke database, dengan nama atau alamat jaringan server database, nama pengguna, kata sandi pengguna, dan berbagai opsi yang ingin Anda tentukan ketika suatu koneksi akhirnya dibuat. Jadi DataSource
objek implementasi Anda tidak masuk ke dalam tanda kurung coba-dengan-sumber daya Anda.
Bersarang coba-dengan-sumber daya
Kode Anda digunakan dengan benar untuk pernyataan try-with-resources bersarang.
Perhatikan pada contoh kode di bawah ini bahwa kami juga menggunakan sintaks coba sumber daya dua kali , satu bersarang di dalam yang lain. Bagian luar try
mendefinisikan dua sumber daya: Connection
dan PreparedStatement
. Batin try
mendefinisikan ResultSet
sumber daya. Ini adalah struktur kode yang umum.
Jika pengecualian dilemparkan dari dalam, dan tidak ditangkap di sana, ResultSet
sumber daya akan secara otomatis ditutup (jika ada, bukan nol). Setelah itu, PreparedStatement
akan ditutup, dan terakhir Connection
ditutup. Sumber daya secara otomatis ditutup dalam urutan terbalik yang dinyatakan dalam pernyataan coba-dengan-sumber daya.
Contoh kode di sini terlalu sederhana. Seperti yang tertulis, itu dapat dieksekusi dengan pernyataan coba-dengan-sumber daya tunggal. Tetapi dalam pekerjaan nyata Anda mungkin akan melakukan lebih banyak pekerjaan di antara pasangan try
panggilan yang bersarang . Misalnya, Anda mungkin mengekstraksi nilai dari antarmuka pengguna atau POJO, dan kemudian meneruskannya untuk memenuhi ?
placeholder dalam SQL Anda melalui panggilan ke PreparedStatement::set…
metode.
Catatan sintaks
Mengejar titik koma
Perhatikan bahwa koma yang membuntuti pernyataan sumber daya terakhir dalam tanda kurung sumber daya percobaan adalah opsional. Saya memasukkannya ke dalam karya saya sendiri karena dua alasan: Konsistensi dan kelihatannya lengkap, dan itu membuat copy-paste campuran garis lebih mudah tanpa harus khawatir tentang titik koma akhir-line. IDE Anda mungkin menandai titik koma terakhir sebagai berlebihan, tetapi tidak ada salahnya meninggalkannya.
Java 9 - Gunakan vars yang ada di try-with-resources
Baru di Java 9 adalah penyempurnaan dari sintaks coba sumber daya. Kami sekarang dapat mendeklarasikan dan mengisi sumber daya di luar tanda kurung try
pernyataan. Saya belum menemukan ini berguna untuk sumber daya JDBC, tetapi perlu diingat dalam pekerjaan Anda sendiri.
ResultSet
harus menutup sendiri, tetapi mungkin tidak
Dalam dunia yang ideal itu ResultSet
akan menutup sendiri sesuai dengan yang dijanjikan dokumentasi:
Objek ResultSet ditutup secara otomatis ketika objek Pernyataan yang dihasilkannya ditutup, dijalankan kembali, atau digunakan untuk mengambil hasil berikutnya dari urutan beberapa hasil.
Sayangnya, di masa lalu beberapa driver JDBC terkenal gagal memenuhi janji ini. Akibatnya, banyak programmer JDBC belajar untuk secara eksplisit menutup semua sumber daya JDBC mereka termasukConnection
, PreparedStatement
dan ResultSet
juga. Sintaks coba-dengan-sumber daya modern telah membuatnya menjadi lebih mudah, dan dengan kode yang lebih ringkas. Perhatikan bahwa tim Java bersusah payah menandai ResultSet
sebagai AutoCloseable
, dan saya sarankan kita memanfaatkannya. Menggunakan coba-dengan-sumber daya di sekitar semua sumber daya JDBC Anda membuat kode Anda lebih mendokumentasikan diri sendiri tentang niat Anda.
Contoh kode
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()) {
karena objek ResultSet secara otomatis ditutup oleh objek Pernyataan yang menghasilkannya