JDBC nedir? Java Veritabanı Bağlantısına Giriş

JDBC (Java Veritabanı Bağlantısı), bir veritabanına bağlanmayı, sorguları ve komutları göndermeyi ve veritabanından elde edilen sonuç kümelerini işlemeyi yöneten Java API'sidir. 1997'de JDK 1.1'in bir parçası olarak piyasaya sürülen JDBC, Java kalıcılık katmanı için geliştirilen ilk bileşenlerden biriydi.

JDBC başlangıçta bir istemci tarafı API'si olarak tasarlandı ve bir Java istemcisinin bir veri kaynağıyla etkileşime girmesini sağladı. Bu, sunucu tarafı JDBC bağlantılarını destekleyen isteğe bağlı bir paket içeren JDCB 2.0 ile değişti. O zamandan beri her yeni JDBC sürümü, hem istemci tarafı paketi ( java.sql) hem de sunucu tarafı paketi ( ) için güncellemeler içeriyor javax.sql. Bu yazı itibariyle en güncel sürüm olan JDBC 4.3, Eylül 2017'de Java SE 9'un bir parçası olarak piyasaya sürüldü.

Bu makale, JDBC'ye genel bir bakış sunmakta ve ardından bir Java istemcisini hafif bir ilişkisel veritabanı olan SQLite ile bağlamak için JDBC API'yi kullanmaya yönelik uygulamalı bir giriş sunmaktadır.

JDBC nasıl çalışır?

C tabanlı ODBC (Açık Veritabanı Bağlantısı) API'sine alternatif olarak geliştirilen JDBC, bir veritabanı veya RDBMS ile iletişim kuran Java uygulamalarının mekaniklerini işleyen programlama düzeyinde bir arabirim sunar. JDBC arayüzü iki katmandan oluşur:

  1. JDBC API, Java uygulaması ile JDBC yöneticisi arasındaki iletişimi destekler.
  2. JDBC sürücüsü, JDBC yöneticisi ile veritabanı sürücüsü arasındaki iletişimi destekler.

JDBC, uygulama kodunuzun etkileşimde bulunduğu yaygın API'dir. Bunun altında, kullandığınız veritabanı için JDBC uyumlu sürücü vardır.

Şekil 1, Java kalıcılık katmanındaki JDBC'nin mimari bir genel görünümüdür.

JavaWorld /

Veritabanına bağlanmak için JDBC'yi kullanma

Java ekosisteminde programlamanın şanslı gerçeklerinden biri, seçtiğiniz veritabanı için büyük olasılıkla kararlı bir JDBC veritabanı konektörü bulacağınızdır. Bu eğitimde, JDBC'yi tanımak için SQLite'ı kullanacağız, çünkü kullanımı çok kolay.

JDBC ile bir veritabanına bağlanma adımları aşağıdaki gibidir:

  1. Erişmek istediğiniz veritabanını kurun veya bulun.
  2. JDBC kitaplığını dahil edin.
  3. İhtiyacınız olan JDBC sürücüsünün sınıf yolunuzda olduğundan emin olun.
  4. Veritabanına bir bağlantı elde etmek için JDBC kitaplığını kullanın.
  5. SQL komutlarını vermek için bağlantıyı kullanın.
  6. Bitirdiğinizde bağlantıyı kapatın.

Bu adımları birlikte atacağız.

JDBC sürücüsü bulma

Kullanmak istediğiniz veritabanı için bir sürücü bulmak amacıyla, veritabanınız ve JDBC için bir web araması yapmanız yeterlidir. Örneğin, " mysql jdbc driver" yazmak MySQL için bir sürücü açacaktır. JDBC sürücüsü olmayan Java uyumlu bir veritabanı bulmanız için size meydan okuyorum!

Adım 1. SQLite'ı indirin ve kurun

SQLite çok kompakt bir veritabanıdır. Üretim kullanımı için tasarlanmamıştır, ancak bir şeyleri hızla denemek için harika bir seçimdir. SQLite, herhangi bir hizmet veya arka plan programı kurulumu gerektirmeden bir dosyayı işlevsel veritabanı olarak kullanır.

Bu demoyu kullanmaya başlamak için devam edin ve SQLite örnek veritabanını indirin. Sıkıştırılmış .dbdosya ve onu bir yere unutmayacağım tasarruf.

Bu dosya hem işlevsel bir dosya tabanlı veritabanı hem de örnek şema ve kullanabileceğimiz verileri içerir.

SQL ve JDBC

NoSQL, son on yılda popüler hale geldi, ancak ilişkisel veritabanları, kullanımda olan en yaygın veri deposu türü olmaya devam ediyor. Bir ilişkisel veritabanı , sütunlar ve satırlar tablolarla oluşan yapısal bir depodur. SQL (Yapılandırılmış Sorgu Dili), mimarların ilişkisel bir veritabanında yeni kayıtlar oluşturmak, okumak, güncellemek ve silmek gibi şeyler yapmak için kullandıkları dildir. JDBC, Java'dan SQL'e bir adaptör katmanıdır : Java geliştiricilerine bir veritabanına bağlanmak, sorgular ve komutlar göndermek ve yanıtları yönetmek için ortak bir arayüz sağlar.

Adım 2. JDBC'yi Java uygulamanıza aktarın

Kodlamamızı bir IDE'de yapabilirdik, ancak doğrudan bir metin düzenleyicide kodlama, JDBC'nin basitliğini daha iyi gösterecektir. Başlamak için, işletim sisteminiz için uyumlu bir JDK kurulumuna ihtiyacınız olacak.

Java platformu geliştirici araçlarının kurulu olduğunu varsayarsak, basit bir Java programı oluşturarak başlayabiliriz. Metin düzenleyicinizde Liste 1'de gösterilen kodu yapıştırın. Bu dosyayı arayın WhatIsJdbc.java.

Liste 1. Basit bir Java programı

 class WhatIsJdbc{ public static void main(String args[]){ System.out.println("Hello JavaWorld"); } } 

Şimdi komutunu girerek kod derleme: javac WhatIsJdbc.java. Derleme, WhatIsJdbc.classdosyanın çıktısını verecektir . Çağrısıyla komut satırından bu dosyayı yürütün: java WhatIsJdbc.

[Komut satırında JDK ile etkileşim hakkında daha fazla bilgi için "JDK nedir? Java Geliştirici Kitine Giriş" bölümüne bakın.]

Temel bir Java programına sahip olduğunuzda, JDBC kitaplıklarını dahil edebilirsiniz. Basit Java programınızın başına Liste 2'deki kodu yapıştırın.

Liste 2. JDBC içe aktarmaları

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.sql.Statement; 

Bu içe aktarmaların her biri, standart Java veritabanı bağlantısını kolaylaştıran bir sınıfa erişim sağlar:

  • Connection represents the connection to the database.
  • DriverManager obtains the connection to the database. (Another option is DataSource, used for connection pooling. )
  • SQLException handles SQL errors between the Java application and the database.
  • ResultSet and Statement model the data result sets and SQL statements.

We'll see each of these in action shortly.

Step 3. Add the JDBC driver to your classpath

Next, you'll add the SQLite driver to your classpath. A JDBC driver is a class that implements the JDBC API for a specific database.

Download the SQLite driver from GitHub. Be sure to get the most recent .jar file and store it somewhere you'll remember.

The next time you execute your Java program, you will pull that .jar file in via the classpath. There are several ways to set the classpath. Listing 3 shows how to do it using a command-line switch.

Listing 3. Executing SQLite driver on the Java classpath

 java.exe -classpath /path-to-driver/sqlite-jdbc-3.23.1.jar:. WhatIsJdbc 

Notice that we've set the classpath to point at the driver and the local directory; this way Java will still find our class file.

Step 4. Obtain a database connection

The classpath now has access to the driver. Now, change your simple Java application file to look like the program in Listing 4.

Listing 4. Using the JDBC Connection class to connect to SQLite

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.sql.Statement; class WhatIsJdbc{ public static void main(String[] args) { Connection conn = null; try { String url = "jdbc:sqlite:path-to-db/chinook/chinook.db"; conn = DriverManager.getConnection(url); System.out.println("Got it!"); } catch (SQLException e) { throw new Error("Problem", e); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException ex) { System.out.println(ex.getMessage()); } } } } 

Compile and execute this code. Assuming all goes well, you will get an affirming message.

No suitable driver found?

If you've received an error that looks like "No suitable driver found for jdbc:sqlite," then you need to revisit the classpath and make sure it points to the driver you downloaded. Failed driver connection is the most common stumbling block for beginners using JDBC. Don't sweat it; just fix it.

Now we're ready for some SQL commands.

Step 5. Query the database

With the live connection object in hand, we can do something useful, like querying the database. Listing 5 shows how to query SQLite using the JDBC Connection and Statement objects.

Listing 5. Querying the database with JDBC

 import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.ResultSet; import java.sql.Statement; class WhatIsJdbc{ public static void main(String[] args) { Connection conn = null; try { String url = "jdbc:sqlite:path-to-db-file/chinook/chinook.db"; conn = DriverManager.getConnection(url); Statement stmt = null; String query = "select * from albums"; try { stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String name = rs.getString("title"); System.out.println(name); } } catch (SQLException e ) { throw new Error("Problem", e); } finally { if (stmt != null) { stmt.close(); } } } catch (SQLException e) { throw new Error("Problem", e); } finally { try { if (conn != null) { conn.close(); } } catch (SQLException ex) { System.out.println(ex.getMessage()); } } } } 

In Listing 5 we use our Connection object to obtain a Statement object: conn.createStatement(). We then use this object to execute an SQL query: stmt.executeQuery(query).

The executeQuery command returns a ResultSet object, which we then use to iterate over the data with while (rs.next()). In this example, you should see the album titles we've queried on as output.

Notice that we also closed the connection, via a call to conn.close().

Network connections with JDBC

The database connection string in Listing 5 is for a local connection: jdbc:sqlite:path-to-db-file/chinook/chinook.db. To access the database via a network, the connection string would need to include the network URL and (usually) credentials for accessing it.

Doing more with JDBC

So far we've covered the basics of using JDBC to connect to a database and issue SQL commands. While Statementss and ResultSets work well for common scenarios, you'll likely need additional options for larger or more complex applications. Fortunately, the JDBC library continues evolving to meet most database access needs.

PreparedStatements

One easy way to increase the flexibility of your code is to replace the Statement class with PreparedStatement, as shown in Listing 6.

Listing 6. Using JDBC PreparedStatements

 String prepState = "insert into albums values (?, ?);"; PreparedStatement prepState = connection.prepareStatement(sql); prepState.setString(1, "Uprising"); prepState.setString(2, "Bob Marley and the Wailers "); int rowsAffected = preparedStatement.executeUpdate(); 

PreparedStatement replaces Statement's hard-coded values with question marks (?). Using PreparedStatements optimizes your code for reuse: a PreparedStatement is compiled only once, and can then be reused with a variety of parameters. As your code base grows, you simply insert new values into the statement, instead of hacking the string object itself.

Batch updates

Whenever an application has several updates to issue, doing them in batches can greatly benefit performance. The essence of batching is to take the multiple updates and collect them together, then issue them all at once. Listing 7 uses JDBC's batch methods to perform a batch update of several PreparedStatements.

Listing 7. Batching with PreparedStatement

 prepState.setString(1, "Uprising"); prepState.setString(2, "Bob Marley and the Wailers"); preparedStatement.addBatch(); prepState.setString(1, "Wildflowers"); prepState.setString(2, "Tom Petty and the Heartbreakers"); preparedStatement.addBatch(); int[] rowsAffected = preparedStatement.executeBatch(); 

JDBC transactions

Transactions in relational databases allow for a set of updates to be wrapped in an interaction that either succeeds or fails altogether. The basics of using a transaction via JDBC are to tell the system to turn off auto-commit, and then manually tell the system to commit when you are done. By default, auto-commit is on, which means whenever an executeUpdate or executeInsert is run, the command is committed.

Listing 8 shows a small slice of a JDBC transaction.

Listing 8. JDBC transactions

 connection.setAutoCommit(false); // Use executeUpdate multiple times connection.commit(); 

When connection.commit() is encountered, all the updates wrapped inside will be attempted, and if any fail, they all will be rolled back.

There are many more features in JDBC 4.3 worth exploring, including using CallableStatement for stored procedures, using DataSource objects for improved application performance (especially via connection pooling), and converting a JDBC ResultSet to a Java Stream.

Database-specific features

Although every JDBC-compliant database offers the same core features for connecting and interacting with a database via SQL, some databases do more than others. As an example, Oracle DB offers result caching, which is not required by the JDBC specification. Here's an example:

 conn.prepareStatement ("select /*+ result_cache */ * from employees where employee_id < : 1"); 

This example is taken from the documentation for Oracle's JDBC OCI Driver.

Conclusion

JDBC is one of Java's oldest APIs, providing an easy-to-use solution for one of the perennial needs of Java application development. Knowing just the few JDBC calls demonstrated in this article will get you started using JDBC to connect to virtually any database. Once you've got those commands down, you can begin to explore some of the more sophisticated options that have been built into JDBC.

JDBC, daha basit uygulamalar için yeterli olsa da, çoğu geliştirici, daha resmi bir veri erişim katmanı geliştirmek için sonunda Java Persistence API'ye (JPA) bakacaktır. JPA, daha önceden çalışma ve uygulama mimarisinin daha karmaşık bir şekilde anlaşılmasını gerektirir, ancak size daha tutarlı, izole edilmiş ve iyi tanımlanmış bir veri erişim katmanı sağlar. Java uygulamalarınız için veri kalıcılığı katmanı geliştirme hakkında daha fazla bilgi için "JPA nedir? Java Persistence API'sine Giriş" başlıklı bu makalenin ekine bakın.

Bu hikaye, "JDBC nedir? Java Veritabanı Bağlantısına Giriş" ilk olarak JavaWorld tarafından yayınlanmıştır.