29 Haziran 2015 Pazartesi

Sistem Saatini Değiştirmek

Giriş
Normalde sistem saati ile oynamamak gerekir. NTP kurarak bu iş halledilir. Ancak birçok işletim sistemi sistem saatini değiştirmek için API de sunar. Sistem saatini almakla ilgili Epoch ve API başlıklı yazıya da göz atabilirsiniz.

Java
Java'da sistem saatini değiştirmek için bir API yok. Ancak harici bir uygulama kullanılarak bu iş yapılabilir. Windows'ta şöyle yaparız.
Runtime.getRuntime().exec("cmd /C date " + strDateToSet); // dd-MM-yy
Runtime.getRuntime().exec("cmd /C time " + strTimeToSet); // hh:mm:ss
Linux'ta ise şöyle yaparız.
Runtime.getRuntime().exec("date -s " + strDateTimeToSet); // MMddhhmm[[yy]yy]
Windows
SetSystemTime
C# örneği
[DllImport("kernel32.dll", SetLastError = true)]
extern static uint SetSystemTime(ref SYSTEMTIME systime);

private struct SYSTEMTIME
{
  public ushort wYear;
  public ushort wMonth;
  public ushort wDayOfWeek;
  public ushort wDay;
  public ushort wHour;
  public ushort wMinute;
  public ushort wSecond;
  public ushort wMilliseconds;
}

SYSTEMTIME systime = new SYSTEMTIME();
//..Populate systime
SetSystemTime(ref systime);

25 Haziran 2015 Perşembe

JVM Havuzları

Not : JVM ile ilgili tanımlamaları burada gördüğüm sözlükten okumak mümkün.

Komut Satırından Java Kaynak Dosyaları Derlemek
src altındaki bazı kaynak dosyaları derlemek için

set sourcefiles = src\main.java src\another.java
javac -d bin -cp lib\myjar.jar;lib\myotherjar.jar -sourcepath src -verbose %sourcefiles%


Java ClassPath
JVM ile alakası yok ancak not almak istedim. Bir jar dosyasını çalıştırmak için iki yol var. İlkinde CLASSPATH ortam değişkeni ile yüklenecek jar dosyalarının bulunduğu dizin belirtilir. Örnek:

set CLASSPATH=D:\Mylib\
Daha sonra java MyApp şeklinde çalıştırılır. 

İkincisinde ise jar dosyaları -cp ile belirtilir. Örnek:


Linux'ta ; yerine : karakteri kullanılır.Örnek:

Daha sonra yine aynı şekilde java MyApp şeklinde çalıştırılır.

JVM açılış ayarları
JVM hiç parametre kullanmadan açılırsa, mevcut belleğin belli yüzdelerini kullanacağını farz ederek açılır. Aşağıda JVM'in oluşturduğu alanlar ve büyüklüklerini atama örnekleri var.
 
Young Generation Nedir?

Bir çok nesnenin çok kısa süreliğine kullanılıp tekrar yok olacağı farz ediliyor. Bu kısa ömürlü nesneler Young Generation denilen havuzda toplanırlar. Young Generation iki kısımdan oluşuyor. Eden ve Survivor.

Eden:
Burada anlatıldığına göre Eden ismi nesneler burada doğdukları için verilmiş. Eğer nesne hayatta kalırlarsa "Young Generation" içindeki diğer alanlara  gönderilirler.

 Survivor:
Survivor da kendi içinde to ve from isimli iki havuzdan oluşuyor.

 
Permenant Generation Nedir ?
Bu konuda bir sürü karmaşık yazı var. Benim anladığım işin özeti şöyle. Eğer bir yazılımda çok fazla yüklenecek class ya da string varsa bazen bu hata alınabiliyor. Tek yapılması gereken -XX:MaxPermSize=128M gibi bir parametre ile daha yüksek bir değer vermek.

-Xmx işe yaramaz ! Boşuna uğraşmayın...

Burada da classloader'ın nasıl çalıştığı anlatılıyor.

Aşağıda buradan aldığım bir şekil var ve durumu çok güzel anlatıyor.

Tüm Heap

Tüm Heap'in büyüklüğünü almak için aşağıdaki kod parçası çalıştırılabilir.

Runtime rt = Runtime.getRuntime();
long maxMb = rt.maxMemory()/(1024*1024);
Old Generation Nedir?

Uzun ömürlü nesneler Old Generation denilen havuzda toplanırlar.


Young + Old Generation Büyüklüğünü Ayarlamak

-Xms500m : Bu alanın başlangıç büyüklüğünü ayarlar.
why jvm consume less memory than -Xms speicified? sorusunda da gösterildiği gibi top komutuyla bakılınca VIRT sütunu altındaki değer -Xms ile atanan değerden daha büyük olmalı.

-Xmx1024m : Bu alanın azami büyüklüğünü ayarlar
Bu ayarlar ile java.lang.OutOfMemoryError: Java heap space diye başlayan exceptionlardan genellikle kurtulmak mümkün oluyor. Şöyle kullanırız
$ java -Xms1025k -Xmx1025k -XshowSettings:vm  MyApp

32 bit JVM'ler için bu alanın alacağı en büyük değer -Xmx1628m civarında. Yani 1.6 gigabyte.
Verilen değer uygulama içinde şöyle görülebilir.
Runtime.getRuntime().maxMemory()

Young + Old Generation Büyüklüğünü Yüzde Olarak Ayarlamak

JVM hafıza alanlarını işletim sisteminden bir kere alınca, normal şartlar altında kullanmasa bile işletim sistemine iade etmek zorunda değildir. Ancak

-XX:MinHeapFreeRatio (default is 40)   ve
-XX:MaxHeapFreeRatio (default is 70)

seçenekleri ise kullanılmayan alanın geri verilmesi sağlanabilir. Örneğin ilk açılışta çok bellek lazımdır ve üst sınır yüksek tutulmalıdır. Ancak daha sonra bu kadar bellek gerekmez ve "boş alan" miktarı artar. Bu durumda JVM kullanmadığı alanları işletim sistemine geri verirse, diğer uygulamalar daha rahat çalışırlar.

Garbage Collector
GC elle optimize edilen koda göre her zaman daha yavaştır. Ancak optimizasyon herkesin harcı olmadığı için GC her zaman daha yavaştır anlamına gelmez.

Çoğu GC gerçekleştirimleri tek thread ile çalışır.

Garbage Collection ve Strong Reference

Strong Reference bir nesneye Root Set tarafından direkt erişilebilmesi demek. Bu tür nesneler GC tarafından yok edilmezler. Aşağıdaki şekilde Root Set tarafından Strong Reference ile erişilebilen nesneleri görmek mümkün.

Bir diğer şekilde ise aynı durumu bu sefer GC tarafından yok edilecek nesneler ile birlikte görmek mümkün. Özellikle birbirine strong reference ile bağlı olan 3 nesnenin oluşturduğu adacığın Root Set'e bağlı olmadıkları için kırmızı ile işaretlendiğine dikkat etmek lazım.


Thread'ler bir şekilde çalıştıkları müddetçe, strong reference'a sahipler. Thread yarattıktan sonra, herhangi bir referans tutulmasa bile, thread nesnesi çalıştığı müddetçe garbage collection'a uğramaz.

Unmanaged Resource'lar
Disposable başlıklı yazıya bakabilirsiniz.

JVM Environment Variables
Windows altında heap boyunu ayarlamak için eğer Oracle JVM kullanılıyorsa _JAVA_OPTIONS değişkeni atanabilir.
Headless Mode
Bu modda çalıştırılan java uygulamasına display ve keyboard verilmez. Örnek:


23 Haziran 2015 Salı

String Algoritmaları - Harf Çevrimi

TitleCase
Her kelimenin ilk harfini büyük harfe çevirir.

C#
Şöyle yaparız
string title = "war and peace";
TextInfo textInfo = new CultureInfo("en-US", false).TextInfo;
title = textInfo.ToTitleCase(title); //War And Peace
Eğer kendimiz yazmak isteseydik şöyle yapardık.
IEnumerable<char> CharsToTitleCase(string s)
{
    bool newWord = true;
    foreach(char c in s)
    {
        if(newWord) { yield return Char.ToUpper(c); newWord = false; }
        else yield return Char.ToLower(c);
        if(c==' ') newWord = true;
    }
}
Bu kodu şöyle kullanırız.
var asTitleCase = new string( CharsToTitleCase(myText).ToArray() );




21 Haziran 2015 Pazar

Concurrent Collections

Not 1:  Java'da Concurrent Kuyruk konusu geniş olduğu için ayrı bir yazı olarak buraya taşıdım.
Not 2: C#'ta Concurrent Kuyruk konusu geniş olduğu için ayrı bir yazı olarak buraya taşıdım.
Not 3: Actor Model'de shared state olmaz.

Kuyruk Teorisi
Kuyruk teorisi veri yapısı ile ilgili değil. Ancak dolaylı olarak kuyruğun ne kadar büyük olması gerektiği ve bekleme süresini matematiksel olarak gösterdiği için bilinmesi faydalı. M/M/1 kuyruğu bu teoride kullanılan basit bir kuyruk.

Amdalh Kanunu
Bu kanunda concurrent programlama modeline geçilse bile hızın paralelleştirilemeyen kod parçasına bağımlı olduğu belirtilmiş.Örneğin sadece %50'si paralelleştirilebilen bir kod parçasına 16 işlemci ekleyerek 2 kat hızlanma elde edilir. Bundan sonra eklenen işlemci sayısının bir etkisi olmaz.

Concurrent Collections
Aşağıda çeşitli dillerde gördüğüm concurrent veri yapıları ile ilgili aldığım notlar var. Öncelikle ACE, Java ve C# arasındaki temel felsefe farkına dikkat etmek lazım.

ACE kütüphanesi, strategy örüntüsünü izleyerek veri yapısına dışarıdan kilitleme mekanizmasının geçilmesi felsefesini benimsemiş. Böylece aynı veri yapısı, kullanıcının isteğine göre thread-safe olarak veya olmayarak kullanılabiliyor.

Java ve C# ise veri yapılarının thread-safe olan ve olmayan 2 farklı sınıfını sunuyor.

ACE ACE_Map_Manager
Örneği buradan aldım.

//Eğer istenirse
//ACE_Null_Mutex
//ACE_Thread_Mutex
//ACE_Recursive_Thread_Mutex
//ACE_RW_Mutex kullanılabilir
typedef ACE_Map_Manager<unsigned long, std::string, ACE_Thread_Mutex> StringMap; 
StringMap m_MapInstance;

typedef StringMap::lock_type ACE_MAP_LOCK_TYPE;
//Create a guard
ACE_Guard<ACE_MAP_LOCK_TYPE> l(m_MapInstance.mutex());
for(StringMap::iterator it = m_MapInstance.begin(), end = m_MapInstance.end(); it!=end; ++it)
{
    const std::string & strContent = (*it).int_id_;
    const unsigned long & ulID = (*it).ext_id_;
    //do something with the element here
}
C# Partitioner
Range Partitioning, Chunk Partitioning algoritmaları var.

EnumerablePartitionerOptions sınıfı

NoBuffering seçeneği
Eğer listedeki elemanları teker teker thread'lere dağıtmak istersek aşağıdaki gibi yapabiliriz.
List<string> _files = new List<string>();
Parallel.ForEach(Partitioner.Create(_files, EnumerablePartitionerOptions.NoBuffering),
                new ParallelOptions
                {
                    MaxDegreeOfParallelism = 5 //limit number of parallel threads
                },
                (file, loopstate, index) =>
                {
                    if (token.IsCancellationRequested)
                        return;
                    //do work...
                });


C# ConcurrentBag
Bu sınıf bag olduğu için sırasız yani unordered bir veri yapısı. Object Pool gibi sıranın önemli olmadığı veri yapılarında kullanmak için ideal. Sırasız çalıştığını aşağıdaki şekilde görebiliriz. Bu sınıf sanırım Java'daki ConcurrentHashMultiSet'e denk geliyor.
image

Add() ve TryTake() bu sınıfın en önemli metodları.

Örnek:
var stringResult = new ConcurrentBag<string>();
stringResult.Add ("line");
string item;
stringResult.TryTake (out item);//Bag'den bir eleman çek
C# ConcurrentDictionary
ConcurrentDictionary yazısına taşıdım.

Java ConcurrentHashMap
ConcurrentHashMap yazısına taşıdım.

Java ConcurrentSkipList
ConcurrentSkipListSet yazısına taşıdım.

Java ConcurrentSkipListMap
ConcurrentSkipListMap yazısına taşıdım


12 Haziran 2015 Cuma

Süre Temsili

Giriş
İki Tarih Arasındaki Fark yazısı verilen iki zaman aralığının kaç yıl, ay, hafta, gün, dakika vs. gibi birimler olarak ölçülebileceğini gösteriyor. Ölçümde kullanılan birimler kavramsal olarak "süre" kelimesiyle anlatılıyor.

Dolayısıyla programlama dilleri ve kütüphaneler süre kavramını ve çeşitli birimler cinsiden temsil edebilmek için çeşitli sınıflar sunuyorlar.

C#
TimeSpan sınıfı
TimeSpan yazısına taşıdım.

Boost
Saniye
Saniyeyi temsil etmek için boost::posixtime::seconds  sınıfı kullanılıyor. Örnek:
boost::posix_time::seconds(1)
Joda
Ay
Ayı temsil etmek için Months sınıfı kullanılıyor.

Gün
Günü temsil etmek için Days sınıfı kullanılıyor.
  
Saat
Saati temsil etmek için Hours sınıfı kullanılıyor. Hour sınıfı yaratmak için
Hours.hours(6);
yazılabilir veya Hours sınıfı içindeki static olarak önceden yaratılmış hazır Hours.ONE gibi nesneler kullanılabilir.


Dakika
Dakikayı temsil etmek için Minutes sınıfı kullanılıyor.

Milisaniye
Milisaniyeyi temsil etmek için Durationnıfı kullanılıyor. Sınıfın açıklamasında "specifying a length of time in milliseconds." deniliyor. Duration sınıfını yaratmak için bir çok seçenek mevcut. Örnek:
Duration.millis (1000);//1000 milisaniyelik süre
Duration.standardDays (1);//1 günün milisaniye olarak süresi
Duration.standardHours (1);//1 saatin milisaniye olarak süresi

Sürenin Bir Üst Süre Cinsi ile Yazılması
Saniyenin Dakika + Saniye Olarak Gösterilmesi
Basit bir örnek:
private String secondsToString(int pTime) {
    return String.format("%02d:%02d", ptime / 60, pTime % 60);
}

10 Haziran 2015 Çarşamba

Blockchain Consensus Algoritmaları

Giriş
Blockchain aslında Distributed Ledger'in bir gerçekleştirimi. İnsanlar Blockchain kelimesini kullansalar dahi aslında kastedilen şey Distributed Ledger. Açıklaması şöyle.
It is crucial to understand that people often don't mean 'Blockchain' when they say 'Blockchain'. What they actually mean is 'Distributed Ledger Technology' (DLT).
Hedera Hashgraph
Hedera Hashgraph bir başka Distributed Ledger gerçekleştirimi

Distributed Ledger Technology (DLT)
Özellikleri şöyle
- Decentralized database
- Managed by various participants. No central authority acts as an arbitrator or monitor
- Distributed log of records, greater transparency
- Fraud and manipulation more difficult, more complicated to hack the system
Blockchain
Özellikleri şöyle
Blockchain is nothing else but a DLT with a specific set of features
- Shared database – a log of records – but in this case, shared using blocks that form a chain
- Blocks are closed by a type of cryptographic signature called a 'hash'; the next block begins with that same 'hash', a kind of wax seal
- Hashing verifies that the encrypted information has not been manipulated and that it can't be manipulated
Blockchain Kavramları
Açıklaması şöyle.
- A blockchain is either permissionless (i.e., public and accessible by everyone, like Bitcoin) or permissioned (using a group of companies or consortium).

- Different consensus algorithms exist, including Proof-of-Work (POW), Proof-of-Stake (POS), or voting systems.

- Blockchain uses global consensus across all nodes. In contrary, DLT can build the consensus without having to validate across the entire Blockchain

- A Blockchain is a growing list of records, called blocks, linked using cryptography. Each block contains a cryptographic hash of the previous block, a timestamp, and transaction data.
Blockchain Block Time
Açıklaması şöyle
The block time is a Unix epoch time when the miner started hashing the header (according to the miner). Must be strictly greater than the median time of the previous 11 blocks. Full nodes will not accept blocks with headers more than two hours in the future according to their clock.
Örnek
Bir örnek şöyle
Event         Time
Last block mined         08:00
Median time of last 11 blocks 07:00
Current time on my clock 11:00
Time on block arriving now 12:59

Rule                 Result
(12:59 - 11:00) < 2         OK
12:59 > 07:00         OK

Consensus Algoritmaları
Consensus Algoritmaları dağıtık sistemlerde kullanılıyor. Bir liderin seçilmesi kuralına dayalı. Lidere orchestrator, coordinator gibi isimler de verilebilir.

Sorgular ya da shared state lidere gönderilir.

Bu tür algoritmalarda yükün lidere verilmesi yani load-balancing değil daha çok fault tolerance önemlidir.

Proof of Work Algoritması
Bitcoin bu algoritmayı kullanıyor. Açıklaması şöyle.
This consensus algorithm being exponentially expensive, and resource intensive
Açıklaması şöyle.
PoW is a simple work-around to a coordination problem that was previously thought to be unsolvable. It sort of "cheats" by providing an economic solution to a distributed systems challenge, by introducing a real cost as a disincentive to unwanted behavior as well as using a reward system both to bootstrap itself and to incentivize security. The advantages of Bitcoin's PoW system include that the group of block authors is truly open to anyone with computational resources, that the system converges on one ground-truth because there is a real cost in producing a competing chaintip, and that it is simple enough for its security model to be well understood.
PoW istenilen hash çıktısını sağlayan nonce değerinin hesaplamanın zor olmasından kaynaklanıyor.  Açıklaması şöyle
A Bitcoin block contains a handful of fields

- Version
- Previous block hash
- Merkle root
- Time stamp
- Difficulty bits
- Nonce

...
Proof of work, in this simplified scenario, is accomplished by adding all of those numbers together and finding a nonce that results in the hash being 000. ...

Instead, Bitcoin uses SHA256. SHA256 has a couple of advantages which stem from its being a cryptographic hash function; the big three are that 
- calculating the SHA256 hash of a given value is "cheap" 
- but generating a value that will produce a given SHA256 hash is hard, 
- and that tiny changes in the input will produce large changes in the output (the avalanche effect).

Proof of State Algoritması
Açıklaması şöyle.
PoS is more similar to the approaches that were pursued before the publication of Bitcoin. PoS is naturally divergent as there is no real cost in staking. The "Nothing at Stake problem" allows stakers to work on multiple chaintips and only publish the next block from the chain most favorable to them. There are different ways of approaching the vastly different security model of PoS.
Gossip About Gossip and Virtual Voting Protocol Algoritması
Açıklaması şöyle.
To achieve consensus, Hashgraph uses the 'Gossip about Gossip' and 'Virtual Voting' mechanisms.

How the ‘Gossip about Gossip’ protocol works, below is the illustration to help you develop a clear understanding of the methodology. Say point A (Alice) randomly calls B (Marry) to inform her about an incident. Marry then records the information and creates an event. At random, a person, let’s say Bob makes a new event to commemorate the synchronized event.

Similarly, the network goes on, and the events are created in an acyclic graph that goes only upward. Each person randomly chooses another person and circulates the information across each node of the network. The acyclic graph, aka Hashgraph, is connected with cryptographic hashes, and the transactions are recorded in cryptographic timestamps.
Açıklaması şöyle.
Both the Hashgraph and blockchain technology employ different consensus mechanisms. Blockchain commonly uses proof-of-work and proof-of-stake consensus algorithm. Whereas Hashgraph opts for a different methodology, as stated above, it uses 'Virtual Voting' to carry out a flawless network consensus.

JDBC/ADO.Net

Never do in code what you can get the SQL Server to do well for you
Bu prensip asla kodun içinde join, veri filtreleme (where), foreign key integrity, primary key integrity, aggregate işlemlerinin yapılmaması gerektiğini belirtir.

JDBC sınıf hiyerarşisi kabaca aşağıdaki gibi
DriverManager
Konuyu DriverManager sıfını yazısına taşıdım.

JDBC ve ? işareti
JDBC ile ilgili öğrenilmesi gereken ilk konu JDBC kütüphanesi verdiğimiz SQL cümleleri ile "?" işareti gibi özel karakterler hariç bilmezler.SQL cümlelerine parametre geçilebilir ancak bazı DDL cümleleri parametre kabul etmezler. Bu tür cümleleri stringleri birleştirerek oluşturmak gerekir. Örneğin "DROP Table ?" şeklindeki bir DDL çalışmayabilir.

JDBC ve kapatılması gereken nesneler
close
JDBC kullanırken ResultSet, Statement ve Connection nesnelerinin işimiz bittikten sonra kapatılmaları gerekir. Örnek:

Connection Arayüzü
setSavepoint
Bu metod ile eğer veritabanı destekliyorsa açılmış olan transaction tamamen geri alınmadan belli bir noktaya kadar geri sarılabilir. Örnek:
stmt = conn.createStatement();
sp = conn.setSavepoint();
stmt.executeUpdate("INSERT INTO test(id) VALUES(1)");
conn.rollback(sp);
setTransactionIsolation
Bu metod ile isolation seviyesi atanır. Örnek:
getConnection().setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Statement Arayüzü
Difference between Statement and PreparedStatement sorusuna verilen cevapta görüldüğü gibi PreparedStatement sınıfı Statement sınıfına tercih edilmeli. Yine de bazı örnekler vermekte fayda var.

cancel
Bu metod ile çalışmakta olan bir Statement iptal edilebilir.

execute
boolean execute(string) metodunu sql cümlelerinin ne yaptığını bilmeden (insert/update/delete gibi) çağırmak için kullanırız. Örneği buradan aldım.
Bu metod sadece Select cümlesi için çağırıldığında true döner. Diğer kullanımlarda hep false döner.
executeUpdate
Bu metod kaç tane satırın güncellendiğini döndürür, ResultSet döndürmez ! Örnek:

Statement stmt = con.createStatement();
int rows = stmt.executeUpdate( insertStr );
System.out.printf("%d row(s) updated!", rows);
Zaten javadoc açıklamasında da dönüş değerini görmek mümkün.


executeQuery (Select cümleleri için kullanılır)
Bu metod ile bir ResultSet döndürülür. Örnek:

PreparedStatement pst = con.prepareStatement("select * from users where username=? ");
pst.setString(1,userName);
ResultSet rs=pst.executeQuery();
if(rs.next()) {
    String userClass=rs.getString("Class");
}
getGeneratedKeys
Bu metod ile bazı veritabları tarafından otomatik olarak üretilen anahtar değerler alınıyor. Örnek:
ResultSet rs = stmt.getGeneratedKeys();
while(rs.next()) {
    String key = rs.getString(1);//Anahtar String olarak geliyor
}
PreparedStatement Arayüzü Setter Metodları
setCharacterStream - Clob yazmak için kullanılır
Bu metod için örneği buradan aldım.
PreparedStatement pstmt = conn.prepareStatement("insert into clob_table (id, clob_colum) values (?,?)");
String clobData = "....";
Reader reader = new StringReader(clobData);
pstmt.setInt(1, 42);
pstmt.setCharacterStream(2, reader, clobData.length());
pstmt.executeUpdate();
setBinaryStream - Blob yazmak için kullanılır
Bu metod için örneği buradan aldım.
File f = new File(path);
FileInputStream fis = new FileInputStream(f);
PreparedStatement preparedStmt = con.prepareStatement(insertstatement);
preparedStmt.setBinaryStream(1, fis, f.length());
setDate - java.sql.Date yazmak için kullanılır
Bu metod ile java.sql.Date sınıfı yazılır. Bu sınıfı yaratmak için aşağıdaki gibi yapmak gerekir.

java.util.Date utilDate = //doldur;
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

setNull metodu
Bu metod ile Spring StoredProcedure Optional Parameters sorusunda açıklandığı gibi null parametre gönderebilme imkanımız var. Örnek :
setNull (1,null); veya setNull (1,Types.NULL) şeklinde olabilir.
Types sınıfı java.sql paketinde geçiyor.

setObject metodu
PreparedStatement arayüzü ile setObject, setString, setTime gibi bir çok setter metod gelmekte. How to I prepare an argument of type: List<Entry<? extends Class<?>, ?>> sorusuna verilen cevaba göre setObject metodu kendisine verilen parametrenini tipine bakarak doğru metodu çağırabilme yeteneğine sahip. Örneğin aşağıda PostgreSQL veritabanının JDBC sürücüsünün kodu var, ve cevaba uygun görünüyor.


CallableStatement Arayüzü
Konuyu JDBC CallableStatement başlıklı yazıya taşıdım.

ResultSet Arayüzü
Konuyu JDBC ResultSet başlıklı yazıya taşıdım.

DatabaseMetaData
Bu arayüz bir Connection sınıfından elde ediliyor. Veritabanı hakkında bilgi toplamak için faydalı.
getTables
Bu metod ile veritabanındaki tablolar hakkında bilgi elde edilebiliyor. Örnek:
Connection con = DriverManager.getConnection( "jdbc:postgresql://localhost:5432/db","user","pass");
DatabaseMetaData md = con.getMetaData();
ResultSet rs = md.getTables(null, "public", "%", null);
while (rs.next()) {
    rs.getString(3);//TABLE_NAME
}
ResultSetMetaData
Bu arayüz bir ResultSet sınıfından elde ediliyor. Dikkat edilmesi gereken nokta ilk sütun 1'den başlar. Örnek :
ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM TABLE2");
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
boolean b = rsmd.isSearchable(1); 
hane sayısı
getScale() ve getPrecision() metodları ile Oracle 'da Number olarak tanımlanmış bir sütunun hane sayısı bilgisini öğrenmek mümkün.

Clob
Clob kullanımı Using Large Objects sayfasında bulunabilir. Hiyerarşi ise aşağıdaki gibi


Datasource
DataSource aynı DriverManager gibi çalışıyor. Aralarındaki en önemli fark DataSource uygulama sunucusu tarafından JNDI vasıtasıyla verilir. Bir diğer fark ise DataSource, Connection Pooling imkanı sağlarken, DriverManager sunmaz.

Connection nesnesini JNDI vasıtasıyla almak için aşağıdakine benzer bir yöntem izlemek lazım.



Tomcat ile tüm uygulamalar için global bir connection pool yaratmak istiyorsak ayarları $CATALINA_BASE/conf/server.xml dosyasına , yok sadece bir web uygulamasına ait bir connection pool yaratmak istiyorsak uygulamanın META-INF/context.xml dosyasına eklemek lazım.

Hibernate

Hibernate ile hem DriverManager hem de JNDI kullanarak veritabanına bağlanmak mümkün. Bu konuyla ilgili olarak Spring ve Transaction/DAO başlıklı yazıya göz atabilirsiniz

JDBC Batch
Batch işlemler için java.sql.Statement arayüzündeki addBatch() ve   executeBatch() metodları kullanılır. Aşağıda PostgreSQL veritabanında batch işlemlerin nasıl bir ArrayList içine doldurulduğunu görmek mümkün.

Not : Batch Insertion in Hibernate ve Hibernate ile DAO ve Castle.ActiveRecord kullanımı başlıklı yazılarda
Hibernate ile JDBC batch ayarları arasındaki ilişkiyi de görmek mmükün.

İlginç bir konu ise batch update yaparken güncellenen satırlara kilit konulması. Eğer konulan kilit sayısı belli bir sayıyı aşıyorsa, tüm tabloya kilit konulduğu yazılmış. Bu durumda bir başkası aynı tablodaki ilgisiz bir satırı güncelleyemez. Dolayısıyla batch güncelleme için 5000 sınırının geçilmemesi tavsiye edilmiş.

JDBC Gün Saat Sınıfları
JDBC Gün Saat Sınıfları yazısına taşıdım.

JDBC Ayarları

setFetchSize : Bu metod Statement arayüzüne ait. Veritabanından bir sorgu için kaç tane satırın getirileceğini gelirtir. Kimi veritabanı (örneğin Oracle default olarak sadece 10 satır gönderiyor). Bu konu ile ilgili bulduğum en faydalı link JDBC performance tuning with optimal fetch size başlıklı yazı
st.setFetchSize(int rows);
Aşağıdaki şekilde setFetchSize() metodunun PostgreSQL veritabanı ile nasıl çalıştığını gösteren bir şekil mevcut

setMaxRows
Tam ne işe yaradığını anlamadım ama şöyle kullanılıyor.
st.setMaxRows(int maxRows);

ADO.Net

ADO.Net ise aşağıdaki gibi


Ado.Net ile asenkron SQL sorguları çalıştırmak ta mümkün. Aşağıdaki şekilde bunu görmek mümkün.
SQLConnection sınıfı
SQLConnection yazısına taşıdım.

SqlCECommand sınıfı
Örnek:
SqlCeCommand com = new SqlCeCommand("INSERT INTO ... VALUES(@CategoryName)",con);

SqlCommand sınıfı
Bu sınıf JDBC'deki Statement sınıfına benziyor. Çalışmak için bir connection nesnesine ihtiyaç duyuyor. Connection nesnesi constructor içinde verilebilir veya property olarak atanabilir.

Property olarak atamak
using (connection)
{
  cmd.Connection = connection; //Here assign connection to command object
        
}//end using(connection)

ExecuteNonQuery metodu
Bu metod kaç tane satırın etkilendiğini döner. Bu açıdan JDBC'deki executeUpdate metoduna benzer.

using (SqlCommand command = new SqlCommand("GP_SOP_AdjustTax", con, sqlTrans))
{
  try
  {
    

    if (con == null || con.State == ConnectionState.Closed)
    {
      con.Open();
    }

     command.ExecuteNonQuery();
    
     sqlTrans.Commit();
    }
    catch (Exception ex)
    {
      sqlTrans.Rollback();
    }
    finally
    {
      con.Close();
     }
}

ExecuteScalar metodu
Örnek:

const string sql = @"SELECT 
                        COUNT(CUSTOMER_NO) 
                     FROM 
                        WEBSITE_CUSTOMERS 
                     WHERE 
                        UPPER(CUSTOMER_NO) = @CUSTOMER_NO;";

using (SqlConnection connection = new SqlConnection("ConnectionString"))
{
    using (SqlCommand cmdCheck = new SqlCommand(sql, connection))
    {
        cmdCheck.Parameters.AddWithValue("@CUSTOMER_NO", "1");
        connection.Open();
        int nExists = (int)cmdCheck.ExecuteScalar();
        return nExists > 0;
    }
}

Parameters
SQL cümlelerine parametre geçmek için kullanılır. AddWithValue() metodu çağırılarak @ABC şeklindeki alanlara değer atanır.

SqlDataReader sınıfı
SqlDataReader yazısına taşıdım.

DataTable sınıfı
DataTable yazısına taşıdım.

DataSet sınıfı
DataSet yazısına taşıdım.

QT
Qt ise aşağıdaki gibi
QSqlDatabase
İsmi olan bir connection ekle
//Yeni bir connection ekle
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "Definitions");
//....
//Connection'ı kapat
QSqlDatabase::removeDatabase("Definitions");

İsimsiz default connection ekle
Örnek:
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("acidalia");
db.setDatabaseName("customdb");
db.setUserName("mojito");
db.setPassword("J0a1m8");
bool ok = db.open();

SQLite örnekleri
SQLite dosya tabanlı bir veritabanı olduğu için kullanması çok kolay. Driver olarak qsqlite4.dll kullanılıyor. Bu dll $QTDIR\plugins\sqldrivers dosyası altında bulunur. Programı kurarken programın kurulduğu yerin altındaki sqldrivers alt dizini altına kopyalamak gerekir. How to deliver sqlite driver to the end user? sorusunda da benzer bir cevap verilmiş.

QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE",CONNECTION_NAME);
QString nativeDbPath = "myfile.db";
database.setDatabaseName(nativeDbPath);
database.open();

QSqlQuery
Bu sınıf JDBC'deki Statement ve PreparedStatement arayüzlerinin karışımına benziyor.
next metodu ile sorgulama işlemi
 
exec metodu ile silme işlemi
QSqlQuery DeleteQuery;
DeleteQuery.prepare("DELETE FROM Contacts WHERE Id = :i;");
DeleteQuery.bindValue(":i",SelectedRecordId);
if(!DeleteQuery.exec())
{
//error
}
OCI (Oracle Call Interface)
C ile Oracle veritabanına erişmek için kullanılır. OCI transport olarak SQLNET kullanır.

ODBC
ODBC kütüphanaleri artık sanırım sadece C++ uygulamaları tarafından kullanılıyor. Oracle hariç çoğu veritabanı için sadece ODBC kütüphanesi yeterli. Oracle ODBC kullanmak için Oracle Client yazılımının da kurulu olması gerekir.