13 Ağustos 2018 Pazartesi

JDBC ResultSet Arayüzü

Giriş
Şu satırı dahil ederiz.
import java.sql.ResultSet;
Veri tabanından SQL sonucunu almak için kullanılır. Bu sınıf using ile kullanılmalı. Şöyle yaparız.
try (Connection con = DriverManager.getConnection("...")) {
  String sql = "select * from ...";
  try (PreparedStatement stmt = con.prepareStatement(sql)) {
    stmt.setInt(1, ...);
    stmt.setString(2, ...);
    try (ResultSet rs = stmt.executeQuery()) {
      while (rs.next()) {
        ...
      }
    }
  }
}
constructor
Select cümlesi ile yaratılabilir.
ResultSet resultSet = statement.executeQuery("select ...);
Bir Statement aynı and tek bir ResultSet döndürebilir. İkinci bir select ilk ResultSet'i kapatır.
String sql = "SELECT * FROM test";
ResultSet resultSet1 = stmt.executeQuery(sql);
ResultSet resultSet2 = stmt.executeQuery(sql);
Eğer resultSet1 nesnesini kullanmaya çalışırsak
while(resultSet.next()) {...}
"Operation not allowed after ResultSet closed" hatasını alırız.

absolute metodu
Belirtilen satır numarasına gider. Row sayıları 1'den başlar. Şöyle yaparız.
if(resultSet.absolute (1)){...}
afterLast metoud
Açıklama yaz

close metodu
Şöyle yaparız.
resultSet.close ();
Nesnenin null olmadığını kontrol etmek iyi bir fikir olabilir çünkü sorgu boş ise nesne null gelebilir.
if (resultSet != null) { resultSet.close (); }
getMetaData metodu
Select cümlesinden sonra kullanılabilir.
ResultSet resultSet = statement.executeQuery("Select * from TABLE_NAME");
ResultSetMetaData metaData = resultSet.getMetaData();
getRow metodu
Row sayıları 1'den başlar. int döner. ResultSet içindeki satır numarasını verir. Şöyle yaparız.
resultSet.getRow ();
getX metodu
ResultSet Arayüzü Sütun İsmi İle Getter Metodları yazısına taşıdım.
ResultSet Arayüzü Sütun Indeksi İle Getter Metodları yazısına taşıdım.

isLast metodu
Açıklama yaz

isFirst metodu
Açıklama yaz

last metodu
Son satırı gider

next metodu
Açıklaması şöyle
Moves the cursor forward one row from its current position. A ResultSet cursor is initially positioned before the first row; the first call to the method next makes the first row the current row; the second call makes the second row the current row, and so on.
Örnek
Elimizde şöyle bir kod olsun.
ResultSet rs = stmt.executeQuery("Select max(Line) as L from logs");
Tek satır sonuç beklendiği için şöyle yaparız.
if (rs.next()) {
    // Access result ...
} else {
    // No match ...
}
Örnek
Eğer birden fazla satır sonuç bekleniyorsa şöyle yaparız.
while (resultSet.next ()) {
  ...
}
relative metodu
Bulunduğumuz satıra göreceli olarak bir önceki, bir sonraki satıra gidebiliriz.

setTimestamp metodu
JDBC sürücüsüleri arasında TimeStamp değerini kaydederken saat diliminin nasıl hesaba katılması konusunda tutarlılık yok. Örneğin MySQL sürücüsü atanan değeri veritabanının saat dilimine göre ayarlıyor.Saat dilimini UTC olarak kaydetmek için aşağıdaki gibi yapılabilir.
stmt.setTimestamp(1, timestamp, Calendar.getInstance(TimeZone.getTimeZone("UTC")))
Calendar parametresi şu işe yarıyor.
With a Calendar object, the driver can calculate the timestamp taking into account a custom timezone. If no Calendar object is specified, the driver uses the default timezone, which is that of the virtual machine running the application.
İleri Geri Gitmek İçin Alanlar
1. TYPE_FORWARD_ONLY
2. TYPE_SCROLL_INSENSITIVE 
3. TYPE_SCROLL_SENSITIVE

Salt Okunur veya Güncelleme İçin Alanlar
1. CONCUR_READONLY
2. CONCUR_UPDATABLE

TYPE_FORWARD_ONLY Alanı
Açıklaması şöyle.
The result set cannot be scrolled; its cursor moves forward only, from before the first row to after the last row. The rows contained in the result set depend on how the underlying database generates the results. That is, it contains the rows that satisfy the query at either the time the query is executed or as the rows are retrieved.
TYPE_SCROLL_INSENSITIVE Alanı
Açıklaması şöyle.
The result can be scrolled; its cursor can move both forward and backward relative to the current position, and it can move to an absolute position. The result set is insensitive to changes made to the underlying data source while it is open. It contains the rows that satisfy the query at either the time the query is executed or as the rows are retrieved.
Aynı Result üzerinden defalarca dolaşabilmek için bu seçeneği kullanabiliriz. Veri istemci tarafında bellekte saklanır. Açıklaması şöyle.
Important: Because all rows of any scrollable result set are stored in the client-side cache, a situation where the result set contains many rows, many columns, or very large columns might cause the client-side Java Virtual Machine (JVM) to fail. Do not specify scrollability for a large result set.
Dolaşmak için ResultSet.last () metodu kullanılarak en sonuncu satıra gidilebilir. Ayrıca ResultSet.getRow() metodu kullanılarak, kaç tane satır döndürüldüğü de bulunabilir.
Örnek
Şöyle yaparız.
PreparedStatement ps = con.prepareStatement(sql,
  ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);    
TYPE_SCROLL_SENSITIVE Alanı
Veri tabanına yapılan güncelleri dolaşırken görebilmeyi sağlar. Açıklaması şöyle. Her seferinde veri tabanına yeni bir "get" yapmak gibi düşünülebilir.
The result can be scrolled; its cursor can move both forward and backward relative to the current position, and it can move to an absolute position. The result set reflects changes made to the underlying data source while the result set remains open.
Örnek
Elimizde tüm sequence değerlerinin saklandığı "SEQUENCE" isimli bir tablo olsun. Şöyle yaparız

- TYPE_SCROLL_SENSITIVE ile biz okurken birisi güncelleme yaparsa, bunu alabilmeyi sağlar. Aslında bu gerekli mi bilmiyorum, çünkü SQL cümlesi zaten "Select for update" .

- CONCUR_UPDATABLE ile "Select" cümlesi çalıştırmamıza rağmen istediğimiz sequence yoksa veri tabanına 1 değerinden başlayacak şekilde ekleyebilmeyi sağlar. Burada setAutoCommit(false); kullanılıyor. Mecburi mi bilmiyorum, ama benim denemelerimde bu olmadan çalışmadı!
String SQL_QUERY =
  "SELECT SEQ_NAME, SEQ_VALUE FROM SEQUENCE WHERE SEQ_NAME = ? FOR UPDATE";

public int nextValue(String sequenceName) throws SQLException {
  try (Connection connection = dataSource.getConnection()) {
    connection.setAutoCommit(false);
    try (PreparedStatement statement =
          connection.prepareStatement(
            SQL_QUERY, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) {
      statement.setString(1, sequenceName);
      try (ResultSet resultSet = statement.executeQuery()) {
        int nextValue = 1;
        if (resultSet.next()) { //Get next value from sequence
          nextValue = 1 + resultSet.getInt(2);
          resultSet.updateInt(2, nextValue);
          resultSet.updateRow();
        } else { //Insert new sequence
          resultSet.moveToInsertRow();
          resultSet.updateString(1, sequenceName);
          resultSet.updateInt(2, nextValue);
          resultSet.insertRow();
        }
        return nextValue;
      }
    } finally {
      connection.commit();
    }
  }
}

Hiç yorum yok:

Yorum Gönder