Java JDBC

Paylaş

Java ile MySQL, Oracle, SQL Server, SQLite gibi veritabanı sistemleri üzerinde veri çekme, listeleme, silme, güncelleme ve veritabanı işlemlerinde kullanılan JDBC API ile ilgili bilgiler yer alıyor.

JDBC nedir?

Java JDBC (Java DataBase Connectivity) MySQL, Oracle, MS SQL Server gibi veritabanlarına bağlanmak veri çekme, listeleme, ekleme, silme, güncelleme gibi işlemleri yapmak için kullanılan pakettir.

JDBC API kullanımı için gerekli olan sınıflar java.sql paketinde yer alır.

JDBC yapısı veritabanından bağımsız olduğundan SQL destekleyen tüm ilişkisel veritabanı ile birlikte çalışır.

Örneğin; MySQL veritabanında yer alan öğrenci listesi Oracle veritabanına taşınıp oradan alınmak istendiğinde sadece bağlantı cümlesinin değiştirilmesi yeterli olacaktır.

JDBC kullanımı

JDBC API kullanımı veritabanı sürücünün yüklenmesi, veritabanı bağlantısı, SQL sorgusunun gönderilmesi ve sonuçların alınması adımlarından oluşur.

Veritabanı bağlantısı için öncelikle kullanılacak olan veritabanı sistemine ait bağlantı sürücüsünün projeye eklenmesi gerekir.

Bu işlem komut yorumlayıcısına jar dosyasının dahil edilmesi, IDE arayüzünde libraries bölümüne eklenmesi veya Maven gibi paket yöneticilerinin kullanımıyla yapılır.

JDBC API içerisinde yer alan DriverManager sınıfı JDBC sürücülerine ulaşmak, veritabanı bağlantısı yapmak ve JDBC ayarları için kullanılır.

DriverManager sınıfında yer alan setLogWriter metodu JDBC işlemleri sırasında oluşan logların yazılacağını yeri tanımlamayı sağlar.

Aşağıdaki tanımla JDBC logları konsol ekranına yazılacaktır.

DriverManager.setLogWriter(new PrintWriter(System.out));

Sürücünün yüklenmesi

Veritabanı sürücüsü için gerekli olan dosyalar yüklendikten sonra veritabanı bağlantı sınıfı projeye dahil edilir.

Class.forName("veritabanı-sürücüsü");

Bazı veritabanı sistemlerine ait sürücü bilgileri aşağıda yer almaktadır.

com.mysql.jdbc.Driver

oracle.jdbc.driver.OracleDriver

org.postgresql.Driver

com.microsoft.sqlserver.jdbc.SQLServerDrive

org.sqlite.JDBC

Diğer yöntem ise jdbc.drivers değerine sürücü sınıfına ait yolu belirtmektir.

public class App {

    static {
        System.setProperty("jdbc.drivers", "org.postgresql.Driver:org.mariadb.jdbc.Driver");
    }

    public static void main(String[] args) {}
}

Yüklü sürücülere DriverManager sınıfında yer alan getDrivers metoduyla erişilir.

public class App {

    static {
        System.setProperty("jdbc.drivers", "org.postgresql.Driver:org.mariadb.jdbc.Driver");
    }

    public static void main(String[] args) {

        DriverManager.setLogWriter(new PrintWriter(System.out));
        Enumeration<Driver> drivers = DriverManager.getDrivers();

        while (drivers.hasMoreElements()) {
            Driver driver = drivers.nextElement();
            System.out.println("Sürücü: " + driver);
            System.out.println("Sürüm: " + driver.getMajorVersion() + "." + driver.getMinorVersion());
        }
    }
}

NOT: Java 6 ile birlikte sürücünün Classs.forName metoduyla yüklenmesine gerek yoktur.

Veritabanı bağlantısı

Sürücünün yüklenmesinden sonra DriverManager sınıfında yer alan getConnection metodu ile veritabanı ile bağlantı sağlanır.

getConnection(String url);

getConnection(String url, Properties info);

getConnection(String url, String user, String password);

Veritabanı bağlantısında kullanılacak bağlantı cümlesi(url) veritabanına göre farklılık gösterir.

Bazı veritabanı sistemlerine ait bağlantı cümlesi aşağıda yer almaktadır.

jdbc:mysql://host:port/?user=&password=

jdbc:mariadb://host:port/?user=&password=

jdbc:oracle:thin:/@::

jdbc:postgresql://host:port/?user=&password=

jdbc:microsoft:sqlserver://host:port;databaseName=?user=&password=

jdbc:db2://host:port/?user=&password=

jdbc:sqlite:

DriverManager sınıfında yer alan getConnection metodu geri dönüş olarak Connection arayüzünü uygulayan bir sınıf döndürür.

public class App {

    public static void main(String[] args) {

        String url = "jdbc:mariadb://localhost:3306/?user=root&password=root";

        try (Connection connection = DriverManager.getConnection(url)) {
            System.out.println("Bağlantı başarıyla sağlandı.");
        } catch (SQLException sqlException) {
            System.err.println(sqlException);
        }
    }
}

Arayüzde yer alan metotlar kullanılarak veritabanı bilgisi ve veritabanı işlemlerinde kullanılacak tanımlara erişilir.

Veritabanı bağlantı bilgisine ulaşmak için getClientInfo metodu kullanılır.

Connection#getClientInfo();

Şema/veritabanı bilgisine ulaşmak için getSchema metodu kullanılır.

Connection#getSchema();

Katalog/veritabanı bilgisine ulaşmak için getCatalog metodu kullanılır.

Connection#getCatalog();

Diğer tüm veritabanı bilgilerine ulaşmak için getMetaData metodu ile elde edilen DatabaseMetaData arayüzü kullanılır.

Connection#getMetaData().getClientInfoProperties();
Connection#getMetaData().getTypeInfo();
Connection#getMetaData().getCatalogs();
Connection#getMetaData().getSchemas();
Connection#getMetaData().getTableTypes();
Connection#getMetaData().getTypeInfo();
Connection#getMetaData().getDriverName();
Connection#getMetaData().getDriverVersion();

Sınıf veritabanına sorgu göndermek için kullanılan Statement, PreparedStatement, CallableStatement arayüzlerini uygulayan sınıfları döndürür.

Statement statement = connection.createStatement();

PreparedStatement preparedStatement = connection.prepareStatement("sql-komutları");

CallableStatement callableStatement = connection.prepareCall("sql-komutları");

Veritabanı işlemleri bittikten sonra close metodu ile bağlantının kapatılması faydalı olacaktır.

connection.close();

JDBC veritabanı işlemlerinde kullanılan Connection, Statement, PreparedStatement, CallableStatement ve ResultSet gibi arayüzler AutoCloseable arayüzünü kullandıklarından dolayı Java try-with-resources özelliğiyle işlem tamamlandığında kaynakların iade edilmesini sağlar.

Statement

Arayüz sql komutlarını veritabanına göndermek için çeşitli metotları tanımlar.

statement.execute("sql-komutları");

Komut sonucu ResultSet ise true, güncelleme sayısı(update, delete) veya sonuç yok ise false döndür.

SQL komut türüne göre sonuçlar aşağıdaki metotlarla alınır.

statement.getResultSet();

statement.getMoreResults();

statement.getUpdateCount();

Doğrudan veri çekme(SELECT) veya veri listeme işlemi için executeQuery metodu kullanılabilir.

statement.executeQuery("sql-komutları");

Veri ekleme, veri güncelleme ve veri silme işlemi sonrası eklenen, güncellenen veya silinen kayıt sayısı bilgisi için executeUpdate metodu kullanılabilir.

statement.executeUpdate("sql-komutları");

Birden fazla-toplu işlem yapmak için executeBatch metodu kullanılır.

statement.executeBatch();

Metodu kullanabilmek için komutların addBatch metodu ile eklenmesi gerekir.

statement.addBatch("komut-1");
statement.addBatch("komut-2");
statement.addBatch("komut-3");
statement.executeBatch();

Sorgu işlemleri bittikten sonra close metodu ile kapatılarak geçici bilgilerin silinmesi faydalı olacaktır.

statement.close();

PreparedStatement

Arayüz sql komutlarını veritabanına göndermek için Statement arayüzünü kalıtım alarak çeşitli metotları tanımlar.

Statement arayüzünde kullanılan bir çok metot bu sınıf ile birlikte kullanılabilir.

Arayüzün Statement arayüzünden farkı yazılan sql komutların tekrar tekrar kullanılabilir olmasını sağlamasıdır.

PreparedStatement preparedStatement = connection.prepareStatement("sql-komutları");

Arayüz SQL komutlarında yer alan alanlara değer atamak için setVeriTipi(setString, setInt) metotlarına sahiptir.

Örnek kullanım aşağıdaki gibidir.

String sql = "INSERT INTO kisiler(kisi_adi, kisi_soyadi, kisi_eposta) VALUES(?, ?, ?)";

PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "Yusuf");
preparedStatement.setString(2, "Sezer");
preparedStatement.setString(3, "[email protected]");

Değerler atandıktan sonra komut türüne göre execute, executeUpdate veya executeQuery metotları ile komut çalıştırılır.

boolean preparedStatement.execute();

ResultSet preparedStatement.executeQuery();

int preparedStatement.executeUpdate();

Yazılan komutları tekrar kullanmak için alanlara gerekli değerler tekrar atanır ve komut tekrar çalıştırılır.

preparedStatement.setString(1, "Yusuf Sefa");
preparedStatement.setString(2, "Sezer");
preparedStatement.setString(3, "[email protected]");
preparedStatement.executeUpdate();

CallableStatement

Arayüz saklı yordam komutlarını veritabanına göndermek için çeşitli metotları tanımlar.

CallableStatement callableStatement = connection.prepareCall("{ CALL SP_KISI_EKLE(?, ?, ?)}");
callableStatement.setString(1, "Yusuf");
callableStatement.setString(2, "Sezer");
callableStatement.setString(3, "[email protected]");
callableStatement.executeUpdate();

Saklı yordam çalıştırıldıktan sonra OUT ile işaretlenen parametreleri almak için paremetre registerOutParameter metodu ile belirtilmelidir.

callableStatement.registerOutParameter(1, java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(2, java.sql.Types.VARCHAR);
callableStatement.registerOutParameter(3, java.sql.Types.DATE);

Parametreler belirtildikten sonra getVeriTipi metotları ile değer alınır.

callableStatement.getString(1);
callableStatement.getString(2);
callableStatement.getDate(3);

ResultSet

JDBC kullanarak veri çekme işlemi sonrasında veri listelemek için ResultSet sınıfı kullanılır.

Sınıf veriler üzerinde dolaşmak için next, first, last, previous, absolute gibi metotlara sahiptir.

Veritabanı sütunlarında yer alan verileri almak için getVeriTipi metotları kullanılır.

Metotların kullanımı sütun-adı ve sütün-sırası olmak üzere iki türlüdür.

ResultSet resultSet = statement.executeQuery("SELECT * FROM kisiler");

int sira;
String adi;
String soyadi;
String eposta;
while (resultSet.next()) {
    sira = resultSet.getInt(1);
    adi = resultSet.getString(2);
    soyadi = resultSet.getString("kisi_soyadi");
    eposta = resultSet.getString(4);

    System.out.println(sira + " " + adi + " " + soyadi + ", " + eposta);
}

Veriler ve tablo hakkında detaylı bilgi almak için getMetaData metodu ile elde edilen ResultSetMetaData arayüzü kullanılır.

ResultSet#getMetaData().getColumnCount();
ResultSet#getMetaData().getColumnType();
ResultSet#getMetaData().getColumnLabel();
ResultSet#getMetaData().getColumnName();
ResultSet#getMetaData().getColumnClassName();
ResultSet#getMetaData().getColumnTypeName();

JDBC Örnekleri

Aşağıda veri ekleme, veri silme, veri güncelleme ve veri listeleme ile ilgili bilgiler yer alıyor.

Aşağıda veri ekleme işlemi yapılmıştır.

public class JavaJDBC {

    public static void main(String[] args) {

        String url = "jdbc:mysql://localhost:3306/kisi";
        String user = "root";
        String password = "";

        try {
            Class.forName("com.mysql.jdbc.Driver");

            Connection connection = DriverManager.getConnection(url, user, password);

            Statement statement = connection.createStatement();

            String sql = "INSERT INTO "
                    + "kisiler(kisi_adi, kisi_soyadi, kisi_eposta) "
                    + "VALUES('Yusuf', 'Sezer', '[email protected]')";

            System.out.println(statement.executeUpdate(sql) + " kayıt eklendi.");

            statement.close();
            connection.close();

        } catch (ClassNotFoundException | SQLException ex) {
            System.err.println(ex);
        }
    }
}

Aşağıda veri silme işlemi yapılmıştır.

// Diğer komutlar

String sql = "DELETE FROM kisiler WHERE kisi_eposta = '[email protected]'";

System.out.println(statement.executeUpdate(sql) + " kayıt silindi.");

// Diğer komutlar

Aşağıda veri güncelleme işlemi yapılmıştır.

// Diğer komutlar

String sql = "UPDATE kisiler "
        + "SET kisi_adi = 'Yusuf Sefa', kisi_soyadi = 'Sezer' "
        + "WHERE kisi_eposta = '[email protected]'";

System.out.println(statement.executeUpdate(sql) + " kayıt güncellendi.");

// Diğer komutlar

Aşağıda veri listeleme işlemi yapılmıştır.

// Diğer komutlar

ResultSet resultSet = statement.executeQuery("SELECT * FROM kisiler");

int sira;
String adi;
String soyadi;
String eposta;
while (resultSet.next()) {
    sira = resultSet.getInt(1);
    adi = resultSet.getString(2);
    soyadi = resultSet.getString(3);
    eposta = resultSet.getString(4);

    System.out.println(sira + " " + adi + " " + soyadi + ", " + eposta);
}

// Diğer komutlar

Son

JDBC esnek yapısı ile bir çok veritabanı sistemi ile birlikte çalışabilmektedir.

Ancak veritabanında yapılan değişiklikler, veritabanı tablolarında yer alan sütunların eşleştirilmesi(map edilmesi) sırasında beklenmedik hatalar olabilir.

Bu durum için çeşitli ORM kütüphanelerini(Hibernate, jOOQ, EclipseLink) kullanmak faydalı olacaktır.

JDBC örneğine buradan ulaşabilirsiniz.

Java Derslerine buradan ulaşabilirsiniz.

Hayırlı günler dilerim.


Bunlarda ilgini çekebilir