Merhabalar.

Bu yazıda sizlere JDBI Kütüphanesi‘nden bahsetmeye ve kayıt ekleme işlemini anlatmaya çalışacağım.

JDBI Nedir?

Günümüz Java dünyasında veritabanı ile çalışan projeler veritabanı ile iletişim için ne kullandıkları farketmeksizin en temel katmanda JDBC kullanmaktadırlar. Kurumsal projelerde kullanılan ORM frameworkleri de (Hibernate, Eclipselink, MyBatis vs.) tabanda JDBC üzerinde çalışmaktadır. Aynı şekilde JDBI da JDBC katmanı üzerinde çalışan ve veritabanı işlemleri gerçekleştirmeyi sağlayan bir kütüphanedir.

JDBI geliştiricilerinin amacı JDBC’nin sağladığı avantajları daha da kolaylaştırarak geliştiriciye sağlamaktır. Bu işlem için de beanler (pojo sınıfları) ve collection sınıflarını kullanarak yapmayı uygun görmüşler.

Aynı zamanda JDBI bize veri tabanı işlemlerimizi bir Interface içerisinde tanımlayıp implementasyonunu JDBI’a yaptırarak bakımı çok daha kolay kodlar yazma imkanı sunar.

JDBI İle Kayıt Ekleme

JDBI’ın ne olduğunu gördükten sonra JDBI kayıt ekleme işlemini örnekleyen bir uygulama yapalım. Ben bu ve gelecek yazılar için MySQL veritabanı sunucusu üzerindeki bir veritabanı kullanacağım.

Öncelikle bir adet JDBIDatabase adında veritabanı oluşturdum. Arından da şu kod ile people adında bir tablo oluşturdum.

CREATE TABLE `JDBIDatabase`.`people` 
( `id` INT NOT NULL AUTO_INCREMENT , 
`name` VARCHAR(25) NOT NULL , 
`surname` VARCHAR(25) NOT NULL , 
`city` VARCHAR(25) NOT NULL , PRIMARY KEY (`id`)) 
ENGINE = InnoDB;

People tablosunda id isminde bir Primary Key olacak ve bunun yanında name, surname ve city kolonları olacak.

Şimdi IDE’niz içerisinde bir Maven projesi oluşturun ve pom.xml dosyasını açıp bu yazının yazıldığı an itibari ile en güncel olan şu bağımlılık kodunu ekleyin.

<dependency>
    <groupId>org.jdbi</groupId>
    <artifactId>jdbi</artifactId>
    <version>2.77</version>
</dependency>

Local Maven reponuzda bu kütüphane yoksa projeye sağ tıklayıp Clean&Build seçeneğine tıklayın.

Şimdi veritabanındaki People tablosuna karşılık gelen Person sınıfını oluşturalım:

package com.ilkaygunel.jdbitutorial.pojo;

public class Person {

    private int id;
    private String name;
    private String surname;
    private String city;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

}

Şimdi veritabanı işlemlerimizi gerçekleştirmek için bir Interface tanımlayalım. Bu Interface içerisinde JDBI’a ait SQL Object API adı verilen bir mekanizma kullanacağız. Başlangıç için kodumuz şu şekilde olsun:

package com.ilkaygunel.jdbitutorial.operation;

import org.skife.jdbi.v2.sqlobject.Bind;
import org.skife.jdbi.v2.sqlobject.SqlUpdate;

public interface PersonOperationsInterface {
    @SqlUpdate("insert into people(name,surname,city) values(:name,:surname,:city)")
    public int insertRecord(@Bind("name") String name,@Bind("surname") String surname,@Bind("city") String city);
    
    void close();
}

PersonOperationsInterface içerisinde insertRecord adında bir metot tanımlı. Bu metot @SqlUpdate notasyonu ile işaretli. Klasik JDBC’de Select işlemi executeQuery metodu ile, diğer 3 işlem ise executeUpdate metodu ile yapılabiliyor. Burada da aynı mantık geçerli ve kayıt ekleme işlemi için metodumuzu SqlUpdate notasyonu ile işaretledik. @SqlUpdate notasyonu içerisine çalıştırılarak SQL cümleciğini parametre olarak alır. Insert işleminde veritabanına işlenecek kayıtlar da values içerisinde önlerine iki nokta koyularak tanımlanır. Klasik JDBC’de bu işlem PreparedStatement kullanılırsa soru işareti ve preparedStatement.setString() gibi metotlar ile yapılıyordu. Akabinde bu SQL cümleciği içerisinde tanınlanmış olan değerlerin metodun parametre kısmında @Bind notasyonu ile de tanımlanması gerekiyor. Herhangi bir yerden bu metot çağırıldığında öncelikle gelen değerler metodun parametre kısmında iletilecek, akabinde @Bind notasyonu vasıtası ile SQL cümleciğine geçirilecek. Bu nedenle @Bind notasyonunun aldığı parametreler ile SQL cümleciğindeki iki nokta ile başlayan parametrelerin kesinlikle aynı olması gerekir.

Interface içerisinde bir de close metodu tanımlı. JDBI bu metodu kullanarak tabandaki JDBC bağlantısını kapatacak.

Şimdi bir de InsertRecordOperation sınıfı oluşturalım ve bu metodun çağırılmasını görelim.

package com.ilkaygunel.jdbitutorial.operation;

import com.mysql.cj.jdbc.MysqlDataSource;
import org.skife.jdbi.v2.DBI;

public class InsertRecordOperation {

    public static void main(String[] args) {
        MysqlDataSource mysqlDataSource = new MysqlDataSource();
        mysqlDataSource.setURL("jdbc:mysql://localhost:3306/JDBIDatabase");
        mysqlDataSource.setUser("root");
        mysqlDataSource.setPassword("");

        DBI dbi = new DBI(mysqlDataSource);

        PersonOperationsInterface personOperationsInterface = null;

        try {
            personOperationsInterface = dbi.open(PersonOperationsInterface.class);
            personOperationsInterface.insertRecord("Can", "Kahveci", "Trabzon");
            System.out.println("The Record Inserted Successfully!");
        } catch (Exception e) {
            System.err.println("An Error Occured!\n Error is:" + e);
        } finally {
            if (personOperationsInterface != null) {
                personOperationsInterface.close();
            }
        }
    }
}

JDBI ile bir veritabanı işlemi gerçekleştireceğimiz zaman kullandığımız veritabanına göre bir DataSource oluşturmamız gerekiyor. Bu örnek için biz MySQL veritabanı kullanıyoruz ve bu nedenle bir MySqlDataSource nesnesi oluşturuyoruz. Bu nesnenin setURL metodu ile database linkini veriyoruz, setUser metodu ile database kullanıcısı ve setPassword metodu ile database parolasını tanımlıyoruz. Biz her ne kadar burada direk String olarak veritabanı kullanıcı adı ve şifresini yazmış olsak da proje geliştirirken bunların bir dosyadan okunup bildirilmesi daha iyi ve geçerlidir.

Akabinde bir adet DBI nesnesini DBI sınıfının yapılandırıcısına MySqlDataSource nesnesini vererek oluşturuyoruz. Bu nesne MySqlDataSource’u kullanarak bizi veritabanına ulaştıracak.

Akabinde PersonOperationsInterface tipinde bir nesne tanımlıyoruz.

try bloğu içerisinde dbi.open(PersonOperationsInterface.class) metodu ile JDBI’a PersonOperationsInterface arabirimindeki metotları implemente ettiriyoruz ve personOperationsInterface nesnesinin içini dolduruyoruz. Bu işlemden sonra da personOperationsInterface nesnesi üzerinden insertRecord metodunu parametrelerini vererek çağırıyoruz. İşlem başarılı olursa kod bir sonraki satıra geçip ekrana başarılı bilgisini yazdıracak. Eğer hata meydana gelirse catch’e girip hatayı ekrana yazıdracak. Son olarak finally bloğu içerisnde de JDBI tarafından içi doldurulan personOperationsInterface nesnesini kapatıyoruz.

Şimdi bu main metodunu çalıştıralım.

Kayıt başarı ile girildi mesajını aldık. Bir de veritabanını kontrol edelim.

Veritabanında kayıt başarılı ile girilmiş görünüyor.

Her zaman sadece bir bir kayıt girilmesi durumu yeterli olmuyor, çoklu kayıt girilmesi gerekebiliyor. Bu durum için de JDBI bir kolaylık sağlamış durumda. PersonOperationsInterface arabirimine şu 2 satır kodu ekleyelim:

@SqlBatch("insert into people(name,surname,city) values(:name,:surname,:city)")
public void insertAll(@BindBean List<Person> personList);

Birden fazla kayıt eklenecek ise öncelikle bu işlemi yapacak metot @SqlBatch metodu ile işaretlenir. Bu notasyona tek kayıt eklerkenki gibi SQL cümleceğini veriyoruz. Metodumuzun parametre kısmında ise bir personList geçiriyoruz ve bu listeyi @BindBean notasyonu ile işaretliyoruz. @BindBean notasyonu bu metot tetiklendiğinde @SqlBatch’e listeyi geçirecek ve listedeki tüm değerler veritabanına işlenecek.

Şimdi InsertMultipleRecords adında bir sınıf oluşturalım ve içeriğini şöyle güncelleyelim:

package com.ilkaygunel.jdbitutorial.operation;

import com.ilkaygunel.jdbitutorial.pojo.Person;
import com.mysql.cj.jdbc.MysqlDataSource;
import java.util.ArrayList;
import java.util.List;
import org.skife.jdbi.v2.DBI;

public class InsertMultipleRecordsOperation {
    public static void main(String[] args) {
        MysqlDataSource mysqlDataSource = new MysqlDataSource();
        mysqlDataSource.setURL("jdbc:mysql://localhost:3306/JDBIDatabase");
        mysqlDataSource.setUser("root");
        mysqlDataSource.setPassword("");

        DBI dbi = new DBI(mysqlDataSource);

        PersonOperationsInterface personOperationsInterface = null;

        try {
            List<Person> personList = new ArrayList<>();
            for (int i = 0; i < 2; i++) {
                Person person = new Person();
                person.setId(i);
                person.setName("Vedat");
                person.setSurname("Gülmez");
                person.setCity("izmir");
                
                personList.add(person);
            }
            
        
            personOperationsInterface = dbi.open(PersonOperationsInterface.class);
            personOperationsInterface.insertAll(personList);
            System.out.println("The Records Inserted Successfully!");
        } catch (Exception e) {
            System.err.println("An Error Occured!\n Error is:" + e);
        } finally {
            if (personOperationsInterface != null) {
                personOperationsInterface.close();
            }
        }
    }
}

Sınıfımız içerisinde hemen hemen tüm işlemler tek kayıt ekleme ile aynı. Farklı olarak try içinde personList listesini oluşturup dolduruyoruz ve insertAll metoduna listeyi geçiriyoruz. Kodu çalıştırdığımızda konsol çıktımız şu şekilde oluyor:

Veritabanını kontrol ettiğimizde de kayıtlar gerçekten girilmiş görünüyor.

Bu yazıda anlatacaklarım bu kadar arkadaşlar. Bir ve birden fazla kayıt JDBI ile nasıl eklenir onu görmüş olduk. Gelecek yazıda kayıt çekme işlemlerine değineceğiz.

Görüşmek üzere

Selam ve Sevgilerimle