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ü
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
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.