bilge adam java.pdf

228

Click here to load reader

Upload: ramazan-aras

Post on 05-May-2017

360 views

Category:

Documents


23 download

TRANSCRIPT

Page 1: Bilge adam java.pdf

C# ve T-SQL Geliştiriciler için Java ve OracleYalçın Kaya

Editör C. Banu Üçüncüoğlu

YAZILIM VE VERİTABANI

19-0

Page 2: Bilge adam java.pdf

C# ve T-SQL Geliştiriciler için Java ve OracleYalçın Kaya

Editör: C. Banu Üçüncüoğlu

Kapak Tasarımı: Melih Sancar

Grafik Tasarım: Tuna Erkan

Grafik Uygulama: Soner Işık

Genel Yayın Yönetmeni: Mehmet Çömlekçi

1. Basım: Şubat 2008

Bilge Adam Yayınları: 21

Eğitim Yayınları Dizisi: 21

ISBN: 978-605-5987-19-0

Copyright © 2007, Bilge Adam Bilgisayar ve Eğitim Hizmetleri San. ve Tic. A.Ş.

Eserin tüm yayın hakları Bilge Adam Bilgisayar ve Eğitim Hizmetleri San. ve Tic. A.Ş.’ye aittir. Yayınevinden yazılı izin alınmadan kısmen ya da tamamen alıntı yapılamaz, hiçbir şekilde kopya edilemez, çoğaltılamaz ve tekrar yayımlanamaz. Bilge Adam’ın öğrencilerine ücretsiz armağanıdır, para ile satılamaz.

Bilge Adam Bilgisayar ve Eğitim Hizmetleri San. ve Tic. A.Ş.

19 Mayıs Mahallesi, 19 Mayıs Caddesi, UBM Plaza, No: 59-61, Kat: 4-7; Şişli, İstanbul

Telefon: (212) 272 76 00 – (212) 217 05 55 Faks: (212) 272 76 01

www.bilgeadam.com - [email protected]

Tanıtım nüshasıdır, para ile satılamaz.

Page 3: Bilge adam java.pdf

İçindekilerJava’ya Giriş���������������������������������������������������������������������������������������������������������������������������������3

Java Nedir?������������������������������������������������������������������������������������������������������������������������������ 3

Windows Ortamında Java Kurulumu�������������������������������������������������������������������������������3

Java Uygulamaları Nasıl Çalışır?��������������������������������������������������������������������������������������������� 7

Basit Veri Tipleri����������������������������������������������������������������������������������������������������������������������� 9

Ondalıklı Tipler��������������������������������������������������������������������������������������������������������������11

Mantıksal Tip�����������������������������������������������������������������������������������������������������������������11

Karakter Tipi������������������������������������������������������������������������������������������������������������������11

Aritmetik İşlemler ve Taşma������������������������������������������������������������������������������������������11

Java’da Operatörler���������������������������������������������������������������������������������������������������������������� 14

Kaydırma (Shift) İşlemleri����������������������������������������������������������������������������������������������15

İşlemlerde Parantez Kullanımı��������������������������������������������������������������������������������������16

Karar Vermek ve Koşullu İfadeler���������������������������������������������������������������������������������16

Döngüler��������������������������������������������������������������������������������������������������������������������������������������23

While Döngüsü����������������������������������������������������������������������������������������������������������������������� 23

do Döngüsü���������������������������������������������������������������������������������������������������������������������������� 24

for Döngüsü���������������������������������������������������������������������������������������������������������������������������� 24

break ve continue Deyimleri�������������������������������������������������������������������������������������������������� 25

Niteleyiciler (Modifiers)��������������������������������������������������������������������������������������������������������������29

Access Modifiers (Erişim Niteleyicileri)����������������������������������������������������������������������������������� 29

Niteleyicilerde Metod Ezme (Access Modifiers Overriding) �����������������������������������������30

Diğer Niteleyiciler ���������������������������������������������������������������������������������������������������������30

Casting ve Conversion��������������������������������������������������������������������������������������������������������������35

Basit Tiplerde Conversion������������������������������������������������������������������������������������������������������ 36

Basit Tiplerde Conversion: Atama���������������������������������������������������������������������������������36

Basit Tiplerde Conversion: Metod Çağırma������������������������������������������������������������������38

Basit Tiplerde Conversion: Aritmetik Yükseltme ����������������������������������������������������������38

Basit Tiplerde Casting���������������������������������������������������������������������������������������������������39

Referans Tiplerde Conversion ����������������������������������������������������������������������������������������������� 40

Referans Tiplerde Conversion: Atama �������������������������������������������������������������������������40

Referans Tiplerde Csonversion: Metod Çağırma ���������������������������������������������������������41

Page 4: Bilge adam java.pdf

Yapısal Programlama�����������������������������������������������������������������������������������������������������������������45

Yapısal Programlama Nedir?������������������������������������������������������������������������������������������������� 45

Nesne Yönelimli Programlamanin Temel Bileşenleri����������������������������������������������������45

Nesne Yönelimli Programlamanın Temel Kavramları������������������������������������������������������������ 51

Kapsülleme (Encapsulation) ����������������������������������������������������������������������������������������51

Swing�������������������������������������������������������������������������������������������������������������������������������������������67

Swing’e Giriş�������������������������������������������������������������������������������������������������������������������������� 67

JButton��������������������������������������������������������������������������������������������������������������������������68

JLabel����������������������������������������������������������������������������������������������������������������������������69

JTextField����������������������������������������������������������������������������������������������������������������������70

Event Handling Mekanizması����������������������������������������������������������������������������������������71

JTextArea����������������������������������������������������������������������������������������������������������������������74

JOptionPane�����������������������������������������������������������������������������������������������������������������75

JCheckBox��������������������������������������������������������������������������������������������������������������������77

JRadioButton�����������������������������������������������������������������������������������������������������������������79

JComboBox�������������������������������������������������������������������������������������������������������������������81

JList ������������������������������������������������������������������������������������������������������������������������������83

Mouse Event’lerinin Yönetilmesi:����������������������������������������������������������������������������������89

Klavye Event’lerinin Yönetilmesi�������������������������������������������������������������������������������������������� 94

JDBC������������������������������������������������������������������������������������������������������������������������������������������103

Veritabanı Bağlantısının Kurulması��������������������������������������������������������������������������������������108

Veri Değiştirme Komutları (insert, update, delete)���������������������������������������������������������������109

Veri Sorgulama Komutları (Select)���������������������������������������������������������������������������������������110

Parametreli SQL İfadelerinin Çalıştırılması�����������������������������������������������������������������112

Stored Procedure’lerin Çalıştırılması��������������������������������������������������������������������������113

JSP���������������������������������������������������������������������������������������������������������������������������������������������123

JSP Teknolojisinde Kullanılan Etiketler��������������������������������������������������������������������������������128

JSP Direktifleri�������������������������������������������������������������������������������������������������������������128

JSP Script Etiketleri�����������������������������������������������������������������������������������������������������129

Form Verilerinin Kullanılması�����������������������������������������������������������������������������������������������129

Durum Yönetimi �������������������������������������������������������������������������������������������������������������������131

JAVA I/O �����������������������������������������������������������������������������������������������������������������������������������143

Dosyalar ve Dizinler ������������������������������������������������������������������������������������������������������������143

IV İçindekiler

Page 5: Bilge adam java.pdf

FilterInputStream Sınıfları�������������������������������������������������������������������������������������������145

FileInputStream ve FileOutputStream Sınıflarının Kullanımı��������������������������������������146

Reader ve Writer Sınıfları: ������������������������������������������������������������������������������������������150

Standart Giriş-Çıkış Biriminin Kullanılması:����������������������������������������������������������������154

Java ile Ağ Programlama: ���������������������������������������������������������������������������������������������������155

Oracle Veritabanı Ailesi�����������������������������������������������������������������������������������������������������������161

Oracle Üzerinde Uygulama Geliştirme���������������������������������������������������������������������������������161

Oracle Veri Tabanı Sisteminin Kurulması�������������������������������������������������������������������161

Tablespace������������������������������������������������������������������������������������������������������������������167

Undo Tablespace��������������������������������������������������������������������������������������������������������167

Oracle’da Veri Tabanı Oluşturmak������������������������������������������������������������������������������168

Temel Veri Tipleri��������������������������������������������������������������������������������������������������������179

Oracle’da Kullanıcı Yönetimi ve Güvenlik�������������������������������������������������������������������179

Oracle Üzerinde Programlama������������������������������������������������������������������������������������������������185

PL/SQL Nedir?���������������������������������������������������������������������������������������������������������������������185

SQL Plus���������������������������������������������������������������������������������������������������������������������185

TOAD��������������������������������������������������������������������������������������������������������������������������187

PL/SQL ile Programlama��������������������������������������������������������������������������������������������189

PL/SQL’de Kontrol Yapıları�����������������������������������������������������������������������������������������191

PL/SQL’de Alfanümerik Tipler�������������������������������������������������������������������������������������201

PL/SQL’de Mantıksal Tipler����������������������������������������������������������������������������������������207

PL/SQL’de Tarih ve Zaman Tipleri������������������������������������������������������������������������������207

Referans Tipleri�����������������������������������������������������������������������������������������������������������213

LOB (Large Object) Tipleri������������������������������������������������������������������������������������������216

PL/SQL’de Döngü Yapıları������������������������������������������������������������������������������������������216

�İçindekiler

Page 6: Bilge adam java.pdf
Page 7: Bilge adam java.pdf

1 Java’ya Giriş

Page 8: Bilge adam java.pdf

1 Java’ya GirişJava Nedir?

Java Uygulamaları Nasıl Çalışır?

Basit Veri Tipleri

Java’da Operatörler

Page 9: Bilge adam java.pdf

Java’ya GirişBölüm Hedefleri:

Java platformu üzerinde Java diliyle basit uygulamalar yazmak.

Temel veri tiplerini tanımak.

Java Nedir?Java, işlemci mimarisinden ve işletim sisteminden bağımsız olarak tasarlanmış bir platformdur. Aynı zamanda da bu platform üzerinde uygulama geliştirilen dilin adıdır. Microsoft .NET plat-formuyla karşılaştırdığımızda .NET platformuna karşılık gelen yapının adı Java olduğu gibi C# .NET, Visual Basic .NET gibi .NET dillerine karşılık gelen dilin adı da Java’dır. Bu açıklamadan anlaşılacağı gibi Microsoft .NET platformundan farklı olarak Java platformunda uygulama geliş-tirilebilecek tek dil vardır. Java platformu pek çok yönden Microsoft .NET platformuna benzediği gibi Java dili de yetenekleri bağlamında C# diline çok benzer.

Java platformu da Microsoft .NET platformu ve modern nesne yönelimli diller gibi geniş bir sınıf kütüphanesine sahiptir. Yine .NET platformuna benzer olarak bir Java uygulamasının çalışması için doğrudan işletim sistemi kullanılmaz. Bu sebeple bir Java uygulaması, işletim sistemine ve mimari platforma göre geliştirilmiş olan JVM�(Java Virtual Machine) aracılığıyla çalıştırılır.

Java ile uygulama geliştirme için kullanılan ortamlar (IDE – Integrated Development Environment), .NET için kullanılan ortamlara göre çok daha fazla sayıdadır ve kolaylık olarak farklılık gösterir. Yaygın olarak kullanılan bütünleşik geliştirme ortamlarından (IDE) biri Eclipse’tir. Eclipse’i http://www.eclipse.org adresinden indirebilirsiniz. Kitaptaki örnekleri gerçekleştirmek için herhangi bir bütünleşik geliştirme ortamı indirmenize gerek yoktur, bütün örnekleri Windows üzerinde Notepad ya da herhangi bir metin editörü ile gerçekleştirebilirsiniz.

Windows Ortamında Java KurulumuJava platformunu Windows işletimi üzerinde kurmak ve uygulamaları yazabilir hale gelmek için öncelikle Java Development Kit’i (JDK) bilgisayarınızda kurmalısınız. JDK’nın sürümlerini http://www.javasoft.com adresinden indirebilirsiniz. İndirdiğiniz dosyayı Windows’un tüm sürümlerinde kurabilirsiniz.

Kurulumu gerçekleştirdikten sonra Windows ortamında çevre değişkenleri (environment variab-les) üzerinde işlem yapmamız gerekir. Komut satırında herhangi bir noktadan derleme ve çalış-tırma programlarını kullanabilmek için Path değişkenine Java’yı kurduğumuz dizinin içindeki bin dizinini eklemelisiniz.

Page 10: Bilge adam java.pdf

Uygulama 1.1:

Windows XP:

Şekil 1’de gösterilen, Bilgisayarım (My Computer) ikonunu sağ tıklayın. Açılan menüde Özel-likler (Properties) öğesini seçin.

Şekil 2’de gösterildiği gibi, açılan pencerede Gelişmiş (Advanced) sekmesini tıklayın.

Şekil 2’de gösterildiği gibi, gelen pencerede Çevre Değişkenleri (Environment Variables) bu-tonuna tıklayın.

Şekil 3’te gösterilen, Sistem Değişkenleri (System Variables) içinde Path’i bulun ve en sonuna “;” ekleyin.

1�

2.

3�

4.

Şekil 1

Şekil 2

� Bölüm 1

Page 11: Bilge adam java.pdf

Şekil 4’te olduğu gibi, sonuna da <Java’yi kurduğunuz yer>\<JDKxxx>\bin yazın.

Windows Vista:

Şeki 5’daki gibi, Bilgisayarım (My Computer) ikonunu sağ tıklayın. Açılan menüde Özellikler (Properties) öğesini seçin.

5.

1�

Şekil 3

şekil 4

Şekil 5

�Java’ya Giriş

Page 12: Bilge adam java.pdf

Şekil 6’de gösterilen, Tasks bölümünden Advanced System Settings link’ine tıklayın.

Şekil 8’de gösterildiği gibi, gelen pencerede Çevre Değişkenleri (Environment Variables) bu-tonuna tıklayın.

2.

3�

Şekil 6

Şekil 7

� Bölüm 1

Page 13: Bilge adam java.pdf

Şekil 8’da gösterildiği gibi, Sistem Değişkenleri (System Variables) içinde Path’i bulun ve en sonuna “;” ekleyin.

Şekil 9’daki gibi, sonuna da <Java’yi kurduğunuz yer>\<JDKxxx>\bin yazın.

Java Uygulamaları Nasıl Çalışır?Bir Java uygulamasının makinenizde çalışması için JVM’in kurulu olması gerekir. JVM Microsoft .NET platformunun IL (Intermediate Language - MSIL) üzerinden çalışması mantığına benzer bir mantıkla çalışır. Java tarafında IL’e karşılık gelen yapı bytecode’dur. JVM sadece bytecode üzerinden çalışır. Bu sebeple yazmış olduğunuz Java kaynak kodunu öncelikle Java derleyicisiy-le derleyerek bytecode’a çevirmelisiniz. Bununla birlikte dikkat edilmesi gereken bir nokta da bir Java sınıfının derlenebilmesi için kaynak kodu tutan .java uzantılı dosyanın adının, içindeki public sınıfın adıyla aynı olması gerektiğidir.

Örnek Uygulama 1.1:

1publicclassIlkJavaUygulamasi

2{

3 publicstaticvoidmain(String[]args)

4 {

5 System.out.println(“IlkJavaUygulamasi”);

6 }

7}

4.

5.

Şekil 8

Şekil 9

�Java’ya Giriş

Page 14: Bilge adam java.pdf

İşlem adımları:

Örnekleri kolaylık açısından Windows’ta oluşturacağınız bir dizin içinde toparlamanız faydalı ola-caktır.

Yukarıdaki kodu herhangi bir metin editöründe yazın ve “IlkJavaUygulamasi.java” adıyla kay-dedin.

Command Prompt’u açın.

Dosyayı kaydettiğiniz dizine girin.

javac IlkJavaUygulamasi.java ifadesini çalıştırın.

Eğer hata almazsanız IlkJavaUygulamasi.class dosyasının kaynak kodla aynı yerde oluştu-ğunu görmelisiniz.

Java IlkJavaUygulamasi ifadesini çalıştırdığınızda komut satırında “Ilk Java Uygulamasi” ifa-desini görmelisiniz.

Uygulamanın açıklaması: 1 numaralı satırda C#’ta olduğu gibi IlkJavaUygulamasi adında bir sınıf tanımlanır. Java dilinde de, C#’ta olduğu gibi kod blokları sınıfların içinde yer almalıdır. 2 numaralı ve 4 numaralı satırlarda “{“ (küme parantezi, curly brace) işareti aynen C#’ta olduğu gibi blok başı işaretidir. 2 numaralı satırdaki “{“ sınıf için tanımlanan bloğun başlangıcıyken 4 numaralı satırdaki “{“ işareti de main metodunun başlangıcıdır.

6 numaralı ve 7 numaralı satırlardaki “}” işareti blok sonu işaretidir. 6 numaralı satırdaki “}” işareti main bloğunun sonuyken, 7 numaralı satırdaki “}” işareti sınıf için açılan bloğun sonudur.

Blok başı ve blok sonu ifadelerinde dikkat etmeniz gereken en önemli nokta son açılan blok her zaman ilk kapatılan bloktur ve her açılan blok mutlaka kapatılmalıdır.

3 numaralı satırda aynen C#’ta olduğu gibi main metodunun tanımını görebilirsiniz. public static void ifadelerinin anlamları C# ile aynı olmakla birlikte daha sonra detaylı olarak ince-lenecektir. Main metodunun parametresi olan String[] args de metodun parametre olarak bir String dizisi aldığını belirtir. Main metodu, Java’da da konsol uygulamalarının otomatik olarak çalışan ilk metodudur.

5 numaralı satırda main metodu çalıştığında ne yapacağını gösterir. System.out.println();�ifadesi C#’taki Console.WriteLine() ifadesine karşılık gelir. Burada System.out standart çıktı birimini temsil eder. Varsayılan olarak kullandığınız ekrandır. println() metodu, kendisine parametre olarak verilen ifadeye yazar ve sonundaki “ln” (line) kısmından dolayı bir satır aşağıya geçer. İfadenin sonundaki “;” işareti Java’da da C#’taki her ifadenin sonunda mutlaka bulunması gereken satır sonlandırıcısıdır.

Bu basit uygulamaya bakarak C# dili ile Java dilinin birbirine pek çok noktada benzediğini gö-rebilirsiniz. Bundan sonraki pek çok aşamada C# dili ile Java dili arasındaki benzerliklere tanık olacaksınız.

İlk uygulamada konsola System.out.println() yazdırdığımız ifadeyi bir mesaj kutusunda yazdırmak istersek bir miktar değişiklik yapmamız gerekecektir.

Örnek Uygulama 1.2a:

1publicclassMesajKutusu

2{

3publicstaticvoidmain(String[]args)

4{

5 javax.swing.JOptionPane.showMessageDialog(null,“IlkJava Uygulamasi”);

6}

7}

1�

2.

3�

4.

5.

6.

� Bölüm 1

Page 15: Bilge adam java.pdf

Uygulamanın açıklaması: Bu uygulamanın 5 numaralı satırı dışındakiler önceki uygulamadan farklı değildir. 5 numaralı satırda da C#’taki MessageBox.Show() metodunun Java’daki benzeri olan JoptionPane.showMessageDialog() metodu kullanılmıştır. Bu kodun başındaki ja-vax.swing�de�JOptionPane sınıfının içinde bulunduğu pakettir. Java’daki paketleri .NET’teki assembly’ler gibi düşünebilirsiniz. Dolayısıyla C#’taki using ifadesinin karşılığı olarak import�ifadesini kullanarak kodumuzu aşağıdaki şekilde güncelleyebiliriz.

Örnek Uygulama 1.2b:

1importjavax.swing.JOptionPane;

2publicclassMesajKutusu

3{

4 publicstaticvoidmain(String[]args)

5 {

6 JOptionPane.showMessageDialog(null,“IlkJava Uygulamasi”);

7 }

8}

Bu örnekte 1 numaralı satırdaki import ifadesi javax.swing paketindeki JOptionPane sınıfı-nın yüklenmesini sağlar. Bir kere yüklendikten sonra tekrar paket adının kod içinde kullanmamıza gerek kalmaz. Burada yapılan yükleme işlemi, .NET’teki gibi, yüklenen paketin içerdiği kodu, oluşturulan .class dosyasının içine eklemez, sadece o pakete erişimi sağlayacak kodu oluşturur.

Uygulama 1.2b’deki 6 numaralı satırda JOptionPane sınıfının showMessageDialog metodunun ilk parametresi swing paketi-nin detaylarına gelene kadar sürekli null olarak kullanılacaktır. 2. parametre de tahmin edebileceğiniz gibi mesaj kutusunda yazdırı-lacak ifadedir.

Basit Veri TipleriJava’daki basit (primitive)�veri tipleri .NET’teki basit veri tipleriyle çok benzerdir. Herhangi bir veri tipinin tanımlanması C#’takinden farklı değildir. Bununla birlikte Java’daki sayısal tiplerin hepsi işaretlidir (signed – hem negatif hem de pozitif sayıları tutar), işaretsiz veri tipi yoktur. Öncelikle tam sayısal veri tiplerinden başlayalım:

byte: Adından da anlaşılabileceği gibi 1 byte’lık, tam sayı tutan veri tipidir. C#’ta sbyte’a, .NET CTS’te System.SByte’a karşılık gelir. Herhangi bir byte değişken tanımlaması aşağıdaki şe-killerde yapılabilir:

byte yas; //ilk değer verilmeden.

byte yas = 67; //ilk değer verilerek.

short: 2 byte’lık, tam sayı tutan veri tipidir. C#’ta short’a, .NET CTS’te System.Int16’ya karşılık gelir. Herhangi bir short değişken tanımlaması aşağıdaki şekillerde yapılabilir:

short derinlik; //ilk değer verilmeden.

short derinlik = 23245; //ilk değer verilerek.

int: 4 byte’lık, tam sayı tutan veri tipidir. C#’ta int’e, .NET CTS’te System.Int32’ye karşılık gelir. Herhangi bir int değişken tanımlaması aşağıdaki şekillerde yapılabilir:

Java’da comment’lerin kullanı-mı C# ile aynıdır. // Satır com-ment. /* */ Blok comment.

�Java’ya Giriş

Page 16: Bilge adam java.pdf

int sayi; //ilk değer verilmeden.

int sayi = 12; //ilk değer verilerek.

long: 8 byte’lık, tam sayı tutan veri tipidir. C#’ta long’a, .NET CTS’te System.Int64’e karşılık gelir. Herhangi bir long değişken tanımlaması aşağıdaki şekillerde yapılabilir:

long GNP; //ilk değer verilmeden

long GNP = 1234567890; //ilk değer verilerek

Bunların dışında basit veri tipi olmamakla birlikte şu aşamada bilmeniz gereken bir veri tipi daha var: String��String tipi referans üzerinden çalışan bir veri tipidir. Yani, aslında basit veri tip-lerinden farklı olarak bir nesne üzerinden çalışırlar; fakat tanımlaması şu ana kadar bahsedilen veri tiplerinden farklı değildir. String’in detaylarına ilerleyen bölümlerde değineceğiz. Burada dikkat etmemiz gereken nokta Java’da küçük harf “s” ile başlayan string tanımının olmamasıdır. Herhangi bir String veri tanımlaması aşağıdaki şekillerde yapılabilir:

String Ad; //ilk değer verilmeden

String Ad = “Yalcin”; //ilk değer verilerek

Artık kullanıcıdan 2 sayı alıp bunları matematiksel herhangi bir işlem içinde kullanabilecek hemen her şeye sahibiz. Tek eksiğimiz bu sayıları kullanıcıdan nasıl alacağımız. Matematiksel işlemlerin nasıl yapıldığına gelirsek, ileride farklılıklarına değineceğemizi belirterek C#’taki yazılışlarından şu an için hiçbir farkı yoktur diyebiliriz. Şimdi bunu örnekleyelim:

Örnek Uygulama 1.3:

1importjavax.swing.JOptionPane;

2publicclassMesajKutusu

3{

4 publicstaticvoidmain(String[]args)

5 {

6 StringbirinciSayi,ikinciSayi;

7 inttoplam,sayi1,sayi2;

8 birinciSayi=JOptionPane.showInputDialog(“Birinci sayiyigiriniz:”);

9 ikinciSayi=JOptionPane.showInputDialog(“Ikinci sayiyigiriniz:”);

10 sayi1=Integer.parseInt(birinciSayi);

11 sayi2=Integer.parseInt(ikinciSayi);

12 toplam=sayi1+sayi2;

13 JOptionPane.showMessageDialog(null,toplam);

14 }

15}

Kod Açıklaması: 6 numaralı satırda String tipinde 2 değişken tanımlanmıştır. Unutmayın ki bu 2 değişken de basit veri tipi değil referans tipli değişkenlerdir. Bu değişkenler JOptionPane sını-fının showInputDialog metodunun döndürdüğü değerleri tutmak için kullanılmıştır. 7 numaralı satırda 3 tane tam sayı tanımlanmıştır. toplam adlı değişken JOptionPane.showInputDia-log() metoduyla aldığımız değerlerin sayıya dönüştürülmüş hallerini toplamak için kullanılmış-tır. sayi1 ve sayi2 değişkenleri de JOptionPane.showInputDialog() metoduyla aldığımız

10 Bölüm 1

Page 17: Bilge adam java.pdf

değerlerin sayıya dönüştürülmüş hallerini tutacaktır. 8 ve 9 numaralı satırlarda JOptionPane.showInputDialog() metodlarıyla, yukarıda tanımladığımız String’lerin içine, kullanıcının gi-receği değerler alınmaktadır. Burada dikkat etmemiz gereken nokta, rakamlar dışında değerler girdiğimizde 10 ve 11 numaralı satırlarda dönüştürme hatasıyla karşılaşma durumumuzdur. Bu satırlarda kullanıcı tarafından girilmiş olan String’ler Integer sınıfının parseInt() aracılı-ğıyla int’e çevrilmeye çalışılır.�Integer sınıfı .NET’teli System.Int32 sınıfına karşılık gelen sınıftır ve terimsel olarak wrapper class olarak geçer. parseInt() metodu da Int32 sınıfının Parse() metoduyla aynı şekilde çalışır. Eğer kendisine gönderilen parametre int’e çevrilemi-yorsa “NumberFormatException” oluşturur. Bunun için de C#’taki gibi istisna yönetimi (excep-tion handling), yani try-catch-finally bloklarını kullanabiliriz.

10 ve 11 numaralı satırlarda eğer herhangi bir exception oluşmazsa, yani bir int’in alabileceği değer aşılmazsa 12 numaralı satır çalışır. Eğer 2 değerin toplamı bir int’in alabileceği en büyük değeri aşıyorsa toplam değişkeninin alacağı değer negatif bir sayıya dönecektir. Çünkü Java, C geleneğinden dolayı sayıları kontrol etmez. Bu durumu daha küçük bir tam sayı tipi olan byte�üzerinden Uygulama 1.4’te açıklayacağım.

13 numaralı satırda bir önceki örnekte kullandığımız JOptionPane.showMessageDialog() metoduyla toplam değişkeninin değerini yazdırıyoruz. Sınıf adıyla kullanılması sebebiyle show-MessageDialog() metodunun JOptionPane sınıfının static bir metodu olduğunu anlaya-bilirsiniz.

Ondalıklı Tiplerdouble: 8 byte’lık ondalıklı veri tipidir. Tanımlandığı standart (IEEE 754) çerçevesinde yük-sek doğruluk isteyen işlemlerde kullanılmamalıdır; ancak ondalıklı kısımda yüksek yoğunluk çok önemli değilse kullanılabilir. C#’ta float’a, .NET CTS’te System.Single’a karşılık gelir.

float: 4 byte’lık ondalıklı veri tipidir. Hem tanımlandığı standart çerçevesinde hem de double�veri tipine göre daha küçük bir veri tipi olması sebebiyle yüksek doğruluk isteyen işlemlerde kulla-nılmamalıdır; ancak ondalıklı kısımda yüksek yoğunluk çok önemli değilse kullanılabilir. Eğer bel-lek yetersizliği ile ilgili bir problem yoksa float yerine double tercih edilmelidir. C#’ta double’a, .NET CTS’te System.Double’a karşılık gelir.

Her 2 ondalıklı veri tipinin yerine java.math paketinde bulunan BigDecimal sınıfı kullanılabi-lir.

Mantıksal Tipboolean:�true ya da false değerlerinde birini taşıyabilen basit veri tipidir. Taşıdığı veri sade-ce 1 bit ile gösterilebiliyor olsa da kapladığı alan 1 bit değildir. C#’ta bool’a, .NET CTS’te Sys-tem.Boolean’a karşılık gelir.

Karakter Tipichar: 2 byte’lık Unicode karakter olarak herhangi bir karakter bilgisini tutmak için kullanılır. C ailesi geleneğinden dolayı işaretsiz tam sayısal veri tipi olarak değerlendirilebilir. C#’ta char’a, .NET CTS’te System.Char’a karşılık gelir.

Aritmetik İşlemler ve TaşmaJava’da tam sayısal aritmetik işlemler, işleme giren değerlerin tipleri eğer birer int değilse int’e dönüştürülerek yapılır. Eğer işleme giren tiplerden en az biri long ise long’a dönüştürülerek yapılır.

Eğer tipler ondalıklı ise işlemler, işleme giren tipler double’a dönüştürülerek yapılır. Dolayısıyla aşağıdaki örnekleri dikkatle incelemek gereklidir:

11Java’ya Giriş

Page 18: Bilge adam java.pdf

Örnek Uygulama 1.4a:

1publicclassTipDonusumleri1

2{

3 publicstaticvoidmain(String[]args)

4 {

5 bytesayi1=120;

6 bytesayi2=110;

7 bytetoplam=sayi1+sayi2;

8 }

9}

Bu örnekte 7 numaralı satırda sayi1 + sayi2 ifadesi, işlem int üzerinden yapıldığından çalı-şacaktır; ancak toplam değişkeninin tipi byte olduğu için derlenemeyecektir ve possible loss of precision (değer kaybı ihtimali) hatası verecektir. Bunun sebebi toplanan byte tipindeki değiş-kenlerin değerlerinin toplamının, byte tipindeki bir alana sığmaması değildir. (120 + 110 = 230, byte tipinin alabileceği en büyük değer ise 127’dir). Bunu sayi1’in değerini 12, sayi2’nin değerini 11 yaparak görebilirsiniz. Possible loss of precision hatasını bu durumda da alacaksınız. (12 + 11 = 23, byte tipinin içine sığar). Dolayısıyla bu hatanın sebebi, sayi1 + sayi2 işleminin int üze-rinden yapılmasıdır. Bunu anlamak için 7 numaralı satırda tanımlanan toplam değişkeninin tipini byte’tan short’a çevirip tekrar derleyerek de görebilirsiniz. Bu durumda 120 ile 110’un toplamı olan 230 değeri short tipine sığacak bir değer olmasına rağmen possible loss of precision ha-tasını yine alırsınız; ancak toplam değişkeninin değerini int ya da long yaparak bu hatadan kurtulabilirsiniz.

Uygulama 1.4a örneği üzerinde düşündüğümüzde yapılan işlem anormal gelmemelidir. Çünkü burada 2 tane byte tipli değişkenin toplamının değerinin byte tipine sığmaması ihtimali yük-sektir. Bu durumda, eğer bu işlemi byte tipi üzerinden gerçekleştirmek istersek ne yapmalıyız? Bunun cevabını da Uygulama 1.4b’de görebilirsiniz.

Örnek Uygulama 1.4b:

1publicclassTipDonusumleri2

2{

3 publicstaticvoidmain(String[]args)

4 {

5 bytesayi1=12;

6 bytesayi2=11;

7 bytetoplam=(byte)(sayi1+sayi2);

8 System.out.println(toplam);

9 }

10}

Örnek Uygulama 1.4b’de 7 numaralı satırda yaptığımız işlem bir explicit cast (göstererek dönüş-türme) işlemidir. Uygulama 1.4a’da int’e dönüştürme ise implicit cast (gizli dönüştürme) işlemi olarak adlandırılır. Daha sonra bu işlemleri farklı isimlerle tekrar değerlendireceğiz. Burada sayi1 + sayi2 işlemi önce yine int üzerinden yapılır ve sonra byte’a dönüştürme yapılır. Bu şekilde 12 ile 11’in toplamı olan 23 değerini byte olarak elde edebilirsiniz. Buraya kadar herşey gü-zel; ancak bu noktada Uygulama 1.3’deki taşma problemimize geri dönelim ve 5 ve 6 numaralı satırlarda tanımladığımız byte tipli değişkenlerimizin değerlerini sırasıyla 120 ve 110 yapalım. Yeni değerlerin her ikisi de byte tipine sığabilirler; fakat toplamları olan 230 değeri byte tipine

12 Bölüm 1

Page 19: Bilge adam java.pdf

sığmaz. Java uygulaması bu durumda hata vermeyecektir ve 8 numaralı satırdaki System.out.println()’den dolayı konsola -26 yazacaktır. Bunu detayıyla şu şekilde açıklayabiliriz:

Bildiğiniz gibi güncel bilgisayar sistemleri 2’lik (binary) sistemle çalışırlar, yani herşey 1 ve 0 ile ifade edilir. Dolayısıyla sayi1 ve sayi2 değişkenlerimizin 2’lik sistemdeki karşılıkları şu şekildedir:

sayi1=120=(01111000)2

sayi2=110=(01101110)2

Sayıların 2’lik sistemdeki karşılıklarının başındaki 0, byte tipinin 1 byte’lık yani 8 bitlik olma-sından dolayı sayıyı 8 bite tamamlamak içindir; ancak en başa eklediğimiz bu 0’ın taşıdığı çok daha farklı bir anlam vardır, Bu ilk değer sayının pozitif ya da negatif olmasını belirler. Eğer 0 ise arkasından gelen tüm bitler pozitif sayıya göre yorumlanacaktır, eğer 1 ise negatif sayıya göre yorumlanacaktır. Şimdi de sayıları toplayalım:

sayi1+sayi2=120+110=230

sayi1+sayi2=(01111000)2+(01101110)2=(11100110)2

toplam=(11100110)2

Az önce bahsettiğimiz işaret biti durumundan dolayı 2’lik sayının en başındaki değer olan 1, ge-risindeki 7 bitin negatif sayıya göre yorumlanacağını gösterir. Dolayısıyla Java’da tamsayıların tümünde sayı değeri en soldaki bitin pozitif ya da negatif olması durumu netleştikten sonra ortaya çıkar. Örnek olarak şu sayıları ele alalım:

5=(00000101)2

En baştaki 0 sayının pozitif olduğu anlamına gelir. Devamındaki 0000101’de de ilk 1’e kadar olan 0’ların bir anlamı yoktur. Böylece elimizde (101)2 kalır. Bunun da karşılığı 10’luk sistemde 5’tir. Açılımı ise şu şekildedir.

1x20=1

0x21=0

1x22=4

1+0+4=5

Bu noktadan sonra eğer sayımız negatif ise durumun değiştiğini göreceğiz. Örnek olarak -1’i ele alacağız.

Eğer 1 = (00000001)2 ise; -1 = (11111110)2 + (00000001)2’dir. Yani (11111111)2’dir. Bu yönteme 2’nin tamlayanı yöntemi denir. (11111110)2 de (00000001)2’nin bire tamlayanıdır. Burada niçin bu kadar dolandırılmış diye düşünebilirsiniz; ancak unutmayın ki gündelik hayatta kullandığımız gibi bir “-” işaretine sahip değiliz. Bu durumu -1 ile 1’i toplayarak deneyelim:

(00000001)2+(11111111)2=(100000000)2

Elimizde 9 bitlik bir veri oluştu; ancak byte veri tipi 8 bitlik bir veri tipiydi. Bu durumda en baştaki 1 değeri hiçbir değerlendirmeye katılmadan son 8 bit değerlendirilir; yani (00000000)2 değeri kul-lanılır. Burada ilk bit 0 olduğu için sayı pozitiftir diyebiliriz. Geri kalan 7 bit de 0 olduğu için sayı 10’luk sistemdeki 0’a karşılık gelir. Bu durumda aklınıza takılabilecek olan soru 0’ın pozitifliği ya da negatifliği olabilir. 0 sayısı matematikte ne pozitif tam sayılar kümesinin ne de negatif tamsayı-lar kümesinin bir üyesidir; ancak programlama dillerinde 0 değeri pozitiftir.

13Java’ya Giriş

Page 20: Bilge adam java.pdf

Sonuç olarak bilgisayar için negatif bir sayının 2’lik sistemde nasıl yazıldığını bulmak istiyorsak şu şekilde bir işlem gerçekleştirmeliyiz:

Sayıyı 2’lik sistemde pozitif olarak yazın.

Oluşan sayıdaki 0’ları 1, 1’leri 0 yapın.

Sayıya 2’lik sistemde 1 ekleyin.

Örnek olarak -5’e ulaşmaya çalışalım:

5=(00000101)2

1’etamlayan=(11111010)2

2’yetamlayan=(11111011)2

Böylece Uygulama 1.4b’nin açıklamasında elde ettiğimiz (11100110)2 değerini irdeleyebilir duru-ma geldik. Yukarıdaki işlemi tersten yaptığınızda da sayıya ulaşabilirsiniz.

(11100110)2–(00000001)2=(11100101)2

1’etamlayan=(00011010)2

(00011010)2=26

Dolayısıyla elimizdeki sayı 10’luk sistemdeki -26’ya karşılık gelir. Bu detayları bilmemeniz halinde basit bir sayısal problem üzerinde çok zaman harcayabilirsiniz. Çünkü gördüğünüz şekilde Java aritmetik işlemlerde taşan sayılar için hata vermez.

Java’da OperatörlerJava’da tipler üzerinde işlem yapmak için pek çok operatör bulunur. Bu operatörlerin çoğu C#’ta da aynı şekilde mevcuttur.

Öncelik Sırası

Öne gelen (prefix) ++ifade, --ifade

Sona gelen (postfix) ifade++, ifade--

Tek ifade alan +ifade, -ifade, ~, !

Çarpımsal *, /, %

Toplamsal +, -

Kaydırma <<, >>, >>>

İlişkisel <, >, <=, >=, instanceof

Eşitlik ==, !=

Bit üzerinde (bitwise) VE (AND) &

Bit üzerinde özel VEYA (EX-OR) ^

Bit üzerinde VEYA (OR) |

Mantıksal VE (AND) &&

Mantıksal VEYA (OR) ||

Üçlü ifade alan (ternary) operatör ? :

Atama =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>=, >>>=

14 Bölüm 1

Page 21: Bilge adam java.pdf

Gördüğünüz gibi Java’daki birkaç operatör dışında hemen hemen tüm operatörler C# ile aynıdır. Bit üzerinde işlem yapan operatörler kestirmeli (shortcut) operatörlerdir. Yani operandlarından (işleme giren değerlerinden) biri işlemin sonucunu kesin olarak ortaya koyuyorsa işlemin deva-mındaki operand değerlendirilmez.

Örnek Uygulama 1.5a:

1publicclassOperatorler1

2{

3 publicstaticvoidmain(String[]args)

4 {

5 intsayi,sonuc;

6 sayi=5;

7 sonuc=sayi+++++sayi;

8 System.out.println(sonuc);

9 System.out.println(sayi);

10 }

11}

Bu uygulamada 8 ve 9 numaralı satırlar işlendiğinde ekranda yazacak değerlerin ne olduğunu ve 7 numaralı satırın nasıl işlediğine bakalım. 6 numaralı satırda sayi değişkeninin değeri 5 yapıl-dıktan sonra 7 numaralı satırda sonuc = sayi++ + ++sayi; ifadesi işletilmektedir. Bu satırı daha detaylı inceleyelim:

sonuc = sayi++ + ++sayi; ifadesinde önce ++sayi ifadesi çalışacaktır ve sayi değişke-nine 1 ekleyerek değerini 6 yapacaktır. Daha sonra sayi++ işlemeden sayi değeri ile artırılmış sayi değerleri toplanarak sonuc değişkenine atama yapılacaktır. Böylece 6 + 6 = 12 değeri so-nuc değişkeninin değeri olur. Bu atama yapıldıktan sonra sayi değişkenine sayi++’dan dolayı tekrar 1 eklenecektir ve sayi değişkeninin değeri 7 olacaktır.

Kaydırma (Shift) İşlemleriKaydırma işlemleri genellikle sistem programlama, oyun programlama gibi uzmanlık gerektiren alanlarda kullanılır. Değerimizi temsil eden 2’lik sayı sistemindeki değeri sağa ya da sola belirti-len bit sayısı kadar kaydırır ve kaydırılan alanlara 0 değerini koyar. İşaret bitiyle ilgili detayları da vardır. Bu sebeple bir örnekle gösterip detaylı olarak anlatmayacağım.

Örnek Uygulama 1.5b:

1publicclassOperatorler2

2{

3 publicstaticvoidmain(String[]args)

4 {

5 intsayi;

6 sayi=5;

7 sayi<<=2;

8 System.out.println(sayi);

9 }

10}

Bu örnekte 7 numaralı satırda sayi değişkeninin bitleri 2 kademe sola kaydırılmaktadır. Bu işlem nasıl yapılıyor inceleyelim:

15Java’ya Giriş

Page 22: Bilge adam java.pdf

int 32 bit (4 byte) olduğu için 2’lik sayı sisteminde aşağıdaki gibi gösterilir.

sayi=5=00000000000000000000000000000101

Bu değer sola 1 bir kaydırıldığında;

sayi=000000000000000000000000000001010=10

değeri elde edilir. En baştaki 0 düşen bittir, ve en sondaki 101 değerleri sola kaydırılarak en sona da 1 tane 0 eklenmiştir.

sayi <<= 2 ifadesi sola doğru 2 bitlik kaydırma işlemi olduğu için sayi 1 bit daha sola kaydırıl-malıdır.

sayi=0000000000000000000000000000010100=20

Böylece sayi değişkeninin değeri 20 olur. Dikkat ederseniz sola kaydırma 2 ile çarpma gibidir.

İşlemlerde Parantez KullanımıMatematiksel ya da mantıksal işlemlerde parantezlerin içine alınan ifadelerin önceliği ilk sıraya çı-kar. Matematik bilgimizden tek farkı kullandığımız tek işaretin sadece normal parantez olmasıdır, köşeli parantez ya da küme parantezi kullanılmaz.

Örnek: Bu ifadeyi matematiksel olarak yazmak istediğimizde eğer;

d=m*P/n*r*T;

şeklinde yazarsak çarpma ve bölmenin önceliklerinin aynı olması sebebiyle işlem soldan sağa sırayla gerçekleşecektir. Böyle olunca m ile P çarpıldıktan sonra n ile bölünecek, bunun sonucu da r ile T’nin çarpımıyla çarpılacaktır. Oysa ifadenin gösterdiği m ile P’nin çarpımının n, r ve T’nin çarpımına bölünmesi şeklindedir. Bu sebeple bu matematiksel ifadeyi;

d=m*P/(n*r*T);

şeklinde yazmalıyız.

Karar Vermek ve Koşullu İfadelerJava’da da C#’taki gibi karar verme ve koşullu ifade yazmak için 2 ifade ve 1 operatör söz konu-sudur. Bunlar:

if...else

Üçlü ifade alan operatör (? :)

switch...case

if...else Yapısıif... else yapısı Java’da da aynen C#’taki gibi kullanılır. En basit yapısı sadece if’in kullanıldığı şeklidir. Koşullu ifadelerde dikkat edilmesi gereken nokta koşulun sonucunun true ya da false, yani boolean bir ifade üretmesi gerekliliğidir. Bu yönüyle C geleneğiyle farklılaşır.

1�

2.

3�

16 Bölüm 1

Page 23: Bilge adam java.pdf

Örnek Uygulama 1.6a:

1importjavax.swing.JOptionPane;

2publicclassKosul1

3{

4 publicstaticvoidmain(String[]args)

5 {

6 intsayi1=Integer.parseInt(JOptionPane. showInputDialog(“Birinci sayıyı giriniz”));

7 intsayi2=Integer.parseInt(JOptionPane. showInputDialog(“Ikinci sayıyı giriniz”));

8 if(sayi1<sayi2)

9 {

10 JOptionPane.showMessageDialog(null,sayi1+

“kucuktur“+sayi2);

11 }

12 }

13}

8 numaralı satırda yapılan karşılaştırmanın sonucu, yani sayi1 değişkeninin değerinin sayi2 değiş-keninin değerinden küçük olma durumu true ya da false, daha genel bir ifadeyle boolean bir so-nuç üretir. Eğer karşılaştırmanın sonucu true ise if bloğunun içi çalıştırılır, if bloğu sonlandığında da akış kaldığı yerden devam eder; aksi takdirde if bloğunun içi çalıştırılmadan programın akışı if�bloğu yokmuş gibi çalışmaya devam eder. Koşullar gibi bir sonraki bölümde inceleyeceğimiz döngü ve tekrarlı yapılarda da kodun okunurluğunu artırmak için if bloğunun içi tek ifadeden oluşsa bile blok parantezlerini, tek ifade için şart olmamasına rağmen kullanmayı alışkanlık haline getirin.

Örnek Uygulama 1.6b:

1importjavax.swing.JOptionPane;

2publicclassKosul2

3{

4 publicstaticvoidmain(String[]args)

5 {

6 intsayi1=Integer.parseInt(JOptionPane. showInputDialog(“Birinci sayıyı giriniz”));

7 intsayi2=Integer.parseInt(JOptionPane. showInputDialog(“Ikinci sayıyı giriniz”));

8 if(sayi1<sayi2)

9 {

10 JOptionPane.showMessageDialog(null,sayi1+

“kucuktur“+sayi2);

11 }

12 elseif(sayi1>sayi2)

13 {

14 JOptionPane.showMessageDialog(null,sayi1+

“buyuktur“+sayi2);

15 }

16 }

17}

17Java’ya Giriş

Page 24: Bilge adam java.pdf

Bu örnekteki çalışma şekli Uygulama 1.6a’dakiyle aslında aynı şekildedir. Eğer 8 numaralı satır-daki karşılaştırma true sonuç vermezse akış 12 numaralı satırdan devam edecektir. Bu blok da else bloğudur. else bloğu aslında if bloğundan sonraki akışın ilk parçasıdır. else bloğunda bir karşılaştırma daha yapılmaktadır. Bu karşılaştırmada da aynen 8 numaralı satırdaki if bloğu gibi bir çalışma mekanizması söz konusudur. Eğer karşılaştırma sonucu true ise else bloğu ça-lışır; aksi takdirde else bloğundan sonraki noktadan; yani 16 numaralı satırdan itibaren çalışma devam eder. Bu uygulamada, Örnek Uygulama1.6a’ya göre farklılaşan tek nokta eğer 8 numaralı satırdaki karşılaştırma true sonuç üretirse 12 numaralı satırdaki else bloğu, her ne kadar ken-dinden sonra gelen ilk ifade olsa da çalışmaz.

Örnek Uygulama 1.6c:

1importjavax.swing.JOptionPane;

2publicclassKosul3

3{

4 publicstaticvoidmain(String[]args)

5 {

6 intsayi1=Integer.parseInt(JOptionPane. showInputDialog(“Birinci sayıyı giriniz”));

7 intsayi2=Integer.parseInt(JOptionPane. showInputDialog(“Ikinci sayıyı giriniz”));

8 if(sayi1<sayi2)

9 {

10 JOptionPane.showMessageDialog(null,sayi1+

“kucuktur“+sayi2);

11 }

12 elseif(sayi1>sayi2)

13 {

14 JOptionPane.showMessageDialog(null,sayi1+

“buyuktur“+sayi2);

15 }

16 else

17 {

18 JOptionPane.showMessageDialog(null,sayi1+

“esittir“+sayi2);

19 }

20 }

21}

Bu uygulamada değişen tek nokta 16 numaralı satırdaki koşulu olmayan else bloğudur. Böylece sayi1 değişkenin değeri ile sayi2 değişkeninin değeri arasında yapılan karşılaştırmada durum ne olursa olsun, bir exception üretilmediği sürece, bu 3 bloktan birinin çalışması kesindir. 16 nu-maralı satırdaki else bloğunun çalışması için 8 ve 12 numaralı satırlardaki karşılaştırmalardan false üretilmesi gerekir. Bu örnekte bu durum 2 sayıyı karşılaştırırken, iki sayının birbirine eşit olması durumudur. Bu bloklardan hangisi çalışırsa çalışsın, akış 20 numaralı satırdan devam edecektir.

18 Bölüm 1

Page 25: Bilge adam java.pdf

Örnek Uygulama 1.6d:

1importjavax.swing.JOptionPane;

2publicclassKosul4

3{

4 publicstaticvoidmain(String[]args)

5 {

6 intsayi1=Integer.parseInt(JOptionPane. showInputDialog(“Birinci sayıyı giriniz”));

7 intsayi2=Integer.parseInt(JOptionPane. showInputDialog(“Ikinci sayıyı giriniz”));

8 if(sayi1<sayi2)

9 {

10 JOptionPane.showMessageDialog(null,sayi1+

“kucuktur“+sayi2);

11 }

12 elseif(sayi1<sayi2)

13 {

14 JOptionPane.showMessageDialog(null,sayi1+

“buyuktur“+sayi2);

15 }

16 }

17}

Bu uygulamalarda göstermek istediğim durum 8 ve 12 numaralı satırlardaki karşılaştırmaların aynı olmasıdır. Bu durumda eğer 8 numaralı satırdaki karşılaştırma true üretirse 12 numaralı satır, aynı karşılaştırmayı yapmasına rağmen çalışmayacaktır. Eğer 8 numaralı satırdaki karşılaş-tırma false üretirse 12 numaralı satırdaki aynı karşılaştırma tekrar yapılacaktır ve doğal olarak o da false üreteceğinden else bloğu da çalışmayacaktır. Bunun da anlamı uygulamada durum ne olursa olsun hiçbir zaman else bloğunun çalışmayacağıdır.

Sayısal karşılaştırmalardan sonra şimdi mantıksal işlemlere bakalım. Mantıksal işlemler sayısal ifadelerden farklı olarak zaten boolean sonuç üretir. Mantıksal işlemler AND (VE), OR (VEYA), EX-OR (ÖZEL VEYA), NOT (DEĞİL) işlemleridir. Mantıksal işlemlerin kestirmeli ve kestirmesiz olmak üzere 2 şekli vardır. Kestirmeli (short-circuited) işlemler doğruluğu kontrol edilecek ifa-denin içinde bulunan ifadelerden herhangi biri bütün ifadenin sonucunu belirlediği anda diğer ifadeler kontrol edilmez. Kestirmeli (short-circuited) işlemlerde, bir ifadenin içinde bulunan bütün ifadelerin doğruluğu kontrol edilir, sonuç belirlense bile işlem sona ermez.

19Java’ya Giriş

Page 26: Bilge adam java.pdf
Page 27: Bilge adam java.pdf

2 Döngüler

Page 28: Bilge adam java.pdf

2 DöngülerWhile Döngüsü

do Döngüsü

for Döngüsü

break ve continue Deyimleri

Page 29: Bilge adam java.pdf

DöngülerBirçok programlama dilinde olduğu gibi, Java dilinde de döngüler önemli bir yere sahiptir. Döngü-ler, yinelenen işlemler için oluşturulan kod bloğunun, belirli bir koşula bağlı olarak tekrarlanmasını sağlayan yapılardır.

Java dilinde 3 tip döngü mevcuttur. Bunlar;

while

do

for

döngüleridir.

Oluşturulan döngü yapıları birkaç farklılık dışında, içinde bulunan kod parçacığını baştan belirle-nen ya da program akışı içerisinde belirlenen sayıda tekrarlanmasını sağlar. Döngüler belirli sayı-da işlenmek üzere kurulabileceği gibi kod bloğu içerisinde gerçekleştirilecek bir koşul sağlanana kadar tekrarlanmak üzere de gerçekleştirilebilir.

Döngülerin oluşturulması sırasında dikkat edilmesi gereken en önemli noktalardan biri, döngü içerisinde işlenecek kod parçacığının işlem sayısıdır. Belirli bir sayı ya da bir kontrol koşulu ile kurulmayan döngüler, program akışının sürekliliğini bozarak çalışan kodu sonsuz döngüye soka-bilir.

Bir döngünün işlenmesi sırasında ya da sonsuz döngü durumunda, kod bloğunun içerisinde mü-dahaleler gerekli olabilir. Bu müdahaler de break ve continue yapıları ile sağlanmaktadır.

While Döngüsüwhile döngüsünün genel yapısı aşağıdaki gibidir.

while(boolean_kontol_ifadesi){

Tekrarlanan_Ifade(ler);

}

Bu ifadede yer alan boolean_kontol_ifadesi� kontrolu sonrasında boolean bir sonuç veren her-hangi bir ifade olabilir. Tekrarlanan_Ifade(ler) ise yinelenmesi istenen kod bloğudur.

C ve C++ dillerinde farklı veri tipleri ile kontrol yapılabilirken, Java da farklı olarak buradaki kontrol boolean bir ifade ile yapılabilir.

While döngüsünde yineleme, belirlenen koşulun sağlanmasına kadar devam edecektir. Yineleme kontrolu çevrimin başında yapılır. Kontol ifadesinin sağlanmaması halinde, döngü içerisinde tek-rarlanması istenen kod parçacığı hiç çalışmayabilir.

Örnek uygulama 2.1:

1 intsayac=0;

2 while(sayac++<5){

3 system.out.println(“MerhabaDünya”)

4}

Uygulama 2.1’ i incelediğimizde, ilk satırda, sayac adlı bir değişken tanımlanarak 0 değeri atan-mıştır. Kontrol ifadesi, sayac++ ifadesiyle artırılan sayac değeri 5’ten küçük olduğu sürece “Mer-haba Dünya” ifadesi yazdırılacaktır. Bu örnekte “Merhaba Dünya” ifadesi 5 kez yazılacaktır.

Page 30: Bilge adam java.pdf

do DöngüsüGenel yapısı,

do{

Tekrarlanan_Ifade(ler);

}while(boolean_kontol_ifadesi)

şeklindedir.

do döngüsü işleyiş biçimi olarak while döngüsüne benzer. Benzer şekilde bu yapıda da boolean bir koşul ile döngünün yinelenmesi kontrol edilmektedir. do döngüsünün en önemli farkı, kontol ifadesi başta değil sonda yapıldığından tekrarlanan ifade(ler) en azından bir kere işlenecektir.

for DöngüsüBirçok programlama dilindeki temel gereksinimlerden biri olan, bir değişkenin belirli bir aralıkta artırılması ile kurulan döngü yapılarının en çok kullanılanı for döngüsüdür.

Genel yapısı;

for(ifade;booelan_kontrol_ifadesi;deyim){

tekrarlanan_ifade(ler)

}

şeklindedir.

ifade olarak adlandırılan kod, sıra döngünün işlenmesine geldiğinde ilk olarak çalışan ifadedir. Henüz döngü içerisindeki kod parçacığı çalışmaya başlamadan bir defaya mahsus olarak çalışa-cak, sonraki iterasyonlarda bu ifade çalışmayacaktır. Çoğunlukla döngüde kullanılacak değişke-nin başlangıç değer atamasında kullanılır.

boolean_Kontrol_ifadesi doğru değerini verdiği sürece döngünün yinelenmesini sağlayan kon-trol ifadesidir. while döngüsünde olduğu gibi koşulun sağlanmaması durumunda for döngüsü de hiç çalışmayabilir.

deyim ise döngü bloğunun sonunda çalışır. Çoğunlukla kullanılan değişkenin arttırımı bu bölüm-de yazılan kod ile sağlanır.

Örnek Uygulama 2.2:

1For(intx=0;x<10;x++){

2 System.out.println(“Değer=” + x );

3}

Uygulama 2.2’de, döngüde kullanılan sayısal bir x değişkeni ilk ifadede tanımlanmış ve 0 değer ataması yapılmış, deyim bölümünde ise arttırımı gerçekleşmiştir. Kontrol ifadesi x değişkeninin 10’ dan küçük olduğu tüm değerler için doğrulanacak ve döngü aşağıdaki sonucu üretecektir:

Değer=0

Değer=1

.....

Değer=8

Değer=9

24 Bölüm 2

Page 31: Bilge adam java.pdf

for döngülerinde genellikle döngünün sayılması için kullanılan bir değişken ihtiyacı oldduğun-dan, ifade bölümünde değişken tanımlamasına ve değer atamasına izin verilmektedir. Burada ta-nımlanan değişken, sadece for döngüsü içinde geçerlidir. Böylece diğer kısımlarda tanımlanan değişkenler ile çakışma ihtimali engellenmektedir.

Döngü bloğu (scope) içerisinde kullanılacak başka değişkenler de yine ifade olarak adlandırılan bölümde tanımlanabilir. Bu işlem Örnek Uygulama 2.3’de belirtildiği gibi, tanımlanacak değişken-ler arasına virgül konularak yapılır.

Örnek Uygulama 2.3:

1intj,k;

2For(j=3,k=6;j+k<20;j++,k+=2){

3 System.out.println(“ j değeri=” + j +” k değeri= “ + k);

4}

break ve continue Deyimleribreak�ve�continue deyimleri Java’da da C#’ ta olduğu gibi kullanılır.

Döngü yapıları içerisinde zaman zaman kod bloğunun işlenmesi ile ilgili müdahale ihtiyaçları or-taya çıkabilir. Belirli bir noktada döngüden çıkmak ya da o anda işlenen çevrimin sonlandırılması istenebilir. Bu ihtiyaçlar break ve continue deyimleri ile sağlanır.

break�deyimi, kod bloğunda kullanıldığı yerde döngünün tamamen sonlandırılmasını sağlar. An-cak dikkat edilmesi gereken en önemli nokta, içiçe (nested) yapılar kullanıldığında break sadece bulunduğu döngü bloğunun sonlandırılmasını sağlar, bir üst döngü işlenmeye devam edecektir. �

25Döngüler

Page 32: Bilge adam java.pdf
Page 33: Bilge adam java.pdf

3 Niteleyiciler (Modifiers)

Page 34: Bilge adam java.pdf

3 Niteleyiciler (Modifiers)

Access Modifiers (Erişim Niteleyicileri)

Niteleyicilerde Metod Ezme (Access Modifiers Overriding)

Diğer Niteleyiciler

Page 35: Bilge adam java.pdf

Niteleyiciler (Modifiers)Niteleyiciler derleyiciye, kod bloğu içinde oluşturulan sınıf ve sınıf elemanları ile ilgili bilgi sağla-yan anahtar kelimeler grubudur.

En sık kullanılan niteleyiciler erişim niteleyicileridir. Bunlar;

public

protected

private

Erişim niteleyicileri dışında belirli bir biçimde kategorize edilemeyen niteleyiciler de bulunmakta-dır. Bunlar ise;

final

abstract

static

transient

synchoronized

volatile

Tanımlama sırasında bir niteleyici ile belirlenmeyen sınıf elemanları default�olarak belirlenir. De-fault kod içerisinde kullanılan bir anahtar kelime olmayıp, bir niteleyici saptanmamasını ortadan kaldırmak için otomatik olarak atanır.

Access Modifiers (Erişim Niteleyicileri)Erişim niteleyicileri olarak adlandırılan niteleyiciler, sınıf ve sınıf elemanlarının (değişken, method) erişim seviyeleri ile ilgili kısıtlama sağlar.

Sınıf, değişken ya da metodların tanımlamalarında kullanılan bu anahtar kelimelerle erişim kısıt-lamaları belirlenerek oluşturulan kodun güvenliği artırılır.

Bazı istisnalar dışında erişim niteleyicileri tarafından kontrol edilebilen değişkenler sınıf seviyesi değişkenlerdir. Bir sınıfın içerisinde tanımlanan değişkenler erişim niteleyicileri ile belirlenmemiş olabilir. Bir metod değişkeni sadece o metodun içerisinde kullanılır.

public Bir Java programında public olarak tanımlanan bir sınıf, değişken ya da metod herhangi bir kı-sıtlama olmaksızın kullanılabilir. Bir uygulamanın main() metodu, tüm Java runtime ortamlarından çağırılabilmesi için public olarak tanımlanır.

Üst sınıflarda (top-level class) kullanılabilen tek erişim niteleyicisi public’tir. Üst sınıflarda pri-vate ya da protected tanımlaması yapılmamaktadır.

privateprivate�olarak tanımlanan değişken ya da metodlar, sadece bulunduğu sınıf içinde kullanılabi-lir. Tanımlandığı sınıf dışından erişimi mümkün değildir.

protectedSadece değişken ve metodlar protected olarak tanımlanabilir. protected sınıf elemanları bu-lundukları paket (package) içerisinde erişilebilir durumdadır. Bu özelliğiyle default yapısında ben-zemekle beraber, yer aldığı sınıfın alt sınıfları (sub classes) tarafından da erişilebilir durumdadır.

protected olarak tanımlanan sınıf elemanı, bulunduğu sınıfın inherit edildiği bir başka package içerisinden de erişilebilir durumdadır.

Page 36: Bilge adam java.pdf

Niteleyicilerde Metod Ezme (Access Modifiers Overriding) Niteleyici olarak adlandırılan sınıf elemanlarında overriding aşağıda belirtilen biçimlerde gerçek-leşir.

Geçerli OverridingŞekil 1:

private olarak tanımlanan bir metod; private, default, protected�ve�public metod-lar tarafından override edilebilir.

Default bir metod; default, protected�ve�public metodlar tarafından override edilebilir.

protected bir metod; protected�ve�public metodlar tarafından override edilebilir.

public bir metod ise sadece public bir metod tarafından override edilebilir.

Geçersiz OverridingŞekil 2:

Default bir metod; private bir metod tarafından override edilemez.

protected olarak tanımlanan bir metod; default ve private metodlar tarafından override edilemez.

public bir metod ise; protected, default ve private metodlar tarafından override edile-mez.

Diğer Niteleyiciler Java’da kullanılan diğer niteleyicilerin tanımlanmasında sıra önem taşımaz. Örneğin public final tanımlaması ile final public tanımlaması birbirinden farklı değildir. Yine ptotected static�ile�static protected tanımlamaları aynı şekilde geçerli olacaktır.

finalfinal�niteleyicisi, sınıf, metod ve değişkenlere uygulanmaktadır. final�olarak belirlenen bir sınıf elemanı değiştirilemez.

Örneğin,

classSubMathextendsjava.lang.Math{}

ifadesi derlendiğinde, “Can’t subclass final classes.” hatası verecektir.

Dikkat edilmesi gereken önemli noktalardan biri, final bir değişken bir nesneye refere edildi-ğinde, değiştirilemeyen nesnenin instance’ı (örnek) değil, referans tipli değişkendir. Bir başka de-yişle; final bir referans nesne değişkeni değiştirilemez ancak yaratılan instance bu kısıtlanmadan etkilenmez. Final niteleyicisinin C#’taki karşılığı sealed anahtar kelimesidir.

private default protected public

public protected default private

30 Bölüm 3

Page 37: Bilge adam java.pdf

abstract abstract�niteleyicisi sınıf ve metodlara uygulanmaktadır. abstract,. Microsoft .NET platfor-mu üzerinde kullanılan Visual Basic .NET dilinde abstract bir sınıf oluşturmak için kullanılan anahtar kelime MustInherit’tir. Buradan anlayacağınız gibi, abstract bir sınıftan mutlaka türetme yapılmalıdır ve türetilen sınıf kullanılmalıdır.

Eğer bir sınıf birden fazla abstract metoda sahipse, derleyici sınıfın abstract olar-ak tanımlanmasını zorlar. Bu durum kullanılabilirliği artırır. Sınıfı kullanırken, türetilen sınıf kullanılması gerektiğini ya da örneklenebileceğinin belirlenmesi için bakılması gereken yer sınıfın tanımlamasıdır.

Aşağıda belirtilen durumlardan en az birisi gerçeklendiğinde, derleyici bir sınıfın abstract olarak tanımlanmasını zorlayacaktır.

Sınıf birden çok abstract metoda sahipse

Sınıf implementasyon sağlamayan bir veya birden çok abstract metod inherit ediyorsa

Sınıf bir arayüz (interface) implemente etmek üzere tanımlandığı halde, interface’in tüm me-todları için implementasyon sağlamıyorsa

staticstatic�niteleyicisi değişkenler, metodlar hatta bir metodun parçası olmayan kod blokları için kullanılabilir. static olarak belirlenen sınıf elemanları bir sınıfla bağlantılı olmaktan çok sınıfa ait olarak düşünülebilir.

static olarak belirlenmiş bir değişkenin değeri, ne kadar instance (örnek) türetilmiş olursa olsun değerini koruyarak sabit kalacaktır.

static bir değişkeni refere etmenin iki yolu vardır:

Sınıfın instance’ına referans verme yolu ile.

Sınıf adı ile.

Metodlar da static olarak tanımlanabilir. Sınıfın static verilerine ulaşabildikleri ve sınıfın diğer static metodlarını çağırabildikleri halde, static metodlar sınıflarının non-static (statik olmayan) elemanlarını kullanamazlar.

Non-static metodlar this�adlı örtülü (implicit) bir değişkene sahiptir. Non-static metodlarda, hangi nesnenin ya da metodun olduğunu belirtmeden bir değişken veya metod çağırılabilir.

Örnek Uygulama 3.1:

1classXyz

2{

3 intix;

4 voidf1(){

5 ix++;

6 }

7}

Örnek Uygulama 3.1’de tanımlanan ix değişkeni, hangi nesne ya da metoda ait olduğu belirtil-meden ix++ ifadesi ile artırılmaktadır. Derleyici varsayılan olarak bu ifadeyi this.ix++ olarak algılar ve doğru bir biçimde işler.

static metodlarda ise this�yapısı bulunmamaktadır. static bir metod içerisinden, bir başka metod ulaşılmak ya da çağırılmak istendiğinde ”Undefined variable:this” hatası verecektir.

31Niteleyiciler (Modifiers)

Page 38: Bilge adam java.pdf

static bir metod, non-static bir değişkene ulaşmak istediğinde hangi sınıfın değişkeni olduğunu ya da metodu çalıştıran sınıfın hangisi olduğunu belirterek çağırmak zorundadır.

static bir metod non-static olarak override edilemez. Bu durumda “Static methods can’t be overriden” hata mesajı verecektir.

transienttransient niteleyicisi sadece değişkenler için kullanılmaktadır. transient bir değişken kendi objesinin sürekli bir parçası olarak tutulmaz.

synchronizedsynchronized� değişkenler multithread programlarda, kritik kodlara erişimi kontrol etmek amacıyla kullanılır. Multithreading daha sonraki bölümlerde detaylı olarak incelenecektir.

volatile volatile olarak belirlenen değişkenler asenkron olarak değiştirilebilen değişkenlerdir.�vola-tile değişkenler çok işlemcili ortamların konusudur.

Niteleyiciler ile ilgili özeti aşağıdaki tabloda bulabilirsiniz.

Şekil 3:

* default bir niteleyici değil, niteleyici belirlenmediğinde varsayılan olarak kullanılan anahtar söz-cüktür.

Niteleyici Sınıf Değişken Metod Constructor

public

protected –

(Default)*

private –

final –

abstract – –

static – –

transient – – –

volatile – – –

synchronized – – –

32 Bölüm 3

Page 39: Bilge adam java.pdf

4 Casting ve Conversion

Page 40: Bilge adam java.pdf

4 Casting ve ConversionBasit Tiplerde Conversion

Referans Tiplerde Conversion

Page 41: Bilge adam java.pdf

Casting ve ConversionJava’ da, C# ve tüm programlama dillerinde olduğu gibi kullanılan her değişkenin bir tipi vardır. Bunlar int, long�ve�double gibi basit (primitive) değişkenler olduğu gibi, sınıf değişkenleri (Ve-ctor, Graphics vb) ya da arayüzler (LayoutManager ve Runnable vb) olabilir.

Bu bölümde, veri tipleri arasındaki dönüşümleri ele alacağım.

Veriler gerek açıkça (explicitly) ya da örtülü (implicitly) olarak dönüştürülebilir. Bir başka deyişle kendi bilgi ve isteğimiz dahilinde ya da derleyici tarafından otomatik olarak yapılan veri tipi dönü-şümleri mümkündür.

Açıkça gerçekleştirilen veri tipi dönüşümleri casting olarak adlandırılır. Bu durumda kodlama es-nasında kendi isteğimizle bir değişkenin tipini değiştiririz.

Örnek Uygulama 4.1:

1ix=(int)mylix;

Örnek Uygulama 4.1’de, mylix değişkeni, int olarak ix değişkenine casting yapılarak atan-maktadır.

Örtülü olarak gerçekleşen veri tipi dönüşümleri ise, değişken atamaları sırasında derleyici tara-fından otomatik olarak yapılmaktadır. Açık olmayan, örtülü dönüşümler conversion olarak adlan-dırılır.

Örnek Uygulama 4.2:

1intx,y;

2doubled;3x=3;

4y=5;5d=x+y;

Örnek Uygulama 4.2’de double değişkenine atanan tam sayı değerlerin toplamı 8.000000... de-ğerini alacaktır. Bu durumda gerçekleştirilen değişken tipi dönüşümü derleyici tarafından otomatik olarak gerçekleştirilecektir.

Java programlama dilinde basit tipler ve referans tipleri olmak üzere iki veri tipi kategorisi bulun-maktadır.

Basit tipler olarak adlandırılan veri tipleri; boolean, char, byte, short, int, long, float, double’dır. Referans tipleri ise; JDK tarafından sağlanan birçok sınıf, arayüzün yanısıra, Java geliştiricileri tarafından geliştirilen sınıflardır.

Basit tipler ve referans tipleri olarak anılan tüm veri tipleri arasında, belirli kurallar dahilinde cas-ting ve conversion mümkündür. Bu bağlamda, 4 çeşit veri tipi dönüşümü ortaya çıkmaktadır:

Basit veri tipleri arasında conversion

Basit veri tipleri arasında casting

Referans tipleri arasında conversion

Referans tipleri arasında casting

Page 42: Bilge adam java.pdf

Basit Tiplerde ConversionBasit veri tiplerinin dönüşümünde 3 tip conversion karşımıza çıkar, bunlar:

Atama

Metod çağırma

Aritmetik yükseltme (arithmetic promotion)

Basit Tiplerde Conversion: AtamaAtama dönüşümü, bir değişkene orijinal değerinden farklı bir değer ataması yapıldığında gerçek-leşir.

Örnek Uygulama 4.3:

1inti;

2doubled;

3i=10;

4d=i;

Örnek Uygulama 4.3’de tanımlanan i int, d ise double değişkenlerdir. double bir değişken tamsayı ifade saklayamayacağından, d = i ataması yapıldığında, d değişkeninin sakladığı de-ğer 10.000000... olacaktır.

Ancak bazı atamalar yukarıda verdiğimiz örnekteki gibi geçerli ifadeler olmayacaktır.

Örnek Uygulama 4.4:

1doubled;

2shorts;

3d=1.2345;

4s=d;

Örnek Uygulama 4.4’te yer alan atama, double bir ifadenin short veri tipine atanması şeklinde-dir. short veri tipi double değerini saklayamaz. Bu kod işlenmeyecek, “Incompitable type for=.” hatasını verecektir.

Daha büyük değer saklayan değişkenlerden daha küçük değer taşıyan değişkenlere dönüşüm bir şişedeki sıvıyı küçük bir bardağa taşımaya benzer ancak explicit casting kullanılmalıdır.

Basit tiplerde atamanın genel kuralları şu şeklidedir:

boolean bir veri tipi diğer veri tiplerine çevrilemez.

Genişletme dönüşümü (widening conversion) sözkonusu ise, boolean olmayan (non-boole-an) bir veri tipi, boolean olmayan bir veri tipine dönüştürülebilir.

Daraltma dönüşümü (narrowing conversion) sözkonusu ise boolean olmayan bir veri tipi, boolean olmayan bir veri tipine dönüştürülemez.

Genişletme dönüşümü, daha küçük değerler saklayan veri tiplerinden daha geniş değerler sakla-yan veri tiplerine gerçekleştirilebilir. Bu durumda herhangi bir veri kaybı olmayacaktır. Genişletme Dönüşümü;

byte veri tipinden; short, int, long, float veya double veri tiplerine,

short veri tipinden; int, long, float veya double veri tiplerine,

char veri tipinden; int, long, float veya double veri tiplerine,

36 Bölüm 4

Page 43: Bilge adam java.pdf

int veri tipinden; long, float veya double veri tiplerine,

long veri tipinden; float veya double veri tiplerine,

float veri tipinden; double veri tipine

gerçekleştirilebilir.

Şekil 4.1:

Şekil 1’de belirtilen tüm dönüşümler veri kaybı yaşanmaksızın yapılan dönüşümlerdir. Yine şe-kilde belirtilen ok yönü dışında gerçekleştirilecek dönüşümler ise daraltma dönüşümü (narrowing conversion) olarak tanımlanır. Bu tip conversionlarda veri kaybı olabilir. Daraltma dönüşümü ise;

byte veri tipinden; char veri tipine,

short veri tipinden; byte veya char veri tiplerine,

char veri tipinden; byte veya short veri tiplerine,

int veri tipinden; byte, short veya char veri tiplerine,

long veri tipinden; byte, short, char veya int veri tiplerine,

float veri tipinden; byte, short, char, int veya long veri tiplerine,

double veri tipinden; byte, short, char, int, long veya float veri tiplerine

gerçekleştirilebilir.

Java programlama dilinde ondalıklı sayısal değerler double, ondalıksız sayısal ifadeler inte-ger veri tipindedir. Normal koşullarda, integer� ve�double değerlerin daha küçük değerler tutan değişkenlere atanmasının derleyici hatasına sebep olacağını düşünebiliriz. Ancak Java bu durumları kendi içinde esneterek ve atamayı hatasız olarak gerçekleştirir.

Örnek Uygulama 4.5:

1floatf=2.345;

2byteb=3;

3shorts=5;

4charc=7;

Örnek Uygulama 4.5’te belirtilen atamalar hatasız olarak gerçekleşecektir. Örnek Uygulama 4.6’de belirtilen kodun ikinci satırı ise sayısal ifade ataması yapılmadığından derlenmeyecektir.

Örnek Uygulama 4.6:

1inti=15;

2byteb=i;

byte

char

short

int long float double

37Casting ve Conversion

Page 44: Bilge adam java.pdf

Basit Tiplerde Conversion: Metod ÇağırmaMetod Çağırma dönüşümü, belirli bir veri tipinde argüman bekleyen bir metoda, farklı bir veri tipin-de argüman sağlandığında derleyicinin otomatik olarak gerçekleştirdiği dönüşümdür.

Örnek Uygulama 4.7:

1floatf;

2doubled;

3f=2.34567f;

4d=Math.cos(f);

Örnek Uygulama 4.7’de belirtilen Math sınıfına ait cos() metodu, veri tipi olarak double bir argüman beklemektedir. f değişkeninin float değeri cos() metodunda işlenmeden önce oto-matik olarak double veri tipine dönüştürülecektir.

Metod çağırma dönüşümlerinde de atama dönüşümlerini belirleyen kurallar geçerlidir. Derleyici zamanında (compile time) genişletme dönüşümüne izin verilirken, daraltma dönüşümüne izin verilmez.

Basit Tiplerde Conversion: Aritmetik Yükseltme Aritmetik yükseltme, aritmetik ifadeler kullanılarak işlem yapıldığında gerçekleşen dönüşüm tipi-dir.

Örnek Uygulama 4.8:

1shorts=5;

2inti=8;

3floatf=13.2f;

4doubled=13.2;

5if(s–i<=f*d)

6 system.out.println( “İlk işlem küçük veya eşit”;

7else

8 system.out.println( “İlk işlem küçük veya eşit değil”;

Örnek Uygulama 4.8, if bloğunun içinde aritmetik ifadeler ile işlenen değişkenler farklı veri tiple-rindedir. Derleyici, aritmetik işlemleri anlamlı bir biçimde gerçekleştirmek için gerekli dönüşümleri otomatik olarak gerçekleştirecektir. Bu dönüşümlerin tamamı daha önce belirttiğimiz genişletme dönüşümü olacaktır.

Aritmetik yükseltme dönüşümü kuralları tekli operatörler (unary operators) ve ikili operatörler (bi-nary operators) için farklılaşmaktadır. Tekli operatörler tek bir işlenen (operand) üzerinde işlem yaparken, ikili operatörler iki işlenen üzerinde işlem yapmaktadır.

Şekil 4.2:

Tekli operators + - ++ -- ~

Binary operators

+ - * / % >> >>> <<

& ^ |

38 Bölüm 4

Page 45: Bilge adam java.pdf

Tekli operatörler için uygulanan dönüşüm kuralları aşağıdaki gibidir;

Eğer kullanılan işlenenin veri tipi byte, short ya da char ise; int veri tipine dönüştürülür. (Eğer kullanılan operatör ++ ya da -- ise dönüşüm yapılmayacaktır)

Yukarıda belirtilen dışındaki veri tiplerinde dönüşüm yapılmaz.

İkili operatörler için uygulanan kurallar ise aşağıdaki şekilde belirlenmiştir.

Eğer işlenenlerden birinin veri tipi double ise, diğer işlenen double veri tipine dönüştürü-lecektir.

Eğer işlenenlerden birinin veri tipi float ise, diğer işlenen float veri tipine dönüştürülecek-tir.

Eğer işlenenlerden birinin veri tipi long� ise, diğer işlenen long veri tipine dönüştürülecek-tir.

Yukarıda belirtilen dışındaki veri tiplerinde int veri tipine dönüştürülecektir.

Basit Tiplerde CastingŞimdiye kadar ele aldığımız dönüşüm tipleri örtülü olarak gerçekleştirilen, Java’nın otomatik ola-rak gerçekleştirdiği dönüşümlerdi. Bu dönüşümler, açıkça bir kod yazmamızı gerektirmeyen dö-nüşümlerdir.

Casting ise, Java’ya bir dönüşümü yapmasını söylemektir. Veri tipleri arasındaki dönüşümü belir-leyen, yazacağımız kod olacaktır.

Genişletme dönüşümü olarak belirttiğimiz dönüşümlerde casting’e ihtiyaç duyulmamakta, derleyi-ci otomatik olarak yapmaktadır. Casting daha çok daraltma dönüşümü olarak bilinen dönüşümler-de kullanılmaktadır. Bu dönüşümlerde veride kayıp riski bulunduğundan, derleyici otomatik olarak yapmamakta, riskin alınarak dönüşümün sağlanması gerektiği yazılacak kod ile belirtilmelidir.

Örnek Uygulama 4.9:

1shorts=362;

2byteb=s;

3system.out.println(“s=”+s+“,b=”+b)

Örnek Uygulama 4.9’da belirtilen ifade derlendiğinde, 2. satırda derleyici hatası verecektir. Çünkü short veri tipinden daha dar bir veri tipi olan byte veri tipine atama yapılmak istenmektedir. Bu dönüşüm Şekil 4.3’ te belirtilmiştir.

Şekil 4.3:

0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 0

Bu durumda derleyici açıkça dönüşüm yapılması gerektiğini bildiren; Explicit cast needed to con-vert short to byte uyarısı verecektir. Örtülü casting yaparsak aşağıdaki durum oluşacak ve veri kaybı sözkonusu olacaktır.

b = (byte)s

39Casting ve Conversion

Page 46: Bilge adam java.pdf

Örnek Uygulama 4.10:

1shorts=362;

2byteb=(byte)s;

3system.out.println(“b=”+b)

b = 106 olarak yazılacaktır.

Basit veri tiplerinin casting yapılmasında aşağıdaki kurallar geçerlidir.

Boolean olmayan herhangi bir veri tipi, boolean olmayan herhangi bir veri tipine dönüştü-rülebilir.

Boolean bir veri tipi herhangi bir veri tipine, herhangi bir veri tipi boolean veri tipine dönüş-türülemez.

Referans Tiplerde Conversion Referans tipli değişkenleri de basit veri tipleri gibi atama, metod çağırma ve casting ile dönüştü-rülebilmektedir. Ancak eski ve yeni tipler arasındaki dönüşümlerde daha çok kombinasyon oldu-ğundan daha karmaşıktır.

Referans tiplerinde conversion da basit tiplerde conversion gibi derleyici zamanında gerçekleş-mektedir. Daha sonra belirteceğimiz üzere object casting için ise bu geçerli değildir.

Referans Tiplerde Conversion: Atama Referans tiplerde atama, bir nesne referans değerini farklı bir veri tipindeki değişkene atadığımız-da gerçekleşir. Genel notasyon olarak aşağıdaki biçimde uygulanmaktadır:

EskiTipx=newEskiTip();

YeniTipy=x;

Referans tiplerde conversion’da, eskitip ve yenitip üyeler (member) arasındaki dönüşüm kombi-nasyonları Şekil 4.4’te belirtilmiştir.

Şekil 4.4:

Tüm dönüşüm kurallarına uygulanmasa da, genel bir bakış açısı olarak, izin verilen referans tipi dönüşümleri, miras hiyerarşisinde (inheritance hierarchy) yukarı doğru olmaktadır. Yani, eskitip, yenitip’ten miraslanmalıdır.

Yen

i Tip

Eski Tip

Sınıf (Class) Arayüz (Interface) Dizi (Array)

Sınıf Eskitip, Yenitip’in altsınıfı olmalıdır.

Yenitip nesne olmalıdır. Yenitip nesne olmalıdır.

Arayüz (Interface)

Eskitip, yenitip’in arayüzünü implemente etmelidir.

Eskitip, Yenitip’in alt-arayüz’ü (subinterface) olmalıdır.

Yenitip cloneable ya da serializable olmalıdır.

Dizi (Array) Derleyici hatası oluşacaktır.

Derleyici hatası oluşacaktır.

Eskitip, yenitip’in dizisine dönüştürülebilecek bir dizi olmalıdır.

40 Bölüm 4

Page 47: Bilge adam java.pdf

Genel kuralları aşağıdaki şekilde belirlenebilir:

Bir arayüz sadece yine bir arayüze ya da nesneye dönüştürülebilir. Eğer yenitip bir arayüz ise, eskitip’in alt-arayüzü olmalıdır.

Bir sınıf yine bir sınıfa ya da arayüze dönüştürülebilir. Bir sınıfa dönüştürüldüğünde, yenitip eskitip’in alt-sınıfı olmalıdır. Bir arayüze dönüştürüldüğünde, eski sınıf arayüzü implemente etmelidir.

Bir dizi, sınıf nesnesine ya da cloneable veya serializable bir arayüze ya da diziye dönüştürü-lebilir. Sadece nesne referans tipinin dizisi bir diziye dönüştürülebilir ve eski eleman tipi yeni eleman tipine çevrilebilir olmalıdır.

Referans Tiplerde Csonversion: Metod Çağırma Genel olarak referans tiplerde atama dönüşümünde tanımlanan kurallar bu dönüşüm tipinde de geçerlidir. Bir süpersınıfa dönüşüme izin verilirken, altsınıfa dönüşüme izin verilmez.

Genel kuralları aşağıda belirtilmiştir.

Bir arayüz sadece yine bir arayüze ya da nesneye dönüştürülebilir. Eğer yenitip bir arayüz ise, eskitip’in alt-arayüzü olmalıdır.

Bir sınıf yine bir sınıfa ya da arayüze dönüştürülebilir. Bir sınıfa dönüştürüldüğünde, yenitip eskitipin alt-sınıfı olmalıdır. Bir arayüze dönüştürüldüğünde, eski sınıf arayüzü implemente etmelidir.

Bir dizi, sınıf nesnesine ya da klonlanabilir veya serileştirilebilir bir arayüze ya da diziye dö-nüştürülebilir. Sadece referans tipinin dizisi bir diziye dönüştürülebilir ve eski eleman tipi yeni eleman tipine çevrilebilir olmalıdır.

Referans Tiplerin Çevrimi Referans tiplerde çevrim daha önce ele aldığımız basit tiplerin çevrimine benzer. Atama ve metod çağırma yöntemlerinde izin verilen tüm açık çevrimler (explicit casting) bu yöntemde de kullanı-labilmektedir.

Referans tiplerin çevriminde derleyici zamanında olduğu gibi çalışma zamanında uygulanan ku-rallar da bulunmaktadır. Bunu sebebi, referans tipli değişkenlere ilişkin bazı bilgilerin derleyici zamanında henüz bilinmemesidir.

Referans tiplerin çevrimi için derleyici zamanı kuralları Şekil 4.5’ te belirtilmiştir.

Şekil 4.5:

Eski Tip

Yen

i Tip

Miras verebilir sınıf (non-final class)

Miras veremeyen sınıf (final - sealed class)

Arayüz (interface) Dizi (array)

Miras verebilir sınıf (non-final class)

Eskitip, yenitip’i genişletmelidir

Eskitip, yenitip’i genişletmelidir

Herzaman geçerlidir

Eskitip nesne olmalıdır

Miras veremeyen sınıf (final - sealed class)

Eskitip, yenitip’i genişletmelidir

Eskitip ve Yenitip aynı sınıf olmalıdır.

Yenitip arayüzü implemente etmelidir

Derleyici hatası oluşacaktır

Arayüz (interface)

Herzaman geçerlidir

Eskitip, Yenitip’in arayüzününü implemente etmelidir

Herzaman geçerlidir

Derleyici hatası oluşacaktır

Dizi (array) Yenitip nesne olmalıdır

Derleyici hatası oluşacaktır

Derleyici hatası oluşacaktır

Eskitip, yenitip’in dizisine dönüştürülebilecek bir dizi olmalıdır

41Casting ve Conversion

Page 48: Bilge adam java.pdf

Eskitip ve Yenitip arasındaki dönüşümlerde derleyici zamanında geçerli kurallar aşağıda belirtil-miştir.

Eskitip ve Yenitip dönüşümlerinde her ikisinin de sınıf olması halinde, bir sınıf diğerinin altsı-nıfı olmalıdır.

Eskitip ve Yenitip’lerin her ikisi de dizi ise, her iki dizi de referans tipi barındırmalı ve eskitipin bir elemanının yenitipin bir elemanına çevrimi geçerli olmalıdır.

Bir arayüz ile Miras verebilir sınıf (non-final class) arasında herzaman çevrim yapılabilir.

Çalışma zamanında uygulanan kurallar ise;

Eğer Yenitip bir sınıf ise, dönüştürülen ifadenin sınıfı ya Yenitip olmalıdır, ya da Yenitip’ten miras alınmalıdır.

Eğer Yenitip bir arayüz ise, dönüştürülen ifadenin sınıfı Yenitip’i implemente etmelidir.

olarak belirlenebilir.

42 Bölüm 4

Page 49: Bilge adam java.pdf

5 Yapısal Programlama

Page 50: Bilge adam java.pdf

5 Yapısal ProgramlamaYapısal Programlama Nedir?

Nesne Yönelimli Programlamanın Temel Kavramları

Page 51: Bilge adam java.pdf

Yapısal ProgramlamaYapısal Programlama Nedir?Yapısal programlamada uygulamanın akışı fonksiyonlara bölünerek her bir fonksiyonun belirli bir işi gerçekleştirmesi sağlanır. Yazılımın amacı gerçek dünyadaki iş akışlarının bilgisayar orta-mında yürütülmesi olduğu için, modellenmesi istenen kavramlar fonksiyonlar ve değişkenler kul-lanılarak modellenmeye çalışılmaktadır. Gerçek dünyada fonksiyon ve değişken gibi kavramlar yerine nesnelerin bulunmasından dolayı modelleme tam anlamıyla gerçekleştirilememektedir.

Nesne Yönelimli Programlamanin Temel BileşenleriSınıf ve NesneModellememiz gereken iş akışlarını yazılım ortamında temsil etmek için kullandığımız temel bile-şen sınıflardır. Sınıf sadece bir modeldir, uygulama çalışırken fiziksel olarak oluşturulmayan, kod üzerinde kalan soyut bir yapıdır. Nesne ise uygulamanın çalışması aşamasında fiziksel olarak bilgisayarın belleğinde oluşan ve başka nesnelerle iletişim kurarak iş akışlarının gerçekleşmesini sağlayan bir bileşendir. C# .Net dilinde olduğu gibi Java dilinde de yeni bir nesne oluşturmak için new anahtar kelimesi kullanılır, new anahtar kelimesini kullandığımız her kod parçası uygulama-nın çalışması sırasında bellek üzerinde yeni bir nesne oluşturur.

Nesne yönelimli programlamaya yeni başlayan yazılım geliştiriciler sınıf ve nesne kavramları ara-sındaki farkı anlamakta zorluk çekebilir, bunun sebebi uygulamanın çalışma aşamasında sınıf diye bir varlığın olmaması gibi gerçek hayatta da sınıf diye bir varlığın bulunmamasıdır.

Nitelikler (Attributes)Bir sınıfın içinde bulunan ve o sınıftan oluşturulacak olan nesnelerin özelliklerini tutan yapılar-dır. Sınıfların kodlanması sırasında değişkenler şeklinde oluşturulurlar ve sınıftan nesne örneği oluşturulduğu anda bellek üzerinde oluşurlar. Gerçek hayattaki nesnelerin çeşitli niteliklere sahip olması gibi yazılım ortamında oluşan nesneler de çeşitli niteliklere sahiptir.

Örnek Uygulama 5.1:

Örnekte, nokta kavramının yazılım ortamındaki modeli olan Nokta sınıfı oluşturulmuştur ve bu sınıftan oluşturulacak olan nesnelerin x ve y koordinatlarını temsil etmek için x�ve�y nitelikleri ola-caktır. x�ve�y nitelikleri sınıfın içinde yer alsa da değerlerini Nokta sınıfından bir nesne oluştuktan sonra ve oluşan nesne üzerinden alacaktır.

Davranışlar Yazılım ortamında bellek üzerinde oluşan nesnelerin sergileyeceği davranışlar da nitelikler gibi bu nesnenin modeli olan sınıf üzerinde bulunur. Davranışlar, sınıfların kodlanması sırasında me-todlar şeklinde oluşturulur ve bir sınıfın içinde bulunan metodlar bu sınıftan oluşturulacak olan bü-tün nesnelerin ortak davranışlarını belirler. Gerçek hayattaki nesnelerin çeşitli davranışlara sahip olması gibi yazılım ortamındaki nesnelerin de çeşitli davranışları bulunur. Her bir nesnenin kendi davranışını modelleyen metodlara örnek metodu(instance method) adı verilir.

Örnek Uygulama 5.2:

1publicclassNokta

2{

3 privateintx;

4 privateinty;

5}

1publicclassNokta

2{

Page 52: Bilge adam java.pdf

Örnek Uygulama 5.1’de oluşturduğumuz Nokta sınıfımıza YerDegistir davranışını ekledik. Bu metod sayesinde Nokta sınıfından oluşan bütün nesnelere iki boyutlu uzayda yer değiştirme kabiliyeti vermiş olduk. YerDegistir metodumuz iki tane tam sayı cinsinden parametre alır ve nesnemizin x ve y koordinat değerlerini yeni koordinat değerleriyle değiştirir.

Nesnelere ait metodlar parametre olarak int, string gibi yerleşik tiplerden değişkenler alabile-cekleri gibi kendi sınıfı veya başka bir sınıf cinsinden nesneler de alabilir.

Örnek Uygulama 5.3:

Herhangi bir nokta nesnesinin başka bir nokta nesnesi ile arasında olan uzaklığı bulmak için bir metod yazdık. UzaklikHesapla metodu parametre olarak bir Nokta nesnesi alıyor ve üzerinde çalışmakta olduğu nesneyle parametreden gelen nesne arasındaki uzaklığı double cinsinden hesaplayarak döndürüyor. Kare alma ve karekök hesaplama işlemleri için yerleşik Java sınfla-rından biri olan Math sınıfını kullandık. Metod içinde kullanılan x�ve�y, davranışın sahibi olan nesneye ait x�ve�y değerleridir. Parametre olarak gelen ikinci nesneye ait x�ve�y nitelikleri ise ikinciNokta.x�ve�ikinciNokta.y şeklinde kullanılmıştır.

Bir sınıfın içinde aynı isimli birden fazla metod tanımlanabilir. Bu durumda tek şart tanımlanacak olan metodların parametre sayılarının veya parametre tiplerinin farklı olmasıdır, aynı tipten aynı sayıda parametre içeren aynı isimli birden fazla metod tanımlanırsa derleme hatası alırız. Bu iş-leme metodların aşırı yüklenmesi (overloading) adı verilir. Bu mekanizma C# dilindekine benzer bir mantıkla gerçekleştirilebilir.

3 privateintx;

4 privateinty;

5 publicvoidYerDegistir(intyeniX,intyeniY)

6 {

7 x=yeniX;

8 y=yeniY;

9}

10}

1publicclassNokta

2{

3 privateintx;

4 privateinty;

5 publicvoidYerDegistir(intyeniX,intyeniY)

6 {

7 x=yeniX;

8 y=yeniY;

9}

10 publicdoubleUzaklikHesapla(NoktaikinciNokta)

11 {

12 doubleuzaklik=Math.sqrt(Math.pow(x-ikinciNokta.x,2)+Math.pow(y-ikinciNokta.y,2));

13 returnuzaklik;

14 }

15}

�� Bölüm 5

Page 53: Bilge adam java.pdf

Örnek Uygulama 5.4:

Son durumda, Nokta sınıfımızın içinde aynı işi yapan aynı isimli iki tane metod var. İlk yazdığımız metod parametre olarak bir Nokta nesnesi ile çalışıyor, ikinci metod ise harici bir noktanın x�ve�y�koordinat değerlerinin parametre olarak verilmesini bekliyor.

Sınıfların içinde bulunan metodlar yine aynı sınıfın içinde bulunan başka metodları da kullanabilir. Nokta sınıfında yazdığımız UzaklikHesapla metodları içinde aynı algoritmayı iki kere yazdık. Bunun yerine UzaklikHesapla metodlarından birinin diğer UzaklikHesapla metodunu kul-lanarak hesaplama yapmasını aşağıdaki gibi sağlayabiliriz. Böylece gerçeklememiz gereken bir algoritmayı veya iş mantığını bir kere gerçekleyerek koddan tasarruf ettiğimiz gibi uygulamamızı olası değişimler için daha uygun hale getiririz.

Örnek Uygulama 5.5:

1publicclassNokta

2{

3privateintx;

4privateinty;

5publicvoidYerDegistir(intyeniX,intyeniY)

6{

7 x=yeniX;

8 y=yeniY;

9}

10 publicdoubleUzaklikHesapla(NoktaikinciNokta)

11 {

12 doubleuzaklik=Math.sqrt(Math.pow(x-ikinciNokta.x,2)

+Math.pow(y-ikinciNokta.y,2));

13 returnuzaklik;

14 }

15 publicdoubleUzaklikHesapla(intikinciNoktaX,intikinciNoktaY)

16 {

17 doubleuzaklik=Math.sqrt(Math.pow(x-ikinciNoktaX,2)

+Math.pow(y-ikinciNoktaY,2));

18 returnuzaklik;

19 }

20}

1publicclassNokta

2{

3 privateintx;

4 privateinty;

5 publicvoidYerDegistir(intyeniX,intyeniY)

6 {

7 x=yeniX;

��Yapısal Programlama

Page 54: Bilge adam java.pdf

Yapıcı Metod (Constructor)Uygulama içinde nesnelerin oluşturulması aşamasında otomatik olarak çalışan metodlara kurucu veya yapıcı metodlar denir. Genelde nesnelerimizin içinde bulunan niteliklere ilk değerler atamak için kullanılır. Yapıcı metodlarla ilgili sınırlamalar aşağıdaki gibidir:

Yapıcı metodlar yeni nesne oluşturulmasını sağlamaz, bir nesnenin oluşma aşamasında ça-lışır.

Yapıcı metodların isimleri sınıfın ismiyle aynı olmak zorundadır.

Yapıcı metodların geri dönüş değeri olamaz, geri dönüş değeri olan bir yapıcı metod tanımı yaparsak derleme hatası alırız.

Bir sınıf içinde birden fazla yapıcı metod bulunabilir. Parametre tiplerinin veya sayılarının farklı olması birden fazla yapıcı metod tanımlanabilmesi için yeterlidir.

Java dilinde de .Net ortamında olduğu gibi varsayılan, parametresiz bir yapıcı metod vardır. Sınıfımızın içinde parametreli veya parametresiz bir tane yapıcı metod oluşturduğumuzda varsayılan yapıcı metod geçersiz hale gelir.

New anahtar kelimesi ile sınıftan nesne oluşturulmasına izin vermek istiyorsak yapıcı me-todları public olarak tanımlamamız gerekir. Sınıfın içinde bir tane yapıcı metod varsa ve bu metodun erişim tipi private ise, bu sınıftan nesne oluşturulamaz.

Örnek Uygulama 5.6:

1�

2.

3�

4.

5.

6.

8 y=yeniY;

9 }

10 publicdoubleUzaklikHesapla(NoktaikinciNokta)

11 {

12 returnUzaklikHesapla(ikinciNokta.x,ikinciNokta.y);

13 }

14 publicdoubleUzaklikHesapla(intikinciNoktaX,intikinciNoktaY)

15 {

16 doubleuzaklik=Math.sqrt(Math.pow(x-ikinciNoktaX,2)

+Math.pow(y-ikinciNoktaY,2));

17 returnuzaklik;

18 }

19}

1publicclassNokta

2{

3privateintx;

4privateinty;

5publicNokta()

6{

7 x=0;

8 y=0;

9}

10}

�� Bölüm 5

Page 55: Bilge adam java.pdf

Nokta sınıfımıza parametresiz bir yapıcı metod ekleyerek yeni oluşan her nesnenin x�ve�y koor-dinatlarının sıfır değerine sahip olmasını yapıcı metod aracılığıyla sağladık. Sınıfımıza bir tane de parametreli yapıcı metod ekleyelim.

Örnek Uygulama 5.7:

Son durumda iki tane yapıcı metodumuz oldu. Parametresiz yapıcı metod kullanılarak oluşan bütün nesnelerin x�ve�y koordinatları sıfır değerini alıyor, parametreli yapıcı metodumuz ise nes-nenin oluşması sırasında noktanın farklı koordinat değerlerine sahip olmasını sağlıyor.

Parametreli yapıcı metodumuzun gövdesinde yer alan this anahtar kelimesi, üzerinde çalışmak-ta olduğumuz nesneyi temsil eder. Nesne özelinde değerlendirilebilen nitelik ve metodlara this�anahtar kelimesi ile ulaşabiliriz. Daha önceki örneklerde this anahtar kelimesini kullanmamıza gerek kalmamıştı, çünkü x�ve�y isimli birer tane değişken bulunuyordu. Son yazdığımız metodda ise biri parametreden gelen, diğeri nesnenin sahip olduğu niteliği temsil eden iki tane x değişkeni olduğundan bu değişkenleri biribirinden ayırabilmek için nesneden gelen x değişkeninin başına this anahtar kelimesini ekliyoruz.

Yapıcı metodun parametrelerinden biri olan x değişkeni ile nesne üzerindeki niteliği temsil eden x değişkeni arasında hiçbir organik bağ yoktur, farklı isimlere sahip olsalar da uygulama istendiği şekilde çalışır. Aralarındaki ilişki yapıcı metodumuzun içinde yaptığımız değer ataması ile sınırlı-dır. Parametreli yapıcı metodumuz Şekil 5.8’de belirtilen iki şekilde de yazılabilirdi:

Örnek Uygulama 5.8:

1publicclassNokta

2{

3privateintx;

4privateinty;

5publicNokta()

6{

7 x=0;

8 y=0;

9}

10 publicNokta(intx,inty)

11 {

12 this.x=x;

13 this.y=y;

14 }

15}

1publicNokta(intyeniX,intyeniY)

2{

3this.x=yeniX;

4this.y=yeniY;

5}

6publicNokta(intyeniX,intyeniY)

7{

8x=yeniX;

9 y=yeniY;

10}

��Yapısal Programlama

Page 56: Bilge adam java.pdf

Nokta sınıfının son halini ve bu sınıftan birkaç tane nesne oluşturan ana programı Şekil 5.9’daki gibi yazabiliriz:

Örnek Uygulama 5.9:

1publicclassNokta

2{

3privateintx;

4privateinty;

5publicNokta()

6{

7 x=0;

8 y=0;

9}

10 publicNokta(intx,inty)

11 {

12 this.x=x;

13 this.y=y;

14 }

15 publicvoidYerDegistir(intyeniX,intyeniY)

16 {

17 x=yeniX;

18 y=yeniY;

19 }

20 publicdoubleUzaklikHesapla(NoktaikinciNokta)

21 {

22 returnUzaklikHesapla(ikinciNokta.x,ikinciNokta.y);

23 }

24 publicdoubleUzaklikHesapla(intikinciNoktaX,intikinciNoktaY)

25 {

26 doubleuzaklik=Math.sqrt(Math.pow(x-ikinciNoktaX,2)

+Math.pow(y-ikinciNoktaY,2));

27 returnuzaklik;

28 }

29}

30publicclassAnaProgram

31{

32 publicstaticvoidmain(String[]args)

33 {

// Parametresiz yapıcı metodla bir Nokta nesnesi oluşturuldu

34 Noktanokta1=newNokta();

35 nokta1.YerDegistir(3,5);

50 Bölüm 5

Page 57: Bilge adam java.pdf

Nesne Yönelimli Programlamanın Temel KavramlarıKapsülleme (Encapsulation) Bir nesnenin içinde yer alan niteliklerin ve iş mantığının nesneyi kullanan kişiler tarafından gö-rülmesinin veya değiştirilmesinin engellenmesine kapsülleme denir. Kapsüllemede temel amaç nesneyi kullanacak kişilerin iş akışıyla ilgili gereksiz detaylarla uğraşmamasını sağlamak ve nes-nelerin içinde bulunan hassas verilerin değiştirilmesini engellemektir.

Günlük hayatta düzenli olarak kullandığımız bir mönitör nesnesi üzerinden örnek verelim: Moni-törümüzün içinde birçok elektronik devre elemanı olduğunu bilsek de bu devrelerin nasıl çalıştığı hakkında çoğumuzun bir fikri bulunmamaktadır. Monitörün içinde bulunan elektronik elemanlar ve bunların çalışma mantıkları son kullanıcıdan soyutlanmış durumdadır. Monitörün dışında yer alan kılıfın bulunmadığını ve monitör üzerinde herhangi bir işlem yapmak için çeşitli devre ele-manlarının değerlerini değiştirmek zorunda kaldığımızı düşünecek olursak bahsettiğimiz gereksiz karmaşıklığın ne anlama geldiğini daha iyi anlayabiliriz. Bahsedilen durumda monitör gibi basit bir nesneyi kullanmak için yoğun çaba harcamamız gerekeceği gibi yanlış bir hareketle içerideki yapılara zarar vermemiz de ihtimal dahilinde olacaktır.

Monitörün kullanıcıyla etkileşim kurmak için düğmelerden oluşan bir iletişim arayüzüne sahip olması gibi, yazılımsal olarak gerçeklediğimiz nesnelerimizin de kendilerini kullanacak yazılım-cılarla aralarında bir iletişim arayüzü bulundurmaları kullanımı kolaylaştıracaktır. Sınıflarımızın içinde bulunan niteliklerin ve metodların sadece ihtiyaç duyulduğu kadarının kullanıcıya açılması kapsülleme mantığı çerçevesinde gerçeklenebilir.

Daha önce anlatıldığı gibi nitelikler ve metodların erişimi aşağıdaki gibi kısıtlanabilir:

// Parametreli yapıcı metodla bir Nokta nesnesi oluşturuldu

36 Noktanokta2=newNokta(5,5);

// nokta1 ve nokta2 nesneleri arasındaki uzaklık nokta1 nesnesi

// üzerinden hesaplandı

37 doubleuzaklik=nokta1.UzaklikHesapla(nokta2);

38 System.out.println(uzaklik); // Ekrana 2.0 değeri basıldı

// nokta1 ve nokta2 nesneleri arasındaki uzaklık nokta2 nesnesi

// üzerinden hesaplandı

39 uzaklik=nokta2.UzaklikHesapla(nokta1);

40 System.out.println(uzaklik); // Ekrana 2.0 değeri basıldı

// nokta1 nesnesinin yeni koordinatları (4, 6) değerini aldı

41 nokta1.YerDegistir(4,6);

// nokta1 nesnesinin (5, 7) koordinatlarında bulunan noktaya uzaklığı

// hesaplandı

42 uzaklik=nokta1.UzaklikHesapla(5,7);

43 System.out.println(uzaklik); // Ekrana 1.414 değeri basıldı

44 }

45}

51Yapısal Programlama

Page 58: Bilge adam java.pdf

Şekil 5.1:

Genel olarak sınıf içindeki bütün niteliklerin private veya protected olarak tanımlanması tav-siye edilmektedir. Sınıfı kullanacak olan yazılımcıların sınıf içinde bulunan niteliklere kendilerine sağlanan bağlantı noktaları üzerinden erişmesi get�ve�set metodları yardımıyla sağlanabilir.

Örnek Uygulama 5.10:

Kodun açıklaması: BankaHesabi, hesap numarası ve bakiye verilerini tutan basit bir sınıf-tır. Para çekmek için ParaCek metodunun, para yatirmak içinse ParaYatir metodunun kulla-nılması öngörülmüştür. BankaHesabi sınıfı içindeki hesapNumarasi�ve�bakiye niteliklerinin

Erişim tipi Anlamı

public Sınıfın içinden, dışından ve türetilmiş sınıflardan.protected Sınıfın ve türetilmiş sınıfların içinden.private Sadece sınıfın içinden.

1publicclassBankaHesabi

2{

3publicinthesapNumarasi;

4publicdoublebakiye;

5publicbooleanParaCek(doublemiktar)

6{

7 if(miktar<=this.bakiye)

8 {

9 this.bakiye-=miktar;

10 returntrue;

11 }

12 else

13 {

14 returnfalse;

15 }

16 }

17 publicvoidParaYatir(doublemiktar)

18 {

19 this.bakiye+=miktar;

20 }

21}

22publicclassAnaProgram

23{

24 publicstaticvoidmain(String[]args)

25 {

26 BankaHesabihesap=newBankaHesabi();

27 hesap.hesapNumarasi=12003345;

28 hesap.ParaYatir(1500);

29 hesap.ParaCek(500);

30 hesap.bakiye -= 1500; // iş akışının dışına çıkıldı

31 }

32}

52 Bölüm 5

Page 59: Bilge adam java.pdf

public olmasından dolayı, Main metodunda oluşturulan bir BankaHesabi nesnesinin bakiye değeri ParaCek veya ParaYatir metodları kullanılmadan da değiştirilebilir. Bakiyenin yetersiz olması durumunda bile istenen miktar hesaptan çekilebilmekte, bu nedenle iş akışının doğru ola-rak gerçekleştirilmesi Main metodunu yazan kişiye bağlı olmaktadır.

Sınıfın aşağıdaki şekilde tasarlanması banka hesabıyla ilgili iş akışının tamamen BankaHesabi�sınıfı içinde yer almasını sağlamaktadır:

Örnek Uygulama 5.11:

1publicclassBankaHesabi

2{

3privateinthesapNumarasi;

4privatedoublebakiye;

5publicbooleanParaCek(doublemiktar)

6{

7 if(miktar<=this.bakiye)

8 {

9 this.bakiye-=miktar;

10 returntrue;

11 }

12 else

13 {

14 returnfalse;

15 }

16 }

17 publicvoidParaYatir(doublemiktar)

18 {

19 this.bakiye+=miktar;

20 }

21 publicintgetHesapNumarasi()

22 {

23 returnthis.hesapNumarasi;

24 }

25 publicvoidsetHesapNumarasi(inthesapNo)

26 {

27 this.hesapNumarasi=hesapNo;

28 }

29 publicdoublegetBakiye()

30 {

31 returnthis.bakiye;

32 }

33}

34publicclassAnaProgram

35{

36 publicstaticvoidmain(String[]args)

53Yapısal Programlama

Page 60: Bilge adam java.pdf

Kodun açıklaması: BankaHesabi sınıfındaki hesapNumarasi� ve�bakiye niteliklerinin eri-şim kısıtları private olarak değiştirilmiştir. Böylece bu alanlara dışarıdan erişim engellenmiştir. hesapNumarasi niteliğinin değeri getHesapNumarasi metodu üzerinden, bakiye niteliğinin değeri getBakiye metodu üzerinden okunabilmektedir. hesapNumarasi niteliğine setHesap-Numarasi metodu aracılığıyla yeni bir değer atanabilmesine rağmen bakiye değeri sadece Pa-raCek�ve�ParaYatir metodları kullanılarak değiştirilebilmektedir. Böylece bakiye değişikliği iş-leminin arkasındaki iş mantığı sadece ilgili metodlar yardımıyla belirlenmekte ve sınıfı kullanacak olan yazılımcının bu konu üzerinde çalışmasına gerek kalmamaktadır. Ana programdaki yorum satırı haline getirilmiş olan kod parçası derleme hatası vermektedir. Bu derleme hatasının sebebi bakiye alanının private olarak tanımlanmış olmasıdır.

.Net Platformu üzerinde bulunan Property kavramının Java Platformunda doğrudan bir karşılığı bulunmamaktadır. Bunun yerine niteliğin adının başına get veya set sözcüklerinin eklenmesiyle oluşturulan metodların kullanılması gelenekselleşmiştir.

Kodun Tekrar KullanımıKodun tekrar kullanımı, daha önce yazılmış olan ve belirli bir işlemi gerçekleştiren kod bloklarının aynı projenin farklı bir yerinde veya başka bir projede kullanılmasıdır. Bu işlem yazılımın gerçek-lenmesi aşamasındaki kodlama maliyetlerini düşürdüğü gibi sistemde yapılacak değişikliklerin de daha düşük maliyetle gerçekleştirilmesini sağlar. Yapısal programlama teknolojilerinde kodun yeniden kullanımı kavramı bulunsa da, gerçeklenen işlevler fonksiyon bazında olduğundan iki farklı proje arasında kod aktarımı sınırlı kalır, genelde kodun önemli bir kısmının veya hepsinin yeniden yazılması gerekir. Nesne yönelimli programlama teknolojilerinde ise temel amaçlardan biri kodun yeniden kullanımını sağlayarak projelerin zaman ve iş gücü maliyetlerini mümkün olduğu kadar düşürmektir. Nesne yönelimli yaklaşımda kodun tekrar kullanımı sınıf bazında ger-çeklenir ve daha önce oluşturulmuş olan sınıflar aynı proje içinde veya farklı projelerde esnek olarak kullanılır.

Nesne yönelimli dillerde kodun tekrar kullanımı birkaç farklı şekilde sağlanabilir:

Daha önce oluşturulmuş sınıflardan oluşturulan nesneler uygulama içinde kullanılabilir.

Daha önce oluşturulmuş sınıflardan oluşturulan nesneler yeni oluşturulan sınıfların içinde bu-lunabilir ve bir sınıf değişik tiplerde ve sayılarda nesne içerebilir. Bu ilişkiye composition adı verilir ve genel olarak “sahip olma” (has-a) ilişkisi olarak tanımlanır.

Daha önce oluşturulmuş sınıflardan yeni sınıfların türetilmesi ile ile uygulamanın genişletilmesi sağlanır. Bu kavram kalıtım adını alır ve genel olarak “olma” (is-a) ilişkisi olarak tanımlanır.

KalıtımKalıtım; bir sınıfın daha önce oluşturulmuş başka bir sınıftan türetilmesidir. Kalıtım sayesinde ön-ceden gerçeklenmiş özelliklerin ve davranışların yeniden gerçeklenmesine gerek kalmaz, kodun tekrar kullanımı sağlanmış olur. İki farklı iş kavramının modellenmesi sırasında aralarında kalıtım ilişkisi olduğuna karar vermek için türetilecek olan sınıfın, temel sınıfın sahip olduğu bütün özel-liklere sahip olduğundan emin olmak gerekir. En basit yaklaşımla, iki farklı kavram arasında olma (is-a) ilişkisi kurulabiliyorsa iki sınıf arasında kalıtım ilişkisi vardır. Kalıtım ilişkisi uygulamanın

1�

2.

3�

37 {

38 BankaHesabihesap=newBankaHesabi();

39 hesap.setHesapNumarasi(12003345);

40 hesap.ParaYatir(1500);

41 hesap.ParaCek(500);

42 //hesap.bakiye-=1500;

43}

44}

�� Bölüm 5

Page 61: Bilge adam java.pdf

ihtiyaçlarına göre iki veya daha fazla sınıf arasında olmak üzere tasarlanabilir. .Net Platformunda olduğu gibi Java Platformunda da çoklu kalıtım desteklenmez, bir sınıf sadece bir sınıftan türeti-lebilir.

Örnek: Bir şirketteki çalışanları modellemek için bir yazılım tasarladığımızı varsayalım.

İlk aşamada bütün çalışanlarımızı Calisan adlı bir sınıf ile temsil edelim. Bu durumda bütün çalışan nesnelerimiz aynı sınıftan oluşturulacaği için farklı çalışan tiplerine özel bilgilerin ve dav-ranışların Calisan sınıfından oluşturulan nesnelerde saklanması mümkün olmaz.

Örnek Uygulama 5.12: Çalışan sınıfının ilk hali

Tasarladığımız uygulamayı biraz daha geliştirerek farklı çalışan tiplerini temsil etmek üzere özel-leşmiş çalışan sınıfları oluşturabiliriz. private erişim tipine sahip alanların erişim tipini protec-ted olarak değiştirirsek bu niteliklere türetilmiş sınıflardan ulaşılmasını da sağlarız.

Örnek Uygulama 5.13:

1publicclassCalisan

2{

3privateStringad;

4privateStringsoyad;

5publicCalisan(Stringad,Stringsoyad)

6{

7 this.ad=ad;

8 this.soyad=soyad;

9}

10}

1publicclassCalisan

2{

3protectedStringad;

4protectedStringsoyad;

5

6publicCalisan(Stringad,Stringsoyad)

7{

8 this.ad=ad;

9 this.soyad=soyad;

10 }

11}

12publicclassMuhendisextendsCalisan

13{

14 protectedString[]projeler;

15 protectedStringdepartman;

16 protectedintprojeSayisi;

17 publicMuhendis(Stringad,Stringsoyad,Stringdepartman)

18 {

19 super(ad,soyad);

20 this.departman=departman;

��Yapısal Programlama

Page 62: Bilge adam java.pdf

Calisan sınıfında sadece niteliklerin erişim tipini protected olarak değiştirdik ve yeni ekle-nen Muhendis sınıfının Calisan sınıfından türemesini “extends” anahtar kelimesi ile sağladık. “extends” anahtar kelimesi, C# dilindeki “:” operatörünün karşılığıdır. Muhendis sınıfının içinde bulunan projeler adındaki string dizisi ile belirli bir mühendisin üzerinde çalıştığı projeleri tutu-yoruz ve ProjeEkle metodu yardımıyla belirli bir mühendisin projelerine ekleme yapabiliyoruz.

Muhendis sınıfımızın yapıcı metodu ad, soyad�ve�departman olmak üzere üç tane parametre alır. Departman parametresi Muhendis sınıfı içindeki departman niteliğine ilk değer vermek için kullanılırken ad� ve�soyad parametreleri “super” anahtar kelimesi yardımıyla temel sınıf olan Calisan sınıfının yapıcı metodunu çalıştırmak için kullanılır. Muhendis sınıfında super(ad, soyad) komutuyla Calisan sınıfının yapıcı metodunu çağırmazsak derleme hatası alırız. Bu-nun sebebi türetilmiş sınıflardan nesne oluşturulurken sırasıyla temel ve türetilmiş sınıfların yapıcı metodlarının çağrılmasıdır. Örnek Uygulama 5.14, temel ve türetilmiş sınıflarda yapıcı metodların çalışmasını göstermektedir:

Örnek Uygulama 5.14:

21 this.projeler=newString[5];

22 this.projeSayisi=0;

23 }

24 publicvoidProjeEkle(Stringproje)

25 {

26 projeler[projeSayisi]=proje;

27 projeSayisi++;

28 }

29}

1publicclassTemelSinif

2{

3publicTemelSinif()

4{

5 System.out.println(“Temel sınıfın yapıcı metodu çalıştı”);

6}

7}

8publicclassTuretilmisSinifextendsTemelSinif

9{

10 publicTuretilmisSinif()

11 {

12 System.out.println(“Türetilmiş sınıfın yapıcı metodu çalıştı”);

13 }

14}

15publicclassAnaProgram

16{

17 publicstaticvoidmain(String[]args)

18 {

�� Bölüm 5

Page 63: Bilge adam java.pdf

Program çalıştırıldığında ekranda çıkan mesajlar şu şekildedir:

Temel sınıfın yapıcı metodu çalıştıTüretilmiş sınıfın yapıcı metodu çalıştı

Çalışan modelimizi biraz daha genişleterek mühendisleri branşlarına göre farklı sınıflara ayırırsak ve bir Muhasebeci sınıfı eklersek sınıfların son hali aşağıdaki gibi olur.

Örnek Uygulama 5.15:

19 TuretilmisSinifturetilmisNesne=newTuretilmisSinif();

20 }

21}

1publicclassCalisan

2{

3protectedStringad;

4protectedStringsoyad;

5publicCalisan(Stringad,Stringsoyad)

6{

7 this.ad=ad;

8 this.soyad=soyad;

9}

10}

11publicclassMuhendisextendsCalisan

12{

13 protectedString[]projeler;

14 protectedStringdepartman;

15 protectedintprojeSayisi;

16 publicMuhendis(Stringad,Stringsoyad,Stringdepartman)

17 {

18 super(ad,soyad);

19 this.departman=departman;

20 this.projeler=newString[5];

21 this.projeSayisi=0;

22 }

23 publicvoidProjeEkle(Stringproje)

24 {

25 projeler[projeSayisi]=proje;

26 projeSayisi++;

27 }

28}

29publicclassBilgisayarMuhendisiextendsMuhendis

30{

31 protectedString[]programlamaDilleri;

��Yapısal Programlama

Page 64: Bilge adam java.pdf

32 protectedintprogramlamaDiliSayisi;

33 publicBilgisayarMuhendisi(Stringad,Stringsoyad,Stringdepartman)

34 {

35 super(ad,soyad,departman);

36 this.programlamaDilleri=newString[5];

37 this.programlamaDiliSayisi=0;

38 }

39 publicvoidProgramlamaDiliEkle(StringprogramlamaDili)

40 {

41 programlamaDilleri[programlamaDiliSayisi]=programlamaDili;

42 programlamaDiliSayisi++;

43}

44}

45publicclassMakinaMuhendisiextendsMuhendis

46{

47 privateString[]modellemeProgramlari;

48 privateintmodellemeProgramiSayisi;

49 publicMakinaMuhendisi(Stringad,Stringsoyad,Stringdepartman)

50 {

51 super(ad,soyad,departman);

52 this.modellemeProgramlari=newString[5];

53 this.modellemeProgramiSayisi=0;

54 }

55 publicvoidModellemeProgramiEkle(StringmodellemeProgrami)

56 {

57 modellemeProgramlari[modellemeProgramiSayisi]=modellemeProgrami;

58 modellemeProgramiSayisi++;

59 }

60}

61publicclassMuhasebeciextendsCalisan

62{

63 privateString[]muhasebeProgramlari;

64 privateintmuhasebeProgramiSayisi;

65 publicMuhasebeci(Stringad,Stringsoyad)

66 {

67 super(ad,soyad);

68 this.muhasebeProgramlari=newString[5];

69 this.muhasebeProgramiSayisi=0;

�� Bölüm 5

Page 65: Bilge adam java.pdf

Çok Şekillilik (Polymorphism)Çok şekillilik, bir nesnenin çalışma aşamasında hangi tipten olduğunu bilmesi ve kendi tipine göre davranış sergilemesidir. Oluşturduğumuz iş modeli çerçevesinde bir müdür ve bu müdüre bağlı çalışanlar bulunduğunu ve bütün çalışanların rapor verme kabiliyetine sahip olduğunu var-sayalım. Müdür aynı anda bütün çalışanlardan kendisine haftalık rapor vermelerini istediğinde aşağıdaki iki yöntemle istekte bulunabilir:

Yalçın Bey Bilgisayar Mühendisliği ile ilgili rapor göndersin, Erkut Bey muhasebecilikle ilgili rapor göndersin.

Bütün çalışanlar rapor göndersin.

Rapor isteme-gönderme mekanizmasının işlevsel olması için ikinci senaryonun kullanılması-nın daha mantıklı olduğunu söyleyebiliriz. Şirket müdürü bütün çalışanlarından rapor isterken tek tek yaptıkları işe göre rapor isteyecek olursa bunun gereksiz zaman kaybına yol açacağı rahatlıkla gözlenebiliyor.

Çok şekillilik, ikinci senaryomuzu gerçekleyen yapıdır. Gerçek hayattaki mühendislerin ve mu-hasebecilerin hangi işi yaptıklarını bilmeleri gibi, nesne yönelimli yazılımda da nesneler çalışma aşamasında hangi işi nasıl yaptıklarını bilirler ve ona göre davranırlar. Bu durumda rapor verme davranışı farklı nesne tiplerine göre farklı şekillerde çalışabildiğinden çok şekilli bir davranıştır.

.Net ortamında metodların çok şekilliliği desteklemesi için “virtual” olarak tanımlanması gerekir, Java ortamında ise metodlar varsayılan olarak çok şekilliliği destekler. Çok şekillilik yapısı sadece kalıtım ilişkisi içinde olan sınıflar arasında kullanılabilir.

Örneğimizin çok şekilliliği destekleyen hali Örnek Uygulama 5.16’daki gibi olacaktır:

Örnek Uygulama 5.16:

1�

2.

3�

70 }

71 publicvoidMuhasebeProgramiEkle(StringmuhasebeProgrami)

72 {

73 muhasebeProgramlari[muhasebeProgramiSayisi]=muhasebeProgrami;

74 muhasebeProgramiSayisi++;

75 }

76 publicvoidMuhasebeProgramiEkle(StringmuhasebeProgrami)

77 {

78 if(!muhasebeProgramlari.contains(muhasebeProgrami))

79 muhasebeProgramlari.add(muhasebeProgrami);

80 }

81}

1publicclassCalisan

2{

3protectedStringad;

4protectedStringsoyad;

5publicCalisan(Stringad,Stringsoyad)

6{

7 this.ad=ad;

8 this.soyad=soyad;

9}

��Yapısal Programlama

Page 66: Bilge adam java.pdf

10 publicvoidRaporVer()

11 {

12 System.out.println(“Ad:“+ad+“Soyad:“+soyad);

13 }

14}

15publicclassMuhendisextendsCalisan

16{

17 protectedString[]projeler;

18 protectedStringdepartman;

19 protectedintprojeSayisi;

20 publicMuhendis(Stringad,Stringsoyad,Stringdepartman)

21 {

22 super(ad,soyad);

23 this.departman=departman;

24 this.projeler=newString[5];

25 this.projeSayisi=0;

26 }

27 publicvoidProjeEkle(Stringproje)

28 {

29 projeler[projeSayisi]=proje;

30 projeSayisi++;

31 }

32 publicvoidRaporVer()

33 {

34 super.RaporVer();

35 System.out.println(“Departman:“+departman);

36 System.out.println(“Projeler:“);

37 for(inti=0;i<projeSayisi;i++)

38 {

39 System.out.println(“\t”+projeler[i]);

40 }

41 }

42}

43publicclassBilgisayarMuhendisiextendsMuhendis

44{

45 protectedString[]programlamaDilleri;

46 protectedintprogramlamaDiliSayisi;

47 publicBilgisayarMuhendisi(Stringad,Stringsoyad,Stringdepartman)

48 {

49 super(ad,soyad,departman);

50 this.programlamaDilleri=newString[5];

60 Bölüm 5

Page 67: Bilge adam java.pdf

51 this.programlamaDiliSayisi=0;

52 }

53 publicvoidProgramlamaDiliEkle(StringprogramlamaDili)

54 {

55 programlamaDilleri[programlamaDiliSayisi]=programlamaDili;

56 programlamaDiliSayisi++;

57 }

58 publicvoidRaporVer()

59 {

60 super.RaporVer();

61 System.out.println(“Görev:BilgisayarMühendisi”);

62 System.out.println(“ProgramlamaDilleri:“);

63 for(inti=0;i<this.programlamaDiliSayisi;i++)

64 {

65 System.out.println(“\t”+programlamaDilleri[i]+““);

66 }

67 }

68}

69publicclassMakinaMuhendisiextendsMuhendis

70{

71 privateString[]modellemeProgramlari;

72 privateintmodellemeProgramiSayisi;

73 publicMakinaMuhendisi(Stringad,Stringsoyad,Stringdepartman)

74 {

75 super(ad,soyad,departman);

76 this.modellemeProgramlari=newString[5];

77 this.modellemeProgramiSayisi=0;

78 }

79 publicvoidModellemeProgramiEkle(StringmodellemeProgrami)

80 {

81 modellemeProgramlari[modellemeProgramiSayisi]=modellemeProgrami;

82 modellemeProgramiSayisi++;

83 }

84 publicvoidRaporVer()

85 {

86 super.RaporVer();

87 System.out.println(“Görev:MakinaMühendisi”);

88 System.out.println(“Modelleme Programları: “);

89 for(inti=0;i<modellemeProgramiSayisi;i++)

61Yapısal Programlama

Page 68: Bilge adam java.pdf

90 {

91 System.out.println(“\t”+modellemeProgramlari[i]+““);

92 }

93 }

94}

95publicclassMuhasebeciextendsCalisan

96{

97 privateString[]muhasebeProgramlari;

98 privateintmuhasebeProgramiSayisi;

99 publicMuhasebeci(Stringad,Stringsoyad)

100 {

101 super(ad,soyad);

102 this.muhasebeProgramlari=newString[5];

103 this.muhasebeProgramiSayisi=0;

104 }

105 publicvoidMuhasebeProgramiEkle(StringmuhasebeProgrami)

{

106 muhasebeProgramlari[muhasebeProgramiSayisi]=muhasebeProgrami;

107 muhasebeProgramiSayisi++;

108 }

109 publicvoidRaporVer()

110 {

111 super.RaporVer();

112 System.out.println(“Görev:Muhasebeci”);

113 System.out.println(“Muhasebe Programları: “);

114 for(inti=0;i<muhasebeProgramiSayisi;i++)

115 {

116 System.out.println(“\t”+muhasebeProgramlari[i]);

117 }

118 }

119}

120publicclassMudur

121{

122 privateCalisan[]calisanlar;

123 privateintcalisanSayisi;

124 publicMudur()

125 {

126 this.calisanlar=newCalisan[5];

127 this.calisanSayisi=0;

128 }

62 Bölüm 5

Page 69: Bilge adam java.pdf

Program çalıştırıldığında aşağıdaki gibi bir çıktı üretir:

Ad: Yalçın Soyad: Kaya

Departman:IT

Projeler:

Görev:BilgisayarMühendisi

ProgramlamaDilleri:

Java

C#

129 publicvoidCalisanEkle(Calisancalisan)

130 {

131 calisanlar[calisanSayisi]=calisan;

132 calisanSayisi++;

133 }

134 publicvoidRaporIste()

135 {

136 for(inti=0;i<calisanSayisi;i++)

137 {

138 calisanlar[i].RaporVer();

139 System.out.println();

140 }

141 }

142}

143publicclassAnaProgram

144{

145 publicstaticvoidmain(String[]args)

146 {

147 BilgisayarMuhendisiblgMuh=newBilgisayarMuhendisi(“Yalçın”, “Kaya”, “IT”);

148 blgMuh.ProgramlamaDiliEkle(“Java”);

149 blgMuh.ProgramlamaDiliEkle(“C#”);

150 MakinaMuhendisimknMuh=newMakinaMuhendisi(“Hasan”, “Polat”, “Bakım”);

151 mknMuh.ModellemeProgramiEkle(“Katia”);

152 Muhasebecimuhasebeci=newMuhasebeci(“Erkut”,“Kutlar”);

153 MudurgenelMudur=newMudur();

154 genelMudur.CalisanEkle(blgMuh);

155 genelMudur.CalisanEkle(mknMuh);

156 genelMudur.CalisanEkle(muhasebeci);

157 genelMudur.RaporIste();

158 }

159}

63Yapısal Programlama

Page 70: Bilge adam java.pdf

Ad:HasanSoyad:Polat

Departman: Bakım

Projeler:

Görev:MakinaMühendisi

Modelleme Programları:

Katia

Ad:ErkutSoyad:Kutlar

Görev:Muhasebeci

Muhasebe Programları:

Mudur sınıfının içinde, çalışanları tutmak için Calisan sınıfı cinsinden bir dizi kullandık. Ana programda oluşturduğumuz üç tane farklı tipte çalışanı (bilgisayar mühendisi, makina mühendi-si, muhasebeci) müdür nesnemizin çalışanlarına ekledik. Mudur sınıfının RaporIste metodu butun çalışanlardan rapor istemek amacıyla yazıldı. Müdür nesnesinin RaporIste metodunu çalıştırdığımızda bütün çalışan nesnelerinin kendi tiplerine ait raporları oluşturduğunu görüyoruz. Raporların doğru bir şekilde oluşması RaporVer metodunun çok şekilli olduğunu gösterir. Müdür sınıfında bütün çalışan bilgilerinin Calisan sınıfından oluşan bir dizide tutulmasından dolayı derleme aşamasında çalışanların tipi belli değildir. Eğer RaporVer metodu çok şekilli olmasaydı, müdür nesnesinin RaporIste metodu çağrıldığında çalışanların hepsi derleme aşamasında ol-duğu gibi çalışma aşamasında da temel Calisan sınıfının raporunu oluşturacaktı.

�� Bölüm 5

Page 71: Bilge adam java.pdf

6 Swing

Page 72: Bilge adam java.pdf

6 SwingSwing’e Giriş

Klavye Event’lerinin Yönetilmesi

Page 73: Bilge adam java.pdf

SwingJava platformunun 1.0 versiyonunda görsel kullanıcı arayüzleri oluşturmak için AWT (Abstract Windowing Toolkit) teknolojisi kullanılıyordu. AWT’nin temel amacı Java programlarının arayüz-lerini işletim sisteminden bağımsız hale getirmek olsa da bu amaca ulaşılamadı. AWT paketinin içinde bulunan bileşenler işletim sistemine bağımlı olduğundan farklı işletim sistemleri üzerinde faklı görünümlere sahip olan programlar ortaya çıktı. Java platformunun 2.0 versiyonuyla birlikte AWT paketinin üzerine Swing adı verilen yeni görsel programlama modeli de eklendi. Swing pa-keti Java ile yazılmış olmasının da etkisiyle İşletim sisteminden bağımsız bir görsel programlama modeli sunar. Yeni geliştirilen Java uygulamalarında Swing paketinin kullanılması uygulamanın görsel arayüzünün güçlü olması için şarttır.

Bu bölümde Java platformunda bulunan Swing paketinin genel özellikleri ve bu paketin içinde bulunan temel arayüz kontrolleri anlatılacaktır. Swing bu bölümde anlatılanlarla sınırlı değildir, özellikle karmaşık kullanıcı etkileşimi gerektiren Java uygulamalarının geliştirebilmesi için Swing teknolojisinin detaylı olarak incelenmesi gerekir.

Swing’e Giriş.Net platformunda Windows uygulamaları geliştirirken kullandığımız kontrollerin benzerleri Java platformunda da vardır. Swing kontrolleri çeşitli olayları (event) tetikleyerek uygulama arayüzüy-le kullanıcının etkileşim halinde olmasına olanak tanır. Uygulamada kullanılan kontroller çeşitli container’lar (saklayıcı) yardimiyla gruplanabilir. Java platformuyla işletim sistemi üzerinde ça-lışan uygulamalar oluşturmak için uygulamanın görsel arayüzünü temsil edecek sınıfın JFrame�sınıfından türetilmesi gerekir. JFrame sınıfının içinde bulunan ve yeni oluşturulan sınıflara ka-lıtımla aktarılan getContentPane metodu kullanılarak uygulamada bulunan kontrolleri içeren Container nesnesine erişilir. Menü kontrolleri dışındaki bütün kontroller Container nesnesi içinde bulunur ve Container nesnesi hiçbir zaman null (boş) değer almaz.

Container nesnesinin setLayout metodu uygulama arayüzünde kullanılacak yerleşim düzenini(layout) belirlemek için kullanılır. Layout seçenekleri ilerleyen sayfalarda anlatılacaktır. Boş bir arayüz oluşturan Java kodu Örnek Uygulama 6.1’de verilmiştir:

Örnek Uygulama 6.1:

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjavax.swing.JFrame;

4publicclassIlkOrnekextendsJFrame

5{

6publicIlkOrnek()

7{

8 super(“İlk Örnek”);

9 Containercontainer=getContentPane();

10 container.setLayout(newFlowLayout());

11 setSize(200,200);

12 setVisible(true);

13}

14publicstaticvoidmain(String[]args)

15{

16 IlkOrnektest=newIlkOrnek();

17 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Page 74: Bilge adam java.pdf

Kodun açıklaması:�IlkOrnek isimli sınıfımız JFrame sınıfından türetilmiştir. Yapıcı metod için-de� �JFrame sınıfının yapıcı metodu super(“İlk Örnek”) kod bloğuyla çalıştırılır, oluşan ekranın başlığında “İlk Örnek” metni bulunur. Container nesnesi getContentPane metodu ile yukarı-da açıklandığı gibi alınır. Forma başka kontroller de ekleyecek olursak bu kontrolleri Container�nesnesinin içine veya Container nesnesinin içinde bulunan bir nesneye eklememiz gerekir. Uy-gulamanın çalışması sırasında formun görünür hale gelmesi için boyutunu vermemiz ve setVi-

sible metodunu kullanarak formu görünür hale getirmemiz gereklidir. Main metodunun içinde, yazdığımız sınıftan bir nesne oluşturarak formun oluşmasını sağlarız. JFrame sı-nıfından türetilmiş olan arayüzün kullanıcı tarafından kapa-tılması durumunda uygulamanın sonlandırılmasının sağlan-ması için test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); kod bloğunu Main metoduna ekleriz. Bu satırı eklemezsek, uygulama kapatıldığında varsayılan işlem olarak form görünmez hale gelindiği halde uygulama kapanmaz. Swing ile ilgili bütün örneklerde yukarıda verilen kodu kullanacağız.

Uygulama çalıştırıldığında oluşan arayüz Şekil 1’deki gibi-dir.

JButton.Net platformundaki Button kontrolünün karşılığı Java platformundaki JButton kontrolüdür. Te-mel olarak üzerinde bir metin yazılı olabilen ve kullanıcı tarafından üzerine tıklandığında event oluşturan bir yapıya sahiptir. Form üzerinde bir buton oluşturmak için JButton sınıfından bir nesne yaratılır ve Container nesnesine eklenir. JButton sınıfının yapıcı metodu butonun üze-rinde görüntülenecek metni parametre olarak alır. JButton nesnesi oluşturan ve formun üzerine ekleyen kod Örnek Uygulama 6.2’de gösterilmiştir.

Örnek Uygulama 6.2:

18}

19}

Şekil 1

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjavax.swing.JButton;

4importjavax.swing.JFrame;

5publicclassJButtonTestextendsJFrame

6{

7privateJButtonbtnTest;

8publicJButtonTest()

9{

10 super(“JButton Örneği”);

11 Containercontainer=getContentPane();

12 container.setLayout(newFlowLayout());

13 btnTest = new JButton(“Örnek Buton”);

14 container.add(btnTest);

15 setSize(200,200);

16 setVisible(true);

17 }

�� Bölüm 6

Page 75: Bilge adam java.pdf

Kodun açıklaması: Formu oluşturan kod bloklarından farklı olarak bir adet JButton nesnesi oluşturan ve Container nesnesine ekleyen kod satırları yukarıdadır. JButton sınıfının yapıcı metoduna parametre olarak butonun üzerinde bulunmasını istediğimiz metni veririz. Container nesnesinin add me-todu herhangi bir kontrolün Container içine eklenmesini sağlar. Uygulama çalıştırıldığında Şekil 2’deki gibi bir arayüz oluşur.

Oluşturduğumuz butona henüz bir event eklemediğimiz için butonun herhangi bir işlevi yoktur.

JLabelJLabel kontrolü, .Net ortamındaki Label kontrolünün kar-şılığıdır. Uygulama üzerinde metin görüntülemek istediğimiz noktalarda kullanılır. Bir JLabel kontrolünün uygulama üze-rinde görünür hale gelmesi için bir JLabel nesnesi oluştu-rup Container nesnesine eklememiz yeterlidir. Örnek kod Örnek Uygulama 6.3’de verilmiştir.

Örnek Uygulama 6.3:

18 publicstaticvoidmain(String[]args)

19 {

20 JButtonTesttest=newJButtonTest();

21 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

22 }

23}

Şekil 2

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjavax.swing.JFrame;

4importjavax.swing.JLabel;

5publicclassJLabelTestextendsJFrame

6{

7privateJLabellblTest;

8publicJLabelTest()

9{10 super(“JLabel Kullanımı”);11 Containercontainer=getContentPane();12 container.setLayout(newFlowLayout());

13 lblTest = new JLabel(“JLabel Örneği”);

14 container.add(lblTest);

15 setSize(200,200);

16 setVisible(true);

17 }

18 publicstaticvoidmain(String[]args)

19 {20 JLabelTesttest=newJLabelTest();21 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);22 }23}

��Swing

Page 76: Bilge adam java.pdf

Kodun açıklaması: lblTest adındaki JLabel nesnesin yapıcı metoduna parametre olarak üzerinde görüntülenecek metin verilmiştir. Container nesnesinin add metodu kullanılarak JLa-bel nesnesinin form üzerinde görüntülenmesi sağlanmıştır. Label üzerindeki metni uygulama-

nın çalışma aşamasında değiştirmek için setText metodu, label üzerindeki metni almak için getText metodu kul-lanılır. Bu iki metodun kullanımıyla ilgili örneği daha sonra vereceğiz. Uygulama çalıştırıldığı zaman Şekil 3’de olduğu gibi görünür.

JTextFieldJTextField kontrolü, .Net ortamındaki TextBox kontrolü-lün Java ortamındaki karşılığıdır. Kullanıcı tarafından girile-cek metin türünden bilgileri uygulamaya aktarmak amacıyla kullanılır. Bir JTextField kontrolünün uygulama üzerinde görünür hale gelmesi için bir JTextField nesnesi oluştu-rup Container nesnesine eklememiz yeterlidir. Örnek kod, Örnek Uygulama 6.4’te verilmiştir.

Örnek Uygulama 6.4:

Kodun açıklaması: txtTest adındaki JTextField nesnesin yapıcı metoduna parametre ola-rak üzerinde görüntülenecek metin verilmiştir. Container nesnesinin add metodu kullanılarak JTextField nesnesinin form üzerinde görüntülenmesi sağlanmıştır. JTextField üzerindeki metni uygulamanın çalışma aşamasında değiştirmek için setText metodu, label üzerindeki

Şekil 3

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjavax.swing.JFrame;

4importjavax.swing.JLabel;

5importjavax.swing.JTextField;

6publicclassJTextFieldTestextendsJFrame

7{

8privateJTextFieldtxtTest;

9publicJTextFieldTest()

10 {

11 super(“JTextField Kullanımı”);

12 Containercontainer=getContentPane();

13 container.setLayout(newFlowLayout());

14 txtTest = new JTextField(“JTextField Örneği”);

15 container.add(txtTest);

16 setSize(200,200);

17 setVisible(true);

18 }

19 publicstaticvoidmain(String[]args)

20 {

21 JTextFieldTesttest=newJTextFieldTest();

22 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

23 }

24}

70 Bölüm 6

Page 77: Bilge adam java.pdf

metni almak için getText metodu kullanılır. Bu iki metodun kullanımıyla ilgili örneği daha sonra vereceğiz. Uygulama çalıştırıldığı zaman Şekil 4’teki gibi görünür.

Event Handling MekanizmasıKullanıcıların Swing kontrolleri aracılığıyla uygulamayla iletişim kurması sonucunda çeşitli event’ler (olaylar) oluşur. Bu event’leri kontrol etmek (handle) için .Net ortamından farklı olarak event sınıfları kullanmamız gerekir. Java ortamında herşeyi sınıflar halinde kullanmak gibi bir amaç olduğundan event handling mekanizması .Net ortamındakinden farklıdır. Net uygulama-larında herhangi bir event için bir tane metod yazmak yeterli olurken Java’da bu işlem için harici veya dahili (inner class) bir sınıf yazarak çeşitli event tipleri için özelleşmiş event interface’lerini implemente etmemiz gerekir. Herhangi bir event birden fazla Swing kontrolü tarafından kulla-nılabilir, boyle bir kullanımda event’in hangi kontrol üzerinden oluştuğunu öğrenmek için event parametreleri kullanılır. JLabel, JTextField�ve�JButton kontrolleriyle birlikte event mekaniz-masini örnek kodu, Örnek Uygulama 6.5 üzerinden inceleyelim:

Örnek Uygulama 6.5:

Şekil 4

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.ActionEvent;

4importjava.awt.event.ActionListener;

5importjavax.swing.JButton;

6importjavax.swing.JFrame;

7importjavax.swing.JLabel;

8importjavax.swing.JTextField;

9publicclassEventMekanizmasiextendsJFrame

10{

11 privateJLabellblGoruntule;

12 privateJTextFieldtxtGiris;

13 privateJButtonbtnGoruntule;

14 publicEventMekanizmasi()

15 {

16 super(“Event Mekanizması”);

17 Containercontainer=getContentPane();

18 container.setLayout(newFlowLayout());

19 txtGiris=newJTextField(“JTextField”);

71Swing

Page 78: Bilge adam java.pdf

Kodun açıklaması: EventMekanizmasi sınıfının yapıcı metodunda daha önce yaptığımız gibi JLabel, JTextField�ve�JButton nesnelerini oluşturduk ve Container nesnesine ekledik.

EventMekanizmasi sınıfının içindeki private erişim tipine sahip ButtonHandler sınıfının ActionListener interface’ini implemente etmesi, bu sınıfın içinde actionPerformed me-todunun yazılmasını zorunlu kılar. Bu metod, Action cinsinden bir event oluştuğunda çalışır. JButton nesnesi üzerinde çalıştırdığımız addActionListener metodunu buton ile event’i ilişkilendirmek için kullandık, bu durumda buton kullanıcı tarafından tıklandığında ButtonHand-ler sınıfındaki actionPerformed metodu çalışacaktır. actionPerformed metodunun içinde txtGiris nesnesinin getText metodunu kullanarak kullanıcı tarafından girilen metni alıp lbl-Goruntule nesnesinin setText metodu ile JLabel kontrolünün metnine atıyoruz.

Aynı işlevi, event handler sınıfını dahili olarak tanımlayarak da gerçekleyebiliriz. Event handler sınıfının dahili olarak gerçeklenmesini gösteren kod bloğu Örnek Uygulama 6.6’daki gibidir.

Örnek Uygulama 6.6:

20 container.add(txtGiris);

21 btnGoruntule=newJButton(“Görüntüle”);

22 container.add(btnGoruntule);

23 btnGoruntule.addActionListener(newButtonHandler());

24 lblGoruntule=newJLabel(“JLabel”);

25 container.add(lblGoruntule);

26 setSize(400,200);

27 setVisible(true);

28 }

29 privateclassButtonHandlerimplementsActionListener

30 {

31 publicvoidactionPerformed(ActionEvente)

32 {

33 lblGoruntule.setText(txtGiris.getText());

34 }

35 }

36 publicstaticvoidmain(String[]args)

37 {

38 EventMekanizmasitest=newEventMekanizmasi();

39 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

40 }

41}

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.ActionEvent;

4importjava.awt.event.ActionListener;

5importjavax.swing.JButton;

6importjavax.swing.JFrame;

7importjavax.swing.JLabel;

8importjavax.swing.JTextField;

9publicclassEventMekanizmasiextendsJFrame

72 Bölüm 6

Page 79: Bilge adam java.pdf

Her iki kod bloğu da aynı şekilde çalışır. Kullanıcının metin kutusuna yazdığı metin butona tıklan-dıktan sonra label üzerinde görüntülenir. Uygulama çalıştırıldığında butona tıklamadan önce ve sonraki görünümler Şekil 5 ve Şekil 6’daki gibidir.

10{

11 privateJLabellblGoruntule;

12 privateJTextFieldtxtGiris;

13 privateJButtonbtnGoruntule;

14 publicEventMekanizmasi()

15 {

16 super(“Event Mekanizması”);

17 Containercontainer=getContentPane();

18 container.setLayout(newFlowLayout());

19 txtGiris=newJTextField(“JTextField”);

20 container.add(txtGiris);

21 btnGoruntule=newJButton(“Görüntüle”);

22 container.add(btnGoruntule);

23 btnGoruntule.addActionListener

24 (

25 newActionListener()

26 {

27 publicvoidactionPerformed(ActionEventevent)

28 {

29 lblGoruntule.setText(txtGiris.getText());

30 }

31 }

32 );

33 lblGoruntule=newJLabel(“JLabel”);

34 container.add(lblGoruntule);

35 setSize(400,200);

36 setVisible(true);

37}

38publicstaticvoidmain(String[]args)

39{

40 EventMekanizmasitest=newEventMekanizmasi();

41 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

42}

43}

73Swing

Page 80: Bilge adam java.pdf

JTextAreaJTextArea kontrolü, .Net ortamındaki RichTextBox kontrolünün karşılığıdır. JTextField�kontrolünden daha geniş kullanım kabiliyetlerine sahiptir ve birden fazla satırdan oluşan metinle-rin girilmesine olanak verir. Append metodu yardımıyla üzerine metin eklemesi yapılabilir. Girilen metnin kontrolün boyutlarından büyük olması durumunda bir alt satıra geçmek için setLineWrap�metodu kullanılır. JTextArea kontrolünün örnek kullanımı Örnek Uygulama 6.7’de verilmiştir.

Örnek Uygulama 6.7:

Şekil 5 Şekil 6

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjavax.swing.JFrame;

4importjavax.swing.JTextArea;

5publicclassJTextAreaTestextendsJFrame

6{

7privateJTextAreatxtArea;

8publicJTextAreaTest()

9{

10 super(“JTextArea Kullanımı”);

11 Containercontainer=getContentPane();

12 container.setLayout(newFlowLayout());

13 txtArea = new JTextArea(“JTextArea alanına birden fazla satirdan oluşan metin girilebilir.”);

14 txtArea.append(“\nYenimetineklenebilir”);

15 txtArea.setLineWrap(true);

16 txtArea.setSize(150,150);

17 container.add(txtArea);

18 setSize(200,200);

19 setVisible(true);

20 }

21 publicstaticvoidmain(String[]args)

22 {

23 JTextAreaTesttest=newJTextAreaTest();

24 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

25 }

26}

�� Bölüm 6

Page 81: Bilge adam java.pdf

Kodun açıklaması: JTextArea nesnesini oluşturulup Container nesnesine ekledikten sonra append metodu ile üzerine yeni metin ekledik. Append metodunun içinde kullandığımız “\n” ka-rakteri metnin bir alt satıra geçmesini sağlar. setLineWrap(true) komutuyla metnin kontrolün genişliğinden fazla yer kaplaması durumunda otomatik olarak bir alt satıra geçmesi sağlanmıştır. setSize metodu ile kontrolün x ve y boyutu 150 olarak atanmıştır. Uygulama çalıştırıldığında Şekil 7’deki gibi bir arayüz oluşur.

JOptionPaneJOptionPane sınıfı, .Net ortamında bulunan MessageBox�sınıfının Java karşılığıdır. MessageBox.Show() metoduna benzer bir şekilde çalışan birçok statik metod içerir. Arayü-zün çalışma mantığı içinde çeşitli mesajları kullanıcıya gös-termek ve onay almak amacıyla kullanılır. Gösterilen onay kutusu uygulamayı oluşturan formun dışında ayrı bir pence-re içinde oluşur. Bir JOptionPane onay kutusunu kullanı-cının karşısına çıkartan ve kullanıcının onay durumuna göre bir tane JOptionPane mesaj diyaloğu gösteren kod Örnek Uygulama 6.8’de verilmiştir.

Örnek Uygulama 6.8:

Şekil 7

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.ActionEvent;

4importjava.awt.event.ActionListener;

5importjavax.swing.JButton;

6importjavax.swing.JFrame;

7importjavax.swing.JOptionPane;

8publicclassJOptionPaneTestextendsJFrame

9{10 privateJButtonbtnOnay;11 publicJOptionPaneTest()

12 {13 Super(“JOptionPane”);

14 Containercontainer=getContentPane();

15 container.setLayout(newFlowLayout());

16 btnOnay=newJButton(“Onayal”);

17 btnOnay.addActionListener(newButtonHandler());

18 container.add(btnOnay);

19 setSize(200,200);

20 setVisible(true);

21 }

22 privateclassButtonHandlerimplementsActionListener

23 {24 publicvoidactionPerformed(ActionEventevent)

25 {

26 intsecim=JOptionPane.showConfirmDialog(null, “Seçiminizi onaylıyor musunuz?”, “Onay

ekranı”, JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);

��Swing

Page 82: Bilge adam java.pdf

Kodun açıklaması: Formun üzerine bir tane buton ekledik ve bu buton için ActionListener��interface’ini implemente eden ButtonHandler adında bir event sınıfı yazdık. Kullanıcı tara-fından butona tıklanması durumunda actionPerformed metodu çalışır ve kullanıcıya JOp-tionPane.showConfirmDialog metodu yardımıyla onay verip vermediği sorulur. Bu statik metodun ikinci parametresi onay kutusunda görüntülenmesini istediğimiz metin, üçüncü para-metresi ise onay kutusunun başlığını oluşturan metindir. Dördüncü parametrede onay kutusunda hangi butonların görüntülenmesini istediğimizi belirttik. Yaptığımız örnekte Yes, No ve Cancel butonlarının görüntülenmesini istedik. Kullanıcının herhangi birşeyi onaylamasını istediğimiz için soru işareti şeklinde bir resim kullanmak duruma uygun olduğundan beşinci parametrede soru mesajı seçeneğini seçtik. Java’daki birçok metod parametresinde olduğu gibi JOptionPane.showConfirmDialog metodunun parametrelerinde de sınıfın üzerinde bulunan değerleri kulla-nabildiğimiz gibi istersek bu değerlerin tam sayı karşılıklarını da kullanabiliriz. Metodun geri dönüş değerinin tam sayı(int) olduğuna dikkat edelim. Bu geri dönüş değerini secim isimli bir tam sayı değişkenine atarak bir sonraki aşamada seçime göre bir işlem yapılmasını sağlayabiliriz.

Sonraki aşamada, onay durumuna göre değişen bir simgeye, başlık metnine ve mesaj kutusu metnine sahip bir mesaj kutusunu kullanıcıya gösteriyoruz.

Uygulama çalıştırıldığında görünen arayüz, butona tıklandığı zaman görüntülenen onay kutusu ve çeşitli seçimlere göre görüntülenen mesaj kutuları Şekil 8, Şekil 9, Şekil 10, Şekil 11 ve Şekil 12’de gösterildiği gibidir.

���������������

� � ����������

27 if(secim==JOptionPane.YES_OPTION)

28 JOptionPane.showMessageDialog(null,“Onaylandı”, “Onay”, JOptionPane.INFORMATION_MESSAGE);

29 elseif(secim==JOptionPane.NO_OPTION)

30 JOptionPane.showMessageDialog(null,“Onaylanmadı”, “Red”, JOptionPane.ERROR_MESSAGE);

31 else

32 JOptionPane.showMessageDialog(null,“Onaylanmadı”, “İptal”, JOptionPane.WARNING_MESSAGE);

33 }

34 }

35 publicstaticvoidmain(String[]args)

36 {

37 JOptionPaneTesttest=newJOptionPaneTest();

38 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

39 }

40}

Şekil 8: Programın ilk çalışması. Şekil 9: Onay ekranı.

�� Bölüm 6

Page 83: Bilge adam java.pdf

JCheckBoxJCheckBox sınıfı, .Net platformunda bulunan CheckBox sınıfının Java ortamındaki karşılığıdır. Seçili durumda olabilen küçük bir kutudan ve yanında bulunan bir Label’dan oluşan JCheck-Box, kullanıcının temel açık/kapalı seçimi yapmasını sağlayan basit bir arayüz kontrolüdür. Be-lirli bir zamanda nesnenin seçili olup olmadığı kontrol edilebilir, seçim değiştiğinde bir event’in tetiklenmesi sağlanabilir, seçili olma durumu değiştirilebilir. JCheckBox kontrolünün kullanımını gösteren kod bloğu Örnek Uygulama 6.9’da verilmiştir.

Örnek Uygulama 6.9:

Şekil 10: Yes butonuna tıklandı. Şekil 11: No butonuna tıklandı.

Şekil 12: İptal butonuna tıklandı.

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.GridLayout;

4importjava.awt.event.ActionEvent;

5importjava.awt.event.ActionListener;

6importjava.awt.event.ItemEvent;

7importjava.awt.event.ItemListener;

8importjavax.swing.JButton;

9importjavax.swing.JCheckBox;

10importjavax.swing.JFrame;

11importjavax.swing.JLabel;

12importjavax.swing.JOptionPane;

13importjavax.swing.JTextField;

14publicclassJCheckBoxTestextendsJFrame

15{

16 privateJCheckBoxchkKabul;

17 privateJLabellblAd;

18 privateJLabellblSoyad;

19 privateJTextFieldtxtAd;

20 privateJTextFieldtxtSoyad;

21 privateJButtonbtnKaydet;

22 publicJCheckBoxTest()

23 {

24 super(“Kullanıcı kayıt formu”);

25 Containercontainer=getContentPane();

��Swing

Page 84: Bilge adam java.pdf

26 container.setLayout(newFlowLayout());

27 lblAd=newJLabel(“Ad:“);

28 container.add(lblAd);

29 txtAd=newJTextField(10);

30 container.add(txtAd);

31 lblSoyad=newJLabel(“Soyad:“);

32 container.add(lblSoyad);

33 txtSoyad=newJTextField(10);

34 container.add(txtSoyad);

35 btnKaydet=newJButton(“Kaydet”);

36 btnKaydet.setEnabled(false);

37 btnKaydet.addActionListener

38 (

39 newActionListener()

40 {

41 publicvoidactionPerformed(ActionEventevent)

42 {

43 JOptionPane.showMessageDialog(null,“Ad:“+txtAd.getText()+“\nSoyad:“+txtSoyad.getText());

44 }

45 }

46 );

47 container.add(btnKaydet);

48 chkKabul = new JCheckBox(“Sözleşmeyi kabul ediyorum”);

49 chkKabul.addItemListener

50 (

51 newItemListener()

52 {

53 publicvoiditemStateChanged(ItemEventevent)

54 {

55 if(chkKabul.isSelected()==true)

56 btnKaydet.setEnabled(true);

57 else

58 btnKaydet.setEnabled(false);

59 }

60 }

61 );

62 container.add(chkKabul);

63 setSize(200,150);

64 setVisible(true);

65 }

�� Bölüm 6

Page 85: Bilge adam java.pdf

Kodun açıklaması: İki tane JLabel, iki tane JTextField, bir tane JButton ve bir tane JC-heckBox nesnesi oluşturularak Container nesnesine eklendi. JCheckBox nesnesi üzerinde çalıştırılan addItemListener metodu ile, bu nesnenin durumunun değişmesi halinde tetikle-necek olan event handler’i oluşturuldu. Yazdığımız koda göre, uygulama ilk çalıştırıldığında bu-ton aktif değildir. Kullanıcı ad ve soyad bilgilerini girdikten sonra sözleşmeyi kabul ettiğini belir-ten JCheckBox’ı işaretlediğinde (checkbox’ı seçili hale getirdiğinde) JCheckBox nesnesinin uzerindeki ItemListener metodu çalışır ve buton aktif hale gelir. Benzer bir şekilde kullanıcı CheckBox üzerindeki seçimi iptal ederse buton aktiflik özelliğini yitirir. Kullanıcı gereken bilgileri girdikten sonra Kaydet butonuna tıkladığında ad ve soyad bilgileri bir mesaj kutusu (JOption-Pane) yardımıyla ekranda görüntülenir. Uygulama çalıştırıldığında görünen arayüz Şekil 13, Şekil 14 ve Şekil 15’teki gibidir:

JRadioButtonJRadioButton bileşeni, .Net ortamındaki RadioButton kontrolünün Java platformundaki kar-şılığıdır. Birden fazla seçeneğe sahip bir veri kümesi arasından birinin seçilmesi gereken durum-larda kullanılır. .Net ortamındaki RadioButton kontrolünden farklı olarak arayüz üzerinde aynı anda birden fazla JRadioButton kontrolü seçili durumda bulunabilir. Bu durumu önlemek için, arayüz üzerindeki ilişkili JRadioButton kontrolleri bir tane ButtonGroup nesnesi kullanıla-rak gruplandırılır. JRadioButton kontrolü üzerindeki seçim durumundaki değişiklik JCheckBox�kontrolü gibi ItemListener interface’i ile kontrol edilebilir. İki tane JRadioButton kontrolü ile bir tane ButtonGroup kontrolü içeren ve JRadioButton nesneleri üzerindeki seçim durumu-nun değişikliğini takip eden kod bloğu Örnek Uygulama 6.10’da gösterilmiştir.

Örnek Uygulama 6.10:

66 publicstaticvoidmain(String[]args)

67 {

68 JCheckBoxTesttest=newJCheckBoxTest();

69 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

70 }

71}

Şekil 13: Buton aktif değil. Şekil 14: Buton aktif.

Şekil 15: Kaydet butonuna tıklandı.

1importjava.awt.Container;

2importjava.awt.FlowLayout;

��Swing

Page 86: Bilge adam java.pdf

3importjava.awt.event.ItemEvent;

4importjava.awt.event.ItemListener;

5importjavax.swing.ButtonGroup;

6importjavax.swing.JFrame;

7importjavax.swing.JOptionPane;

8importjavax.swing.JRadioButton;

9importjavax.swing.plaf.basic.BasicComboBoxUI.ItemHandler;

10publicclassJRadioButtonTestextendsJFrame

11{

12 privateJRadioButtonrbErkek;

13 privateJRadioButtonrbKadin;

14 privateButtonGroupgrpRadio;

15 publicJRadioButtonTest()

16 {

17 super(“JRadioButton örneği”);

18 Containercontainer=getContentPane();

19 container.setLayout(newFlowLayout());

20 rbErkek=newJRadioButton(“Erkek”,true);

21 rbErkek.addItemListener(newRadioButtonHandler());

22 container.add(rbErkek);

23 rbKadin = new JRadioButton(“Kadın”, false);

24 rbKadin.addItemListener(newRadioButtonHandler());

25 container.add(rbKadin);

26 // JRadioButton nesnelerini gruplandırmak için ButtonGroup kullanılır

27 grpRadio=newButtonGroup();

28 grpRadio.add(rbErkek);

29 grpRadio.add(rbKadin);

30 setSize(200,100);

31 setVisible(true);

32 }

33 privateclassRadioButtonHandlerimplementsItemListener

34 {

35 publicvoiditemStateChanged(ItemEventevent)

36 {

37 if(event.getStateChange()==ItemEvent.SELECTED)

38 {

39 JOptionPane.showMessageDialog(null,((JRadioButton)event.getSource()).getText());

40 }

41 }

42 }

43 publicstaticvoidmain(String[]args)

44 {

80 Bölüm 6

Page 87: Bilge adam java.pdf

Kodun açıklaması: JRadioButtonTest sınıfının yapıcı metodunda iki tane JRadioButton, bir tane ButtonGroup nesnesi oluşturduk. JRadioButton nesnelerini oluştururken kullandığı-mız yapıcı metodun ikinci parametresi mantıksal değer alır ve uygulama ilk çalıştığında JRadi-oButton nesnesinin seçili durumda olup olmayacağını belirtir. Uygulama ilk çalıştığında Erkek değerine sahip JRadioButton nesnesi seçili durumdadır. İki JRadioButton nesnesi için de aynı event handler sınıfını kullanacağımız için private bir iç sınıf oluşturduk. ItemStateChan-ged event handler metodu JRadioButton nesnelerinden birinin seçili olma durumu değiştiğinde çalışır. Metodun başında kullandığımız if mekanizmasıyla sadece seçili hale gelen nesnelerle ilgilendiğimizi belirttik ve JRadioButton kontrollerinden biri seçili hale geçtiğinde bu nesne-nin text özelliğini mesaj kutusu kullanarak kullanıcıya gösterdik. Eğer ButtonGroup nesnesini kullanmasaydık aynı anda birden fazla JRadioButton kontrolü seçili durumda bulunabilecekti. ButtonGroup nesnesinin olması ve olmaması durumlarında uygulamanın davranışı Şekil 16, Şekil 17 ve Şekil 18’de gösterilmiştir.

JComboBoxJComboBox kontrolü, .Net ortamındaki ComboBox kontrolü gibi bir veri kümesi üzerinden bir tane eleman seçmek amacıyla kullanılır. .Net ortamındaki ComboBox kontrolü seçme, metin cinsinden veri girişi, otomatik tamamlama gibi amaçlar için kullanılabildiği halde JComboBox kontrolü sade-ce veri seçmek amacıyla kullanılabilir, aynı anda birden fazla elemanın seçilmesine izin verilmez. Temel amacı gereği bir arada kullanılan JRadioButton nesnelerine benzese de çalışma zama-nında dinamik veri bağlama kolaylığından dolayı bu kontrolden ayrılır. JComboBox kontrolüne veri bağlanması ve seçili elemanın değişmesi durumunda oluşan event’in kullanılması aşağıdaki kod üzerinde gösterilmiştir.

Örnek Uygulama 6.11:

45 JRadioButtonTesttest=newJRadioButtonTest();

46 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

47 }

48}

Şekil 16: ButtonGroup nesnesi kullanılmadığında herhangi bir zamanda iki JRadioButton bir arada seçilebilir.

Şekil 17: ButtonGroup nesnesi kullanıldı. Şekil 18: rbErkek seçili durumda.

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.ActionEvent;

4importjava.awt.event.ActionListener;

5importjavax.swing.JComboBox;

81Swing

Page 88: Bilge adam java.pdf

Kodun açıklaması: Uygulama içinde bir tane JLabel ve bir tane JComboBox nesnesi tanımla-dık. Öğrenim durumlarını tutan bir string dizisi oluşturarak JComboBox nesnesinin yapıcı meto-duna parametre olarak verdik. JComboBox nesnesi oluşurken yapıcı metoduna parametre olarak verdiğimiz string dizisini veri kaynağı olarak kullanır. JComboBox nesnesinin seçili elemanı de-

6importjavax.swing.JFrame;

7importjavax.swing.JLabel;

8importjavax.swing.JOptionPane;

9publicclassJComboBoxTestextendsJFrame

10{

11 privateJLabellblOgrenimDurumu;

12 privateJComboBoxcmbOgrenimDurumu;

13 publicJComboBoxTest()

14 {

15 super(“JComboBox örneği”);

16 Containercontainer=getContentPane();

17 container.setLayout(newFlowLayout());

18 lblOgrenimDurumu = new JLabel(“Öğrenim durumunuzu seçin”);

19 container.add(lblOgrenimDurumu);

20 String[] ogrenimDurumlari = {“İlkokul”, “Ortaokul”, “Lise”,“Üniversite”,“Yükseklisans”,“Doktora”};

21 cmbOgrenimDurumu=newJComboBox(ogrenimDurumlari);

22 cmbOgrenimDurumu.addActionListener

23 (

24 newActionListener()

25 {

26 publicvoidactionPerformed(ActionEventevent)

27 {

28 JOptionPane.showMessageDialog(null,cmbOgrenimDurumu.getSelectedItem().toString());

29 }

30 }

31 );

32 container.add(cmbOgrenimDurumu);

33 setSize(200,100);

34 setVisible(true);

35 }

36 publicstaticvoidmain(String[]args)

37 {

38 JComboBoxTesttest=newJComboBoxTest();

39 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

40 }

41}

82 Bölüm 6

Page 89: Bilge adam java.pdf

ğiştiğinde çalışmak üzere bir ActionListener event handler metodu tanımladık. Uygulama ilk çalıştığında ilk elemanın seçili durumda olduğu ve event handler metodunun uygulamanın ilk ça-lışması sırasında tetiklenmediği gözlenebilir. Bu aşamadan sonra seçili eleman değiştiği zaman event handler metodu tetiklenir ve seçilmiş olan elemanın sahip olduğu metni bir JOptionPane�mesaj kutusu aracılığıyla kullanıcıya gösterir. Uygulamanın ihtiyacına göre birden fazla JCombo-Box nesnesinin aynı event handler metodunu kullanması sağlanabilir, bu durumda ActionLis-tener interface’ini implement eden bir sınıf oluşturmak gerekir. Ayrıca bir JComboBox nesnesi-nin seçili elemanının değişmesiyle başka bir JComboBox nesnesinin veri kümesinin değişmesi de sağlanabilir. İlerleyen kısımlarda bu durumla ilgili bir örnek yapacağız.

Uygulama ilk çalıştığında ve seçili eleman değiştiğinde Şekil 19 ve Şekil 20’deki gibi bir görünüm oluşur:

JList .Net ortamındaki ListBox kontrolünün Java platformundaki karşılığıdır. Belirli bir veri kümesi üzerinden bir veya daha çok sayıda eleman seçmek amacıyla kullanılır. JComboBox kontrolünde olduğu gibi sahip olduğu veri kümesi uygulamanın çalışması sırasında değiştirilebilir. Uygulama-nın gereksinimlerine bağlı olarak bir tane, belirli bir aralıkta olmak üzere birden fazla veya belirli bir aralıkta bulunma şartı bulunmadan birden fazla elemanın seçili olmasına izin verilebilir. Belirli bir aralıkta olmak üzere birden fazla elemanın seçilmesi sağlanırsa kullanıcı, klavyedeki shift tuşuyla birlikte mouse imlecini kullanarak aralık şeklinde seçim yapabilir. Belirli bir aralıkta bulun-ma şartı olmadan seçim yapılabilecekse kullanıcı, klavyedeki ctrl tuşuyla birlikte mouse imlecini kullanabilir. Gereksinime göre JComboBox nesnesinde olduğu gibi ActionListener interface’i kullanılarak seçili elemanların değişmesi izlenebilir ve kontrol edilebilir.

JList nesnesinin oluşturulması ve kullanımı aşağıdaki Örnek Uygulama 6.12’de gösterilmiştir.

Örnek Uygulama 6.12:

Şekil 19 Şekil 20: Seçili eleman değişti.

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.ActionEvent;

4importjava.awt.event.ActionListener;

5importjavax.swing.JButton;

6importjavax.swing.JFrame;

7importjavax.swing.JLabel;

8importjavax.swing.JList;

8importjavax.swing.JScrollPane;

10importjavax.swing.JTextArea;

11importjavax.swing.ListSelectionModel;

12publicclassJListTestextendsJFrame

13{

14 privateJLabellblIlgiAlanlari;

15 privateJListlstIlgiAlanlari;

83Swing

Page 90: Bilge adam java.pdf

16 privateJScrollPanescrIlgiAlanlari;

17 privateJTextAreatxtSonuc;

18 privateJButtonbtnGoster;

19 publicJListTest()

20 {

21 super(“JListBox örneği”);

22 Containercontainer=getContentPane();

23 container.setLayout(newFlowLayout());

24 lblIlgiAlanlari = new JLabel(“İlgi alanlarınızı seçin”);

25 container.add(lblIlgiAlanlari);

26 String[]ilgiAlanlari=newString[]{“Spor”,“Müzik”,“Edebiyat”,“Tiyatro”,“Resim”,“Sinema”};

27 lstIlgiAlanlari=newJList(ilgiAlanlari);

28//lstIlgiAlanlari.setSelectionMode(ListSelectionModel.SINGLE_

SELECTION);

29//lstIlgiAlanlari.setSelectionMode(ListSelectionModel.SINGLE_

INTERVAL_SELECTION);

30 lstIlgiAlanlari.setSelectionMode(ListSelectionModel.MULTIPLE_

INTERVAL_SELECTION);

31 lstIlgiAlanlari.setVisibleRowCount(4);

32 scrIlgiAlanlari=newJScrollPane(lstIlgiAlanlari);

33 container.add(scrIlgiAlanlari);

34 btnGoster=newJButton(“Göster”);

35 btnGoster.addActionListener

36 (

37 newActionListener()

38 {

39 publicvoidactionPerformed(ActionEventevent)

40 {

41 txtSonuc.setText(“”);

42 Object[]seciliElemanlar=lstIlgiAlanlari.getSelectedValues();

43 for(Objecteleman:seciliElemanlar)

44 {

45 txtSonuc.append(eleman.toString()+“\n”);

46 }

47 }

48 }

49 );

�� Bölüm 6

Page 91: Bilge adam java.pdf

Kodun açıklaması: Uygulamada ilgi alanlarını görüntülemek için bir tane JList nesnesi ve bu nesneye scroll özelliği vermek için bir tane JScrollPane nesnesi kullandık. Kullanıcının bir veya birkaç tane seçebileceği ilgi alanı veri kümesini tutmak için kullanılan string dizisi JList�nesnesinin yapıcı metoduna parametre olarak verildi. Jlist nesnesinin sahip olduğu setSe-lectionMode metodu, JList üzerinde aynı anda birden fazla elemanın seçilmesine izin verilip verilmeyeceğini belirler. Tek bir elemanın seçilmesine izin vermek isteseydik SINGLE_SELEC-TION seçeneğini, belirli bir aralıkta olmak üzere birden fazla elemanın seçilmesine izin vermek isteseydik SINGLE_INTERVAL_SELECTION seçeneğini kullanacaktık. Kullandığımız yapıda ise belirli bir aralığa dahil olan veya olmayan birden fazla eleman seçilebilir. JList nesnesi varsa-yılan olarak sahip olduğu bütün elemanları alt alta gösterir. Eleman sayısı arttıkça nesne uygu-lama arayüzü üzerinde fazla yer kaplamaya başlayacağından scroll özelliğine ihtiyaç duyulabilir. JList nesnesinin kendine ait bir scroll özelliği olmadığı halde JScrollPane bileşeni kullanıla-rak JList nesnesine scroll özelliği verilebilir. Koda dikkat edilirse JList nesnesinin doğrudan Container nesnesine eklenmediği görülebilir. JList nesnesi JScrollPane nesnesine, JSc-rollPane nesnesi ise Container nesnesine eklenmiştir. JList nesnesinin setVisible-RowCount metodu scroll işleminden önce görüntülenecek eleman sayısını belirlemek amacıyla kullanılır. Örnek uygulamada, dört tane elemanın görünür halde olmasına izin verilmiştir, diğer elemanlara ancak scroll işlemiyle ulaşılabilir.

Örnek uygulamada, JList nesnesi üzerinde kullanıcının seçtiği elemanların değeri butona basıl-dıktan sonra JTextArea nesnesine yazılır. Butona her tıklandığında JTextArea bileşenin text özelliği boş string değeri almaktadır, bunun sebebi sadece butona tıklandığı anda seçili olan elemanların değerlerini görüntülemek istememizdir.

Uygulama çalıştırıldığında ve butona tıklandığında Şekil 21 ve Şekil 22’de olduğu gibi görünür.

50 container.add(btnGoster);

51 txtSonuc=newJTextArea();

52 container.add(txtSonuc);

53 setSize(200,200);

54 setVisible(true);

55 }

56 publicstaticvoidmain(String[]args)

57 {

58 JListTesttest=newJListTest();

59 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

60 }

61}

Şekil 21: Uygulama çalıştırıldığında JTextArea nesnesi görünmüyor.

Şekil 22: Üç tane eleman seçildi ve Göster bu-tonuna tıklandı.

��Swing

Page 92: Bilge adam java.pdf

JList kontrolü sıklıkla kullanılabilecek bir kontrol olduğu için, birçok uygulamada karşımıza çıka-bilecek bir arayüz oluşturalım ve iki tane JList kontrolü arasında veri aktarımı yapalım.

Örnek Uygulama 6.13:

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.ActionEvent;

4importjava.awt.event.ActionListener;

5importjavax.swing.DefaultListModel;

6importjavax.swing.JButton;

7importjavax.swing.JFrame;

8importjavax.swing.JList;

9importjavax.swing.ListSelectionModel;

10publicclassVeriAktarimiextendsJFrame

11{

12 privateJListlstIlgiAlanlari;

13 privateJListlstSecilmisIlgiAlanlari;

14 privateJButtonbtnEkle;

15 privateJButtonbtnCikar;

16 privateDefaultListModelmodelElemanlar;

17 privateDefaultListModelmodelSeciliElemanlar;

18 publicVeriAktarimi()

19 {

20 super(“JListBox nesneleri arasında veri aktarımı”);

21 Containercontainer=getContentPane();

22 container.setLayout(newFlowLayout());

23 modelElemanlar=newDefaultListModel();

24 modelSeciliElemanlar=newDefaultListModel();

25 modelElemanlar.addElement(“Spor”);

26 modelElemanlar.addElement(“Müzik”);

27 modelElemanlar.addElement(“Edebiyat”);

28 modelElemanlar.addElement(“Tiyatro”);

29 modelElemanlar.addElement(“Resim”);

30 modelElemanlar.addElement(“Sinema”);

31 lstIlgiAlanlari=newJList(modelElemanlar);

32 lstIlgiAlanlari.setSelectionMode(ListSelectionModel.MULTIPLE_

INTERVAL_SELECTION);

33 container.add(lstIlgiAlanlari);

34 btnCikar=newJButton(“<<<<”);

35 btnCikar.setEnabled(false);

36 btnCikar.addActionListener

37 (

38 newActionListener()

39 {

�� Bölüm 6

Page 93: Bilge adam java.pdf

40 publicvoidactionPerformed(ActionEventevent)

41 {

42 Object[]seciliElemanlar=lstSecilmisIlgiAlanlari.getSelectedValues();

43 for(Objecteleman:seciliElemanlar)

44 {

45 modelSeciliElemanlar.removeElement(eleman.toString());

46 modelElemanlar.addElement(eleman.toString());

47 }

48 if(modelSeciliElemanlar.getSize()==0)

49 {

50 btnCikar.setEnabled(false);

51 }

52 if(modelElemanlar.getSize()!=0)

53 {

54 btnEkle.setEnabled(true);

55 }

56 }

57 }

58 );

59 container.add(btnCikar);

60 btnEkle=newJButton(“>>>>”);

61 btnEkle.addActionListener

62 (

63 newActionListener()

64 {

65 publicvoidactionPerformed(ActionEventevent)

66 {

67 Object[]seciliElemanlar=lstIlgiAlanlari.getSelectedValues();

68 for(Objecteleman:seciliElemanlar)

69 {

70 modelElemanlar.removeElement(eleman.toString());

71 modelSeciliElemanlar.addElement(eleman.toString());

72 }

73 if(modelElemanlar.getSize()==0)

74 {

��Swing

Page 94: Bilge adam java.pdf

Kodun açıklaması: Uygulamada iki tane JList kontrolü ile iki tane JButton kontrolü kullan-dık. Bir önceki örnekte JList kontrolüne veri kaynağı olarak bir string dizisi verdiğimiz halde bu örnekte DefaultListModel nesnesinden yararlandık. Bunun sebebi, DefaultListModel�bileşeninin uygulamanın çalışması sırasında veri ekleme ve çıkartma işlemlerini desteklemesidir. Uygulama ilk çalıştığı sırada bütün ilgi alanları sol tarafta bulunan JList bileşenin içinde bulunur ve sol tarafa veri aktarmayı sağlayan buton aktif değildir. Bir veya birden fazla ilgi alanı seçilip sağ tarafa veri aktarmayı sağlayan butona tıklandığında, seçili elemanlar modelElemanlar nes-nesinden removeElement metodu yardımıyla çıkartılır modelSeciliElemanlar nesnesine addElement metodu yardımıyla eklenir. Bu işlemler JButton nesneleri için yazılan ve Action-Listener interface’ini implement eden metodlar içinde gerçeklenir. Sol taraftaki JList bileşenin içinde eleman kalmadığında sola aktarma işlemini gerçekleyen buton aktif olmaktan çıkar. JList�nesnelerine veri kaynağı olarak bağladığımız DefaultListModel nesnelerini event handler metodları içinde tekrar bağlamaya gerek olmadığına dikkat edelim, bu durum kullandığımız nes-nelerin referans tipinde olmasından kaynaklanır. DefaultListModel nesnelerinin barındırdığı veriler değiştiğinde otomatik olarak JList görünümleri de değişir.

Uygulama çeşitli çalışma aşamalarında Şekil 23, Şekil 24 ve Şekil 25’te olduğu gibi görünür:

75 btnEkle.setEnabled(false);

76 }

77 if(modelSeciliElemanlar.getSize()!=0)

78 {

79 btnCikar.setEnabled(true);

80 }

81 }

82 }

83 );

84 container.add(btnEkle);

85 lstSecilmisIlgiAlanlari=newJList(modelSeciliElemanlar);

86 lstIlgiAlanlari.setSize(100,100);

87 container.add(lstSecilmisIlgiAlanlari);

88 setSize(200,200);

89 setVisible(true);

90 }

91 publicstaticvoidmain(String[]args)

92 {

93 VeriAktarimitest=newVeriAktarimi();

94 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

95 }

96}

�� Bölüm 6

Page 95: Bilge adam java.pdf

Mouse Event’lerinin Yönetilmesi:Fare hareketleri ile tetiklenen event yapıları MouseListener ve MouseMotionListener interface’lerinin implement edilmesiyle kontrol edilebilir. Bu interface’lerin içinde bulunan metodlar şu şekildedir:

MouseListener

mousePressed: Fare butonlarından birine basıldığı anda tetiklenir.

mouseClicked: Fare butonlarından birine basılıp bırakıldığında tetiklenir.

mouseReleased: Fare butonlarından birine basıldıktan sonra bırakıldığında tetiklenir.

mouseEntered: Fare imleci bir bileşenin alanına girdiğinde tetiklenir.

mouseExited: Fare imleci bir bileşenin alanını terk ettiğinde tetiklenir.

MouseMotionListener:

mouseDragged: Fare imleci bir bileşenin üzerindeyken butonlardan birine basılarak mouse ha-reket ettirildiğinde tetiklenir.

mouseMoved: Fare imleci bir bileşenin üzerindeyken fare hareket ettirildiğinde tetiklenir.

Fare ile ilgili event’leri kontrol eden bütün metodlar parametre olarak bir MouseEvent nesnesi alırlar. Fare imlecinin x ve y koordinatları, hangi butona kaç kere basıldığı gibi bilgiler bu nesne aracılığıyla alınır. Mouse event’leri herhangi bir bileşen için kaydedilebilir ve bu bileşen üzerinde herhangi bir fare hareketi olduğunda ilgili event metodu tetiklenir. Interface mantığından dolayı MouseListener ve MouseMotionListener interface’lerinden herhangi biri implement edildiğinde bu interface’in içinde bulunan bütün metodlar implement edilmek zorundadır. Kullanılmayacak olan metodların tanımları yapılarak içleri boş bırakılır.

Mouse event’lerini kontrol etmek amacıyla oluşturduğumuz uygulamanın kodları aşağıdaki gibi-dir.

Şekil 23: Üç tane eleman seçili durumda, henüz butona tıklanmış.

Şekil 24: Sağ tarafa aktarma işlemi yapıldıktan sonra iki buton da aktif.

Şekil 25: Sol taraftaki bütün veriler sağ tarafa geçmiş, sağa ak-tarma butonu kullanılamıyor.

��Swing

Page 96: Bilge adam java.pdf

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.MouseEvent;

4importjava.awt.event.MouseListener;

5importjavax.swing.JFrame;

6importjavax.swing.JLabel;

7importjavax.swing.JTextArea;

8publicclassMouseYonetimiextendsJFrame

9{

10 privateJTextAreatxtContainerEvent;

11 privateJTextAreatxtLabelEvent;

12 privateJLabellblAlan;

13 publicMouseYonetimi()

14 {

15 super(“Mouseyönetimi”);

16 Containercontainer=getContentPane();

17 container.setLayout(newFlowLayout());

18 container.addMouseListener(newContainerMouseListenerHandler());

19 lblAlan = new JLabel(“Mouse imlecini bu alanın üzerinegetirin”);

20 lblAlan.addMouseListener(newJLabelMouseListenerHandler());

21 container.add(lblAlan);

22 txtContainerEvent=newJTextArea();

23 container.add(txtContainerEvent);

24 txtLabelEvent=newJTextArea();

25 container.add(txtLabelEvent);

26 setSize(200,200);

27 setVisible(true);

28 }

29 privateclassContainerMouseListenerHandlerimplementsMouseListener

30 {

31 publicvoidmouseClicked(MouseEventevent)

32 {

33 txtContainerEvent.append(ButonAdiAl(event.getButton())+“butona“+event.getClickCount() + “ kez basıldı ve bırakıldı\n”);

34 }

35 publicvoidmousePressed(MouseEventevent)

36 {

37 txtContainerEvent.append(ButonAdiAl(event.getButton())+“butona(“+event.getX()+ “,” + event.getY() + “) noktasında basıldı\n”);

38 }

90 Bölüm 6

Page 97: Bilge adam java.pdf

39 publicvoidmouseReleased(MouseEventevent)

40 {

41 txtContainerEvent.append(ButonAdiAl(event.getButton()) + “ buton bırakıldı\n”);

42 }

43 publicvoidmouseEntered(MouseEventevent)

44 {

45 }

46 publicvoidmouseExited(MouseEventevent)

47 {

18 }

49 }

50 privateclassJLabelMouseListenerHandlerimplementsMouseListener

51 {

52 publicvoidmouseEntered(MouseEventevent)

53 {

54 txtLabelEvent.append(“MouseimleciJLabelbölgesinegirdi\n”);

55 }

56 publicvoidmouseExited(MouseEventevent)

57 {

58 txtLabelEvent.append(“MouseimleciJLabel bölgesinden çıktı\n”);

59 }

60 publicvoidmouseClicked(MouseEventevent)

61 {

62 }

63 publicvoidmousePressed(MouseEventevent)

64 {

65 }

66 publicvoidmouseReleased(MouseEventevent)

67 {

68 }

69 }

70 publicstaticStringButonAdiAl(intbutonNumarasi)

71 {

72 StringbutonAdi=“”;

73 if(butonNumarasi==MouseEvent.BUTTON1)

74 {

75 butonAdi=“Sol”;

76 }

77 elseif(butonNumarasi==MouseEvent.BUTTON2)

78 {

79 butonAdi=“Orta”;

91Swing

Page 98: Bilge adam java.pdf

Kodun açıklaması: Container nesnesi ve JLabel nesnesi için birer tane event handler sınıfı oluşturduk. İki sınıf da MouseListener interface’ini implement ediyor. Kullanılmayan metodların gövdelerini boş bırakarak interface yapısından kaynaklanan derleme hatalarını önlemiş olduk. Uygulamada kullanılan statik ButonAdiAl metodu, tıklanan butonun numarasını alarak butona bir isim vererek döndürür. Örneğin sol fare butonuna tıklandığında buton kodu olarak “1” değeri oluşur, ButonAdiAl metodunu kullanarak “Sol” değeri döndürülür.

Container nesnesinin ilişkili olduğu ContainerMouseListenerHandler sınıfının içinde bulu-nan metodlar aşağıdaki işlevlere sahiptir:

mousePressed: Fare butonlarından biriyle formun üzerine tıklandığında hangi butona basıldığı ve tıklanan pozisyonun x ve y değerleri JTextArea bileşenine eklenir.

mouseReleased: Tıklandıktan sonra bırakılan mouse butonunun adı JTextArea bileşenine ek-lenir.

mouseClicked: Tıklandıktan sonra bırakılan fare butonunun adı ve tıklanma sayısı JTextArea bileşenine eklenir.

JLabel nesnesinin ilişkili olduğu JLabelMouseListenerHandler sınıfının içinde bulunan me-todlar aşağıdaki işlevlere sahiptir:

mouseEntered: Fare imleci JLabel kontrolünün üzerine geldiğinde ikinci JTextArea nesnesine bu bilgi yazılır.

mouseExited: Fare imleci JLabel kontrolünün bölgesinden çıktığında ikinci JTextArea nesnesine bu bilgi yazılır.

Uygulama çalıştırıldıktan sonra mouse ile JLabel kontrolünün bölgesine girilip çıkıldığında ve form üzerine farklı fare butonlarıyla çeşitli seferlerde tıklandığında, uygulama arayüzü aşağıdaki gibi bir görünüm alır.

80 }

81 elseif(butonNumarasi==MouseEvent.BUTTON3)

82 {

83 butonAdi = “Sağ”;

84 }

85 returnbutonAdi;

86 }

87 publicstaticvoidmain(String[]args)

88 {

89 MouseYonetimitest=newMouseYonetimi();

90 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

91 }

92 }

92 Bölüm 6

Page 99: Bilge adam java.pdf

Java ortamının event altyapısı interface’ler üzerine kurulu olduğu için, içinde birden fazla metod tanımı bulunan interface’lerin kullanılması durumunda gereksiz metodlar da implement edilmek zorundadır. Bu durumun önüne geçmek için Adapter sınıfları oluşturulmuştur. Adapter sınıfları ilgili interface’lerin bütün metodlarını gövdeleri boş olacak şekilde implement eder. Yeni oluşturu-lan event handler sınıfları Adapter sınıflarından türetilirse sadece gerekli event metodları override edilebilir. Mouse event’lerinin kontrol edilmesi için MouseAdapter sınıfının temel sınıf olarak kul-lanıldığı bir uygulamanın kodları aşağıdadır.

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.MouseAdapter;

4importjava.awt.event.MouseEvent;

5importjavax.swing.JFrame;

6importjavax.swing.JTextArea;

7publicclassMouseAdapterTestextendsJFrame

8{

9 privateJTextAreatxtContainerEvent;

10 publicMouseAdapterTest()

11 {

12 super(“Mouseyönetimi”);

13 Containercontainer=getContentPane();

14 container.setLayout(newFlowLayout());

15 container.addMouseListener(newContainerMouseHandler());

93Swing

Page 100: Bilge adam java.pdf

Uygulama çalıştırılıp formun üzerine çeşitli mouse butonlarıyla tıklanırsa arayüz aşağıdaki gibi bir görünüme sahip olur.

Klavye Event’lerinin YönetilmesiKullanıcının klavye ile etkileşimi sonucunda oluşan event’ler KeyListener interface’ini implement eden sınıfların oluşturulması ile kontrol edilir. KeyListener interface’inin içinde aşağıdaki metodlar bulunur:

keyPressed: Klavyedeki herhangi bir tuşa basıldığında tetiklenir.

16 txtContainerEvent=newJTextArea();

17 container.add(txtContainerEvent);

18 setSize(200,200);

19 setVisible(true);

20 }

21 privateclassContainerMouseHandlerextendsMouseAdapter

22 {

23 publicvoidmouseClicked(MouseEventevent)

24 {

25 txtContainerEvent.append(event.getButton() + “ numaralı butona “ + event.getClickCount() + “ kez basıldı ve bırakıldı\n”);

26 }

27 }

28 publicstaticvoidmain(String[]args)

29 {

30 MouseAdapterTesttest=newMouseAdapterTest();

31 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

32 }

33 }

�� Bölüm 6

Page 101: Bilge adam java.pdf

keyTyped: Aksiyon tuşu olmayan tuşlardan herhangi birine basıldığında tetiklenir. Aksiyon tuşları ok tuşları, home, end, scroll lock gibi işlevsel özellikleri olan tuşlardır.

keyReleased: Herhangi bir buton bırakıldıktan sonra, yani keyTyped veya keyPressed event’inden sonra tetiklenir.

Klavye event’lerinin kullanımını gösteren uygulamayı oluşturan kodlar aşağıda verilmiştir.

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjava.awt.event.KeyEvent;

4importjava.awt.event.KeyListener;

5importjavax.swing.JFrame;

6importjavax.swing.JTextArea;

7publicclassKeyboardEventTestextendsJFrame

8{

9 privateJTextAreatxtContainerEvent;

10 publicKeyboardEventTest()

11 {

12 super(“Klavyeyönetimi”);

13 Containercontainer=getContentPane();

14 container.setLayout(newFlowLayout());

15 txtContainerEvent=newJTextArea();

16 txtContainerEvent.setEnabled(false);

17 container.add(txtContainerEvent);

18 this.addKeyListener(newKeyboardEventHandler());

19 setSize(200,200);

20 setVisible(true);

21 }

22 privateclassKeyboardEventHandlerimplementsKeyListener

23 {

24 publicvoidkeyPressed(KeyEventevent)

25 {

26 txtContainerEvent.append(“keyPressed\tDeğer: “ + event.getKeyText(event.getKeyCode()) + “\n”);

27 }

28 publicvoidkeyReleased(KeyEventevent)

29 {

30 txtContainerEvent.append(“keyReleased\t\n\n”);

31 }

32 publicvoidkeyTyped(KeyEventevent)

33 {

34 txtContainerEvent.append(“keyTyped\tDeğer: “ + event.getKeyChar() + “\n”);

��Swing

Page 102: Bilge adam java.pdf

Kodun açıklaması: Kullanıcı klavyedeki herhangi bir tuşa bastığında keyPressed event’i tetik-lenir. Basılan tuş aksiyon tuşu değilse keyTyped event’i de tetiklenir. Basılan tuş ne olursa olsun keyReleased event handler metodu en son çalışır. keyPressed ve keyTyped event handler me-todları; çalışan event’in adını ve basılan tuşa karşılık gelen karakter değerini JTextArea bileşenine ekler. keyReleased event handler metodu ise tuşun bırakıldığını belirtir, hangi tuş üzerine işlem yapıldığını bildirmez. Uygulama çalıştırıldıktan sonra sırasıyla q, home, F2, 7, alt, ctrl tuşlarına basılırsa arayüz aşağıdaki gibi bir görünüme kavuşur.

Layout YönetimiSwing tabanlı arayüzler içeren Java uygulamalarında arayüze eklenen bileşenlerin form üzerin-deki görünümleri layout yapılarıyla şekillendirilir.

FlowLayout: Bu görünümde arayüze eklenen bileşenler soldan sağa doğru eklendikleri sırada görüntülenirler. Bütün örneklerimizde FlowLayout görünümünü kullandık. Dört tane JButton nes-nesiyle bir tane JTextArea nesnesini FlowLayout biçiminde düzenlenmiş bir Swing arayüzüne ekleyelim. Uygulamanın kodları aşağıda verilmiştir.

35 }

36 }

37 publicstaticvoidmain(String[]args)

38 {

39 KeyboardEventTesttest=newKeyboardEventTest();

40 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

41 }

42 }

1importjava.awt.Container;

2importjava.awt.FlowLayout;

3importjavax.swing.JButton;

�� Bölüm 6

Page 103: Bilge adam java.pdf

Bileşenler formun üzerine soldan sağa doğru eklenmiştir. Çalışma sırasında formun boyutu de-ğiştirilirse arayüz kontrollerinin form üzerindeki yerleri de değişecektir. Formun iki farklı boyutu için arayüzün görünümü aşağıda verilmiştir.

BorderLayout: JFrame sınıfından türeyen sınıfların varsayılan layout görünümüdür. Uygulama arayüzü kuzey, güney, doğu, batı ve merkez olmak üzere beş parçaya ayrılır. Uygulamaya kon-

4importjavax.swing.JFrame;

5importjavax.swing.JTextArea;

6publicclassFlowLayoutTestextendsJFrame

7{

8 publicFlowLayoutTest()

9 {

10 super(“BorderLayout”);

11 Containercontainer=getContentPane();

12 FlowLayoutlayout=newFlowLayout();

13 container.setLayout(layout);

14 JButtonbtn1=newJButton(“1.Buton”);

15 container.add(btn1);

16 JButtonbtn2=newJButton(“2.Buton”);

17 container.add(btn2);

18 JButtonbtn3=newJButton(“3.Buton”);

19 container.add(btn3);

20 JButtonbtn4=newJButton(“4.Buton”);

21 container.add(btn4);

22 JTextArea txt = new JTextArea(“Metin alanı”);

23 container.add(txt);

24 setSize(300,200);

25 setVisible(true);

26 }

27 publicstaticvoidmain(String[]args)

28 {

29 FlowLayoutTesttest=newFlowLayoutTest();

30 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

31 }

32 }

��Swing

Page 104: Bilge adam java.pdf

trol ekleme aşamasında hangi bölgeye ekleneceği belirtilir. Dört tane JButton nesnesi ile bir tane JTextBox nesnesi içeren bir arayüzü BorderLayout biçiminde oluşturalım.

JButton kontrolleri arayüzün kuzey, güney, doğu ve batı bölgelerine, JTextArea bileşeni ise mer-kez bölgesine eklenmiştir. Uygulama çalıştırıldığında aşağıdaki gibi görünür.

importjava.awt.BorderLayout;

importjava.awt.Container;

importjavax.swing.JButton;

importjavax.swing.JFrame;

importjavax.swing.JTextArea;

1publicclassBorderLayoutTestextendsJFrame

2{

3 publicBorderLayoutTest()

4 {

5 super(“BorderLayout”);

6 Containercontainer=getContentPane();

7 BorderLayoutlayout=newBorderLayout(10,10);

8 container.setLayout(layout);

9 JButtonbtnNorth=newJButton(“Kuzey”);

10 container.add(btnNorth,BorderLayout.NORTH);

11 JButtonbtnSouth=newJButton(“Güney”);

12 container.add(btnSouth,BorderLayout.SOUTH);

13 JButton btnEast = new JButton(“Doğu”);

14 container.add(btnEast,BorderLayout.EAST);

15 JButton btnWest = new JButton(“Batı”);

16 container.add(btnWest,BorderLayout.WEST);

17 JTextAreatxtCenter=newJTextArea(“Merkezbölge”);

18 container.add(txtCenter,BorderLayout.CENTER);

19 setSize(300,200);

20 setVisible(true);

21 }

22 publicstaticvoidmain(String[]args)

23 {

24 BorderLayoutTesttest=newBorderLayoutTest();

25 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

26 }

27 }

�� Bölüm 6

Page 105: Bilge adam java.pdf

GridLayout: GridLayout biçimi, container’ı satırlar ve sütunlardan oluşan bir grid şeklinde düzen-ler. GridLayout şeklinde düzenlenmiş bir arayüzdeki bütün bileşenlerin boyutu aynı olur. GridLa-yout biçiminde düzenlenmiş bir Swing arayüzünü aşağıdaki kod bloğuyla oluşturabiliriz.

1importjava.awt.Container;

2importjava.awt.GridLayout;

3importjavax.swing.JButton;

4importjavax.swing.JFrame;

5importjavax.swing.JTextArea;

6publicclassGridLayoutTestextendsJFrame

7{8 publicGridLayoutTest()

9 {10 super(“GridLayout”);

11 Containercontainer=getContentPane();

12 GridLayoutlayout=newGridLayout(2,3);

13 container.setLayout(layout);

14 JButtonbtn1=newJButton(“1.Buton”);

15 container.add(btn1);

16 JButtonbtn2=newJButton(“2.Buton”);

17 container.add(btn2);

18 JButtonbtn3=newJButton(“3.Buton”);

19 container.add(btn3);

20 JButtonbtn4=newJButton(“4.Buton”);

21 container.add(btn4);

22 JTextArea txt = new JTextArea(“Metin alanı”);

23 container.add(txt);24 setSize(300,200);25 setVisible(true);

26 }27 publicstaticvoidmain(String[]args)

28 {29 GridLayoutTesttest=newGridLayoutTest();

30 test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);31 }

32 }

��Swing

Page 106: Bilge adam java.pdf

Uygulama çalıştırıldığında aşağıdaki gibi bir arayüz oluşur:

Bunların dışında daha az kullanılan BoxLayout, CardLayout ve GridBagLayout görünümleri de vardır.

100 Bölüm 6

Page 107: Bilge adam java.pdf

7 JDBC

Page 108: Bilge adam java.pdf

7 JDBCVeritabanı Bağlantısının Kurulması

Veri Değiştirme Komutları (insert, update, delete)

Veri Sorgulama Komutları (Select)

Parametreli SQL İfadelerinin Çalıştırılması

Stored Procedure’lerin Çalıştırılması

Page 109: Bilge adam java.pdf

JDBCJava uygulamaları üzerinden veri kaynaklarını bulmak ve bulunan kaynaklara bağlanarak bu kay-naklar üzerinde çeşitli sorguları çalıştırmak için JDBC adı verilen Java API’si kullanılır. JDBC, .Net ortamındaki ADO.Net yapısının Java platformundaki karşılığıdır. JDBC, platform bağımsız-lığını sağlayabilmek için, ortamdaki veri kaynaklarına bağlanmak amacıyla kullanılan sürücüleri çalışma zamanında tespit edebilen bir sürücü yönetim sistemine(Driver Manager) sahiptir. Veri kaynaklarına bağlanmadan önce sürücülerin yüklenmesini sağlamak için Class.forName()�metodu gereken parametreler kullanılarak çağrılır.

ODBC sürücüsüne sahip olan veri kaynaklarına bağlanmak için JDBC-ODBC köprüsü kullanılır. Sürücüler bulunduktan sonra ODBC üzerinde kayıtlı bulunan herhangi bir veri kaynağına bağla-nılabilir. Windows tabanlı işletim sistemleri üzerinde bulunan bir veritabanı yönetim sistemi yazılı-mındaki bir veritabanına bağlanmak için, bu veritabanının ODBC kaynaklarına eklenmesi gerekir. Bu işlem denetim masasında veya yönetimsel araçlarda bulunan veri kaynakları (ODBC) seçene-neği kullanılarak gerçekleştirilebilir.

Bilgisayarımızda bulunan Microsoft SQL Server 2005 veritabanı sunucusu üzerinde dört tablodan oluşan AlisveriSitesi adında bir veritabanı oluşturarak uygulamalarımızı bu veritabanı üzerinde çalıştıralım. AlisverisSitesi veritabanını oluşturmak ve sahip olduğu tabloları oluşturmak için kul-lanılacak SQL ifadeleri ve veritabanının diyagramı Şekil 1’de gösterilmiştir.

Örnek Uygulama 7.1:

Şekil 1

1createdatabaseAlisverisSitesi

2useAlisverisSitesi

3createtableUrun

4(

5 urunIDintprimarykeyidentity(1,1),

6 urunAdivarchar(20),

7 fiyatmoney

8)

9createtableMusteri

Page 110: Bilge adam java.pdf

Veritabanımızı oluşturduktan sonra denetim masasından veya yönetimsel araçlardan veri kay-nakları (ODBC) ayarlarını açalım. Java üzerinden herhangi bir veri kaynağına bağlanmadan önce kullanacağımız veritabanı sunucusunu ve veritabanını System DSN menüsünden kayıt edeceğiz. System DSN menüsü ilk açıldığında Şekil 2’dekine benzer bir görünüme sahip olacaktır.

Yeni bir veri kaynağı eklemek için Add butonuna tıklayalım. Karşımıza çıkan pencerede, bağlan-mak istediğimiz veri kaynağını seçtikten sonra Finish butonuna tıklayarak veri kaynağımızla ilgili

10(

11 musteriIDintprimarykeyidentity(1,1),

12 advarchar(20),

13 soyadvarchar(30),

14)

15createtableSiparis

16(

17 siparisIDintprimarykeyidentity(1,1),

18 musteriIDintforeignkeyreferencesMusteri(musteriID),

19 siparisTarihismalldatetime

20)

21createtableSiparisDetay

22(

23 siparisIDintforeignkeyreferencesSiparis(siparisID),

24 urunIDintforeignkeyreferencesUrun(urunID),

25 miktarint

26)

Şekil 2

104 Bölüm 7

Page 111: Bilge adam java.pdf

ek bilgiler istenir. Microsoft SQL Server veritabanı sunucusu kullandığımız için en altta bulunan SQL Server seçeneğini seçmeliyiz.

Bir sonraki pencerede, veri kaynağımıza vereceğimiz ismi ve kullanılacak veritabanı sunucusu-nun adını veya adresini yazdıktan sonra Next butonuna tıklayalım. Veri kaynağı ile ilgili ayarlar Şekil 4’te görülebilir.

Veritabanı sunucumuz belirlendikten sonra, bu sunucuya bağlanmak için kullanılacak olan kimlik bilgilerinin girileceği ekran karşımıza çıkar. SQL Server veritabanı sunucusuna bağlanmak için Windows Authentication veya SQL Authentication kullanabiliriz. Windows Authentication kullan-mamız durumunda kullanıcı adı ve şifre bilgileri istenmez, veritabanı sunucusuna bağlanmak için sisteme giriş yapmış olan Windows kullanıcı hesabı kullanılır. Bahsedilen ayarlar Şekil 5’te görülebilir.

Şekil 3

Şekil 4

105JDBC

Page 112: Bilge adam java.pdf

SQL Server 2005 veritabanı sunucusuna bağlanmak için Windows NT Authentication modunu seçtikten sonra Next butonuna tıklayın. AlisverisSitesi adını verdiğimiz sürücüyle bağlanılacak olan varsayılan veritabanını en üstteki change default database to checkbox’ı yardımıyla belirle-yebiliriz. AlisverisSitesi veritabanını varsayılan veritabanı olarak seçtikten sonra Next butonuna ve bir sonraki pencerede Finish butonuna tıklayın. Son üç aşamada karşımıza çıkan ekran gö-rüntüleri aşağıdadır.

Şekil 5

Şekil 6

106 Bölüm 7

Page 113: Bilge adam java.pdf

Finish butonuna tıkladıktan sonra ODBC veri kaynağının başarıyla eklendiğini belirten bir mesaj aldık. ODBC kaynağı eklendikten sonra Şekil 8’de gösterilen Test Data Source butonuna tıklaya-rak veritabanı bağlantımızın doğru çalışıp çalışmadığını kontrol edin. Şekil 9’da görülen mesaj, veri kaynağına başarıyla bağlandığımızı gösterir.

Şekil 7

Şekil 8

107JDBC

Page 114: Bilge adam java.pdf

Veritabanı Bağlantısının KurulmasıVeritabanına bağlanmak için kullanılacak ODBC kaynağını işletim sistemine ekledikten sonra Java ortamı üzerinden AlisverisSitesi veritabanına bağlanmaya çalışalım. Veri kaynağına bağlan-mak için aşağıdaki adımların gerçekleşmesi gerekir:

İşletim sistemi üzerinde bulunan JDBC sürücüsünün Class.forName() metodu yardımıyla bulunması.

DriverManager sınıfında bulunan getConnection() metodu ile veritabanı bağlantısının sağlanması.

Class.forName metodunun uygulamada kullanılabilmesi için, bu metodu çağıran metodun ClassNotFoundException tipinden hata fırlatabilmesi gerekir. Benzer bir şekilde DriverMa-nager.getConnection() metodunu çağıran metodun SQLException tipinden hata fırlatabil-mesi gerekir. İki metod çağrısını da uygulamanın main metodundan yapacağımız için main meto-dumuz bu iki hatayı da fırlatabilecek şekişlde oluşturulur. Aşağıdaki kodu yazıp çalıştırdığımızda herhangi bir mesaj almazsak ODBC kaynağına bağlantı kurmayı başardık demektir.

Örnek Uygulama 7.2:

1�

2.

Şekil 9

1importjava.sql.Connection;

2importjava.sql.DriverManager;

3 import java.sql.SQLException;

4publicclassVeritabaniBaglantisi

5{

6 publicstaticvoidmain(String[]args)throwsClassNotFoundException, SQLException

7 {

8 try

9 {

10 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

11 Connectionbaglanti=DriverManager.getConnection(“jdbc:odbc:AlisverisSites1i”);

108 Bölüm 7

Page 115: Bilge adam java.pdf

Eğer bağlantı kurma aşamasında SQLException veya ClassNotFoundException oluşursa aşağıdaki iki hata mesajından birini alırız.

[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

sun.jdbc.ODBC.JdbcOdbcDriver

JDBC altyapısı kullanılarak veritabanı sunucularının desteklediği komutlar çalıştırılabilir. SQL Server veritabanı sunucusu üzerinde veri değiştirme komutları (insert, update, delete), veri tanım komutları(create, alter, drop) ve sorgu komutları (select) çalıştırılarak uygulamanın ihtiyaçlarına göre bir veri erişim altyapısı oluşturulması sağlanabilir.

Veri kaynağı üzerinde çalıştırılacak ifadeler, Connection nesnesi aracılığıyla oluşturulur. Conne-ction nesnesinin createStatement() metodu ile oluşturulan Statement nesnesi veritabanına SQL ifadelerini göndermek amacıyla kullanılır. Statement nesnesi oluştuktan sonra, bu nesnenin sahip olduğu executeXxx metodları ile SQL ifadeleri veritabanı sunucusu üzerinde çalıştırılır. Connection nesnesini sahip olduğı metodlarla Statement tipinden başka tiplerde ifadeler de oluş-turulabilir. (Örneğin BLOB, XML..)

Veri Değiştirme Komutları (insert, update, delete)JDBC kütüphanesi kullanılarak veritabanı üzerinde insert, update, delete gibi veri ile ala-kalı komutlar çalıştırmak için genellikle Statement nesnesinin executeUpdate komutları kullanılır. executeUpdate komutları, veritabanı üzerinde çalıştırılan ifadeden etkilenen kayıt sayısını tam sayı değeri olarak döndürür ve ADO.Net mimarisinde bulunan Command nesnesinin Execute-NonQuery metoduna benzerlik gösterir.

Örnek Uygulama 7.3’de verdiğimiz kod bloğunda veritabanına üç tane müşteri ve beş tane ürün eklenmektedir. Tablolarda bulunan xxxID alanları identity olarak tanımlandığından, değerleri oto-matik olarak ve birer birer artarak verilir. Bu sebepten dolayı insert ifadesinin içinde xxxID alanla-rının bulunması hata oluşmasına neden olur.

Örnek Uygulama 7.3:

1importjava.sql.Connection;

2importjava.sql.DriverManager;

3 import java.sql.SQLException;

4importjava.sql.Statement;

5publicclassVeritabaniBaglantisi

6{

7 publicstaticvoidmain(String[]args)throwsClassNotFoundException, SQLException

8 {

9 try

12 }

13 catch(Exceptione)

14 {

15 System.out.println(e.getMessage());

16 }

17 }

18}

109JDBC

Page 116: Bilge adam java.pdf

10 {

11 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

12 ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

13 StatementstaInsert=dbConnection.createStatement();

14 staInsert.executeUpdate(“INSERTINTOMusteri(ad, soyad) VALUES (‘Yalçın’, ‘Kaya’)”);

15 staInsert.executeUpdate(“INSERTINTOMusteri(ad,soyad)VALUES(‘Erkut’,‘Kutlar’)”);

16 staInsert.executeUpdate(“INSERTINTOMusteri(ad,soyad)VALUES(‘Hasan’,‘Polat’)”);

17 staInsert.executeUpdate(“INSERTINTOUrun(urunAdi,fiyat)VALUES(‘1GBRam’,40)”);

18 staInsert.executeUpdate(“INSERTINTOUrun(urunAdi,fiyat)VALUES(‘3GHzCPU’,80)”);

19 staInsert.executeUpdate(“INSERTINTOUrun(urunAdi,fiyat)VALUES(‘2GBUSBBellek’,30)”);

20 staInsert.executeUpdate(“INSERTINTOUrun(urunAdi, fiyat) VALUES (‘256 MB Ekran Kartı’, 20)”);

21 staInsert.executeUpdate(“INSERTINTOUrun(urunAdi,fiyat)VALUES(‘DVDWriter’,45)”);

22 staInsert.close();

23 }

24 catch(Exceptione)

25 {

26 System.out.println(e.getLocalizedMessage());

27 }

28 }

29}

Kodun açıklaması: JDBC sürücüsü çalışma zamanında bulunduktan sonra daha önce oluştu-rulan AlisverisSitesi isimli ODBC kaynağı aracılığıyla AlisverisSitesi veritabanı üzerinde insert�ifadeleri çalıştırıldı. Statement nesnesinin işi bittikten sonra kapatılması, alınan sistem ve verita-banı kaynaklarının geri verilmesini sağlar. Uygulamanın çalışması aşamasında bir hata oluşmaz-sa arayüz üzerinde herhangi bir mesaj oluşmaz. Gerçek bir uygulamada ürün ve müşteri bilgileri Java kodunun içinde girilmez, web veya işletim sistemi ortamında çalışan bir kullanıcı arayüzü aracılığıyla kullanıcıdan alınır. İlerleyen sayfalarda, Swing görsel programlama kütüphanesini kul-lanarak benzer bir uygulama geliştireceğiz.

Veri Sorgulama Komutları (Select)Select komutunun Java ortamından veritabanı sunucusu üzerinde çalıştırılması için benzer nes-neler oluşturulur. İşletim sistemi üzerinde bulunan JDBC sürücüsüne ulaşıldıktan sonra ODBC kaynağına bağlanılır, bu bağlantı üzerinden Statement nesnesi oluşturulur ve Statement nesne-sinin executeXxx komutlarından biri çalıştırılır. Veritabanından tek bir tam sayı değişkeni yerine birden fazla satır ve sütündan oluşabilen bir değer kümesi döndüğünden, select ifadelerinin çalıştırılması insert, update, delete ifadelerinin çalıştırılmasından farklıdır. executeXxx ko-mutları select ifadelerini veritabanına göndermek için kullanıldığında geriye bir sonuç kümesi (result set) döndürür. Bu sonuç kümesi veri kaynağına bağlı olarak çalışan tek yönlü bir işaretçi

110 Bölüm 7

Page 117: Bilge adam java.pdf

yapısıdır ve ADO.Net yapısında bulunan xxxDataReader sınıflarının Java ortamındaki karşılı-ğıdır. Sonuç kümesi alındıktan sonra kümenin sonuna gelene kadar okuma işlemi tekrar edilir ve bu işlem döngüler aracılığıyla gerçekleştirilir.

AlisverisSitesi veritabanında bulunan Urun tablosundaki verileri okuyalım:

Örnek Uygulama 7.4:

1importjava.sql.Connection;

2importjava.sql.DriverManager;

3importjava.sql.ResultSet;

4 import java.sql.SQLException;

5importjava.sql.Statement;

6publicclassUrunler

7{

8 publicstaticvoidmain(String[]args)throwsClassNotFoundException, SQLException

9 {

10 try

11 {

12 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

13 ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

14 StatementstaSelect=dbConnection.createStatement();

15 ResultSetresultSet=staSelect.executeQuery(“SELECT urunID, urunAdi, fiyat FROM Urun”);

16 while(resultSet.next())

17 {

18 System.out.print(resultSet.getInt(“urunID”));

19 System.out.print(“\t”+resultSet.getString(“urunAdi”)+“\t\t”);

20 System.out.println(resultSet.getDouble(“fiyat”));

21 }

22 staSelect.close();

23 }

catch(Exceptione)

{

System.out.println(e.getLocalizedMessage()); }}

}

Kodun açıklaması: Daha önceki uygulamada yaptığımız gibi JDBC sürücüsünü bulduktan sonra ODBC veri kaynağına bağlantıyı kurduk ve bağlantı üzerinden Statement nesnesini oluşturduk. executeUpdate() metodu yerine executeQuery() metodunu yazdığımızda geri dönüş ti-pinin ResultSet olduğunu görürür. Bu durum, veritabanı sunucusu üzerinde çalışan ifadenin bir değer kümesi döndürebileceğini gösterir. executeQuery metoduna parametre olarak “SELECT

111JDBC

Page 118: Bilge adam java.pdf

urunID, urunAdi, fiyat from Urun” şeklindeki SQL ifadesini yazdığımızdan dolayı exe-cuteQuery metodu Urun tablosundaki bütün verileri sorgulayarak ResultSet cinsinden bir nesne oluşturur ve bu nesnenin veri kaynağına doğrudan bağlı olmasını sağlar. Bu noktadan sonra veri kaynağına bağlı durumda olan ResultSet nesnesi ile veriler üzerine tek yönlü ve salt okunur bir biçimde gezebilirir.

Uygulama çalıştığı zaman Örnek Uygulama 7.5’teki gibi bir çıktı alınır:

Örnek Uygulama 7.5:

11GBRam 40.0

23GHzCPU 80.0

32GBUSBBellek 30.0

4256MBEkranKarti 20.0

5DVDWriter 45.0

Parametreli SQL İfadelerinin ÇalıştırılmasıJDBC kütüphanesi komutlarını kullanarak parametreli SQL ifadeleri de çalıştırılabilir. ADO.Net kütüphanesi kullanılarak çalıştırılan SQL sorgularında “@” karakteri ile başlayan parametrelerin tanımlanması gibi JDBC mimarisinde “?” karakteri ile parametreler oluşturulur. ADO.Net’te oldu-ğu gibi parametre adının belirtilmesine gerek yoktur, parametreler sırayla eklenirse sorgu doğru şekilde çalışır. Parametresiz SQL ifadelerinin çalıştırılması için Statement nesnesi kullanılmasına karşın parametreli SQL ifadelerinin çalıştırılması için PreparedStatement nesnesi kullanılır. Daha önce bahsettiğimiz gibi veritabanına gönderilen ve sorguların sınırlandırılmasını sağlayan veriler kullanıcı arayüzünden alınabilir. Kullanıcı tarafından veri girişinin yapıldığı durumlarda kötü niyetli kullanıcıların sisteme zarar vermesini engellemek için parametrik sorguların oluştulması gerekir.

Bir SQL ifadesinin parametreli olarak Java ortamında çalıştırılmasını ve sorgu sonucunda dönen değer kümesinin ekranda gösterilmesini sağlayan kod Örnek Uygulama-7.6’da gösterilmiştir.

Örnek Uygulama 7.6:

1importjava.sql.Connection;

2importjava.sql.DriverManager;

3importjava.sql.PreparedStatement;

4importjava.sql.ResultSet;

5 import java.sql.SQLException;

6publicclassParametreliSqlSorgusu

7{

8publicstaticvoidmain(String[]args)throwsClassNotFoundException, SQLException

9{

9Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

10ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

11PreparedStatementstatement=dbConnection.prepareStatement(“SELECT * FROM Urun WHERE fiyat > ? AND fiyat < ?”);

12statement.setDouble(1,20);

13statement.setDouble(2,60);

112 Bölüm 7

Page 119: Bilge adam java.pdf

14 ResultSet resultSet = statement.executeQuery();

15while(resultSet.next())

16{

17System.out.println(resultSet.getInt(“urunID”)+““+resultSet.getString(“urunAdi”)+““+resultSet.getDouble(“fiyat”));

18}

19statement.close();

20}

21}

Kodun Açıklaması: Select ifadesi iki tane parametre ile sınırlandırılarak belirli bir fiyat aralı-ğındaki ürünlerin getirilmesi sağlanmıştır. PreparedStatement nesnesi, Connection nesnesi tarafından oluşturulur. Select ifadesinin içinde bulunan “?” karakterleri parametrelerin bulunaca-ğı yerlerdir ve bu parametre değerleri PreparedStatement nesnesinin setXxx metodları ile verilir. Örneğimizde iki tane fiyat parametresine değer vermek amacıyla PreparedStatement�nesnesinin setDouble metodunu kullandık. setXxx metodlarının ilk parametresi, veritabanına gönderilecek sorgunun içinde bulunan parametresinin indeksini belirtir. “SELECT * FROM Urun WHERE fiyat > ? AND fiyat < ?” sorgusunda ilk parametre değerini 20, ikinci parametre değerini 60 olarak verdik. Bu aşamadan sonra, parametresiz ifadelerin çalıştırılmasında yaptı-ğımız gibi PreparedStatement nesnesinin executeXxx metodlarından birini çalıştırarak ça-lıştırılacak ifadeyi veritabanı sunucusuna göndeririz. Örnekte Select ifadesi kullandığımız için, dönen veri kümesini ResultSet nesnesi aracılığıyla aldık ve ekrana bastık. Uygulama çalıştırıldı-ğında oluşan ekran çıktısı Örnek Uygulama 7.7’deki gibidir:

Örnek Uygulama 7.7:

11GBRam40.0

32GBUSBBellek30.0

5DVDWriter45.0

Stored Procedure’lerin ÇalıştırılmasıStored procedure’ler veritabanı sunucuları üzerinde bulunan ve farklı veritabanı yönetim sistemi yazılımlarında farklı biçimlerde oluşturulan prosedürel programlama yapılarıdır. Genelde iş man-tığının bir bölümünün uygulamadan alınıp veritabanı sunucusuna aktarılması amacıyla kullanılır-lar. Stored procedure yapıları parametre kullanılarak çalıştırıldığı için ve yetkilendirme seviyeleri veritabanı tablolarından farklı olarak ayarlanabildiği için uygulama güvenliğinin arttırılmasını da sağlar. JDBC kütüphanesi ile stored procedure’leri çalıştırmak için Connection nesnesi üzerinden bir CallableStatement nesnesi oluşturulur.

Örnek veritabanımızda bulunan ürün ve müşteri tablolarına veri eklemek amacıyla kullanmak için iki tane stored procedure oluşturalım.

Örnek Uygulama 7.8:

1CREATEPROCinsUrun

2@urunAdiVARCHAR(20),

3@fiyatMONEY

4AS

5INSERTINTOUrun(urunAdi,fiyat)

6VALUES(@urunAdi,@fiyat)

7GO

113JDBC

Page 120: Bilge adam java.pdf

8CREATEPROCinsMusteri

9@adVARCHAR(20),

10@soyadVARCHAR(30)

11AS

12INSERTINTOMusteri(ad,soyad)

13VALUES(@ad,@soyad)

14GO

Örnek Uygulama 7.8’de verdiğimiz SQL ifadeleri ile oluşturulan stored procedure’leri çalıştırmak için aşağıdaki gibi bir Java uygulaması oluşturabiliriz.

Örnek Uygulama 7.9:

1importjava.sql.CallableStatement;

2importjava.sql.Connection;

3importjava.sql.DriverManager;

4 import java.sql.SQLException;

5publicclassStoredProcedure

6{

7 publicstaticvoidmain(String[]args)throwsClassNotFoundException, SQLException

8 {

9 try

10 {

11 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

12 ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

13 CallableStatementstaInsertUrun=dbConnection.prepareCall(“{call insUrun(?, ?)}”);

14 staInsertUrun.setString(1,“ToshibaM70Notebook”);

15 staInsertUrun.setDouble(2,1200);

16 introwCount=staInsertUrun.executeUpdate();

17 if(rowCount==0)

18 {

19 System.out.println(“Ürüneklenemedi”);

20 }

21 else

22 {

23 System.out.println(“Ürüneklendi”);

24 }

25 CallableStatementstaInsertMusteri=dbConnection.prepareCall(“{call insMusteri(?, ?)}”);

26 staInsertMusteri.setString(1,“Ahmet”);

27 staInsertMusteri.setString(2,“Balaban”);

28 rowCount=staInsertUrun.executeUpdate();

29 if(rowCount==0)

114 Bölüm 7

Page 121: Bilge adam java.pdf

30 {

31 System.out.println(“Müşteri eklenemedi”);

32 }

33 else

34 {

35 System.out.println(“Müşteri eklendi”);

36 }

37 staInsertUrun.close();

38 staInsertMusteri.close();

39 }

40 catch(Exception e)

41 {

42 System.out.println(e.getMessage());

43 }

44 }

45 }

Kodun Açıklaması: Veritabanı bağlantısının sağlanması için gereken ayarları yaptıktan sonra stored procedure çalıştırmak için Connection nesnesi üzerinden iki tane CallableState-ment nesnesi oluşturduk. Bu nesnelerden biri insUrun stored procedure’ünün çalıştırılması için, diğeri insMusteri stored procedure’ünün çalıştırılması için gerekli. Stored procedure çağrısının yapılması için “{call sp_name(?, ..)}” ifadesi kullanılır. Bu ifadede sp_name metni yerine çalıştırılacak stored procedure’ün adı yazılır. Stored procedure’ü çalıştırmak için gereken para-metreler daha önce yaptığımız gibi Statement nesnelerinin setXxx metodları kullanılarak verilir. insMusteri prosedürünü çalıştırmak için müşterinin ad ve soyad değerlerini, insUrun prose-dürünü çalıştırmak için ürünün ad ve fiyat değerlerini parametre olarak verdikten sonra ifadeleri executeUpdate metodu ile çalıştırdık ve etkilenen kayıt sayısını kontrol ederek ürün ve müşteri verilerinin veritabanına eklenip eklenmediği bilgisini ekrana bastık. Uygulama çalıştırıldığı zaman Örnek Uygulama 7.10’da olduğu gibi bir çıktı alınırsa ürün ve müşteri bilgilerini başarıyla ekledik demektir.

Örnek Uygulama 7.10:

1Ürüneklendi

2 Müşteri eklendi

Veritabanı Erişimi için Bileşen Oluşturulması:Veritabanı sunucuları üzerinde çalıştırılacak metodlar merkezi bir package altında toplanırsa, veritabanı sunucusu üzerinde herhangi bir değişiklik olması durumunda karşılaşılacak bakım maliyeti düşürülebilir. Bunun yanında uygulamanın geliştirilmesi aşamasında veritabanı konfigü-rasyonu ve çeşitli komutların veritabanı sunucusu üzerinde çalıştırılması daha kolay bir şekilde gerçekleştirilebilir. Bu amaçla kullanılabilecek temel bir veri erişim bileşeni oluşturalım.

115JDBC

Page 122: Bilge adam java.pdf

Şimdiye kadar kullandığımız veritabanı erişim yöntemlerini bir sınıf altında toplayabiliriz. Oluştura-cağımız bileşenin farklı veritabanı tabloları ile kullanılabilmesi ve geri dönüş değerlerini temel veri tipleri şeklinde döndürebilmesi gerekir. Alt yapıda kullanılan veritabanı sunucusunun değişmesi riskinin olduğu senaryolarda, veritabanı sistemine bağımlı olmayan veri tiplerinin kullanılması bü-yük avantaj sağlayacaktır.

Veri erişim bileşeninin kodu aşağıda verilmiştir. Bileşen ayrı bir Java paketi (package) şeklinde oluşturulmuştur ve bu bileşeni başka bir yerde kullanmak için import anahtar kelimesi ile uygula-maya eklemek gerekir.

Örnek Uygulama 7.11:

1packagedbAccess;

2importjava.sql.Connection;

3importjava.sql.DriverManager;

4importjava.sql.PreparedStatement;

5importjava.sql.ResultSet;

6importjava.sql.ResultSetMetaData;

7 import java.sql.SQLException;

8importjava.sql.Statement;

9importjava.util.ArrayList;

10publicclassDbConnection

11{

12 privateConnectionconnection;

13 public DbConnection() throws SQLException, ClassNotFoundException

14 {

15 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

16 connection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

17 }

18 public int NonQuery(String commandText) throws SQLException

19 {

20 Statement stNonQuery = connection.createStatement();

21 int rowCount = stNonQuery.executeUpdate(commandText);

22 stNonQuery.close();

23 returnrowCount;

24 }

25 public int NonQuery(String commandText, Object[] parameterValues) throws SQLException

26 {

27 PreparedStatement pstNonQuery = connection.prepareStatement(commandText);

28 for(intparameterIndex=0;parameterIndex<parameterValues.length;parameterIndex++)

29 {

116 Bölüm 7

Page 123: Bilge adam java.pdf

30 pstNonQuery.setObject(parameterIndex + 1, parameterValues[parameterIndex]);

31 }

32 int rowCount = pstNonQuery.executeUpdate();

33 pstNonQuery.close();

34 returnrowCount;

35 }

36 publicArrayListReturnArrayList(StringcommandText)throws SQLException

37 {

38 ArrayListresult=newArrayList();

39 Statement stQuery = connection.createStatement();

40 ResultSet resultSet = stQuery.executeQuery(commandText);

41 ResultSetMetaDatametaData=resultSet.getMetaData();

42 intcolumnCount=metaData.getColumnCount();

43 while(resultSet.next())

44 {

45 String[]row=newString[columnCount];

46 for(intcolumnIndex=0;columnIndex<columnCount;columnIndex++)

47 {

48 row[columnIndex]=resultSet.getString(columnIndex+1).toString();

49 }

50 result.add(row);

51 }

52 stQuery.close();

53 returnresult;

54 }

55 publicArrayListReturnArrayList(StringcommandText,Object[] parameterValues) throws SQLException

56 {

57 ArrayListresult=newArrayList();

58 PreparedStatement pstQuery = connection.prepareStatement(commandText);

59 for(intparameterIndex=0;parameterIndex<parameterValues.length;parameterIndex++)

60 {

61 pstQuery.setObject(parameterIndex + 1, parameterValues[parameterIndex]);

62 }

63 ResultSet resultSet = pstQuery.executeQuery();

64 ResultSetMetaDatametaData=resultSet.getMetaData();

117JDBC

Page 124: Bilge adam java.pdf

65 intcolumnCount=metaData.getColumnCount();

66 while(resultSet.next())

67 {

68 String[]row=newString[columnCount];

69 for(intcolumnIndex=0;columnIndex<columnCount;columnIndex++)

70 {

71 row[columnIndex]=resultSet.getString(columnIndex+1).toString();

71 }

72 result.add(row);

73 }

74 pstQuery.close();

75 returnresult;

76 }

77}

Kodun açıklaması: Veri erişim mantığını uygulamadan ayırmak için dbAccess isimli bir packa-ge içinde DbConnection isimli bir sınıf oluşturduk. Geri dönüşsüz sorguları çalıştırmak için iki tane metod ve değer kümesi döndüren sorguları çalıştırmak için iki tane metod yazdık. İki işlev için de ikişer tane metod yazmamızın sebebi SQL ifadelerini çalıştırırken parametre eklenmesine olan sağlamaktır. Sınıfta bulunan nitelikleri ve metodları kısaca açıklayalım:

Connectionconnection: Veritabanına bağlanmak amacıyla kullanılan nesne. Bütün State-ment nesneleri Connection nesnesi tarafından oluşturulur.

DbConnection():�DbConnection sınıfının yapıcı metodu. JDBC sürücüsünü bulmak ve Con-nection nesnesine ilk değerini vermek için kullanılır.

int NonQuery(String commandText): Parametresiz ve veri kümesi döndürmeyen SQL ifa-delerinin çalıştırılması amacıyla kullanılır. commandText parametresi ile, çalıştırılacak olan SQL ifadesi alınır. Statement nesnesi oluşturulduktan sonra executeUpdate komutu çalıştırılacak işlemden etkilenen kayıt sayısı veritabanı sunucusundan alınır ve döndürülür.

int NonQuery(String commandText, Object[] parameterValues): Veritabanı üze-rinde çalıştırılacak olan SQL ifadesi commandText parametresi ile, sorgunun içinde bulunan parametrelerin değerleri Object dizisi cinsinden parameterValues parametresiyle alınır. Con-nection nesnesi üzerinden PreparedStatement nesnesi oluşturulduktan sonra parameter-Values dizisinin eleman sayısı kadar parametre setValue(Object) metodu ile PreparedS-tatement nesnesine eklenir . SQL ifadesi çalıştırıldıktan sonra veritabanında etkilenen kayıt sayısı geri döndürülür.

ArrayListReturnArrayList(StringcommandText): Veritabanı üzerine çalıştırılan Se-lect ifadesinin sonucunda dönen değer kümesi ResultSet nesnesi üzerinden alınır. ResultSet-MetaData nesnesi, veritabanından dönen sonuç kümesinin sütun sayını almak için kullanılır. Veritabanından dönen değerleri uygulamaya göndermek için ArrayList nesnesi kullanılmıştır. ArrayList nesnesinin her bir kaydı, veritabanından gelen bir satır veriyi içerir. Bir veri satırını tutmak için String dizisi kullanılmıştır ve String dizisinin eleman sayısı ResultSetMetaDa-ta nesnesinden alınan sütun sayısına göre belirlenir. ResultSet nesnesinin içindeki kayıt sayısı kadar String dizisi oluşturulur ve ArrayList’e eklenir. resultSet.getString() metodu columnIndex+1 parametresiyle çalıştırılır. Bunun sebebi, .Net ortamından farklı olarak para-metre ve sütun indekslerinin 1 değerinden başlamasıdır.

118 Bölüm 7

Page 125: Bilge adam java.pdf

ArrayList ReturnArrayList(String commandText, Object[] paramaterValu-es): Parametreli select ifadelerinin çalıştırılması için bu metod kullanılır. parameterValues�Object dizisi aracılığıyla select ifadesinin parametre değerleri alınır ve PreparedStatement�nesnesine setObject() metodu yardımıyla eklenir. Bir önceki metod yapısında olduğu gibi ArrayList nesnesi oluşturulur. ArrayList nesnesinin her bir kaydı veritabanından gelen bir satırı tutan String dizisinden oluşur.

Örnek Uygulama 7.12:

1 import java.sql.SQLException;

2importjava.util.ArrayList;

3importdbAccess.DbConnection;

4publicclassVeriErisimi

5{

6 publicstaticvoidmain(String[]args)throwsClassNotFoundException, SQLException

7 {

8 DbConnectionconnection=newDbConnection();

9 // Yeni bir ürün veritabanına kaydediliyor

10 int rowCount = connection.NonQuery(“INSERT INTO Urun (urunAdi, fiyat) VALUES (‘HP 870cxi Yazıcı’, ‘70’)”);

11 if(rowCount!=0)

12 {

13 System.out.println(“Ürünkaydedildi”);

14 }

15 else

16 {

17 System.out.println(“Ürünkaydedilemedi”);

18 }

19 // Yeni bir müşteri veritabanına kaydediliyor

20 Object[]musteriInsertParameters=newObject[2];

21 musteriInsertParameters[0]=“Veli”;

22 musteriInsertParameters[1]=“Karaman”;

23 rowCount = connection.NonQuery(“INSERT INTO Musteri (ad, soyad) VALUES (?, ?)”, musteriInsertParameters);

24 if(rowCount!=0)

25 {

26 System.out.println(“Müşteri kaydedildi”);

27 }

28 else

29 {

30 System.out.println(“Müşteri kaydedilemedi”);

31 }

32 System.out.println();

33 // Veritabanından belirli bir fiyat aralığındaki ürün bilgileri çekilip ekrana basıldı

34 Object[]urunSelectParameters=newObject[2];

119JDBC

Page 126: Bilge adam java.pdf

35 urunSelectParameters[0]=30;

36 urunSelectParameters[1]=60;

37 ArrayListarrUrun=connection.ReturnArrayList(“SELECT * FROM Urun WHERE Fiyat BETWEEN ? AND ?”, urunSelectParameters);

38 for(Objectobject:arrUrun)

39 {

40 String[]urun=(String[])object;

41 for(inti=0;i<urun.length;i++)

42 {

43 System.out.print(urun[i]+“\t”);

44 }

45 System.out.println();

46 }

47 System.out.println();

48 // Veritabanından bütün müşteri bilgileri çekilip ekrana basıldı49 ArrayListarrMusteri=connection.ReturnArrayList(“SELECT*FROMMusteri”);50 for(Objectobject:arrMusteri)51 {52 String[]musteri=(String[])object;53 for(inti=0;i<musteri.length;i++)54 {55 System.out.print(musteri[i]+“\t”);56 }57 System.out.println();58 }

59 }

60}

Uygulamada; müşteri kaydı eklenmesi için parametreli NonQuery metodu, ürün kaydı eklen-mesi için parametresiz NonQuery metodu, belirli bir fiyat aralığındaki ürünlerin çekilmesi için parametreli ReturnArrayList metodu, bütün müşteri bilgilerinin çekilmesi için parametresiz ReturnArrayList metodu kullanılmıştır. Uygulama çalıştırıldığında aşağıdaki gibi bir ekran çıktısı alınır.

Örnek Uygulama 7.13:

Ürünkaydedildi

Müşteri kaydedildi

11GBRam 40.0000

22GBUSBBellek 30.0000

3DVDWriter 45.0000

1 Yalçin Kaya 2Erkut Kutlar3Hasan Polat4Veli Karaman

120 Bölüm 7

Page 127: Bilge adam java.pdf

8 JSP

Page 128: Bilge adam java.pdf

8 JSPJSP Teknolojisinde Kullanılan Etiketler

JSP Direktifleri

JSP Script Etiketleri

Form Verilerinin Kullanılması

Durum Yönetimi

Page 129: Bilge adam java.pdf

JSPJava platformunu kullanarak web uygulamaları geliştirmek için JSP (Java Server Pages) tekno-lojisi kullanılır. JSP, .Net ortamının web geliştirme teknolojisi olan ASP.Net mimarisinin Java or-tamındaki karşılığıdır. ASP.Net uygulamaları geliştirirken kullanılan code-behind mimarisini JSP ortamında doğrudan bir karşılığı olmadığından Java kodları ile HTML kodları aynı sayfanın içinde bulunur. JSP uygulamalarında iş mantığını web sayfalarından ayırmak ve uygulamaları bileşen-lere bölmek için Java tabanlı Servlet mimarisi kullanılılır. Bu bölümde JSP uygulaması geliştirme ve Servlet bileşenleri oluşturmayı öğreneceğiz.

JSP uygulamalarını ve Servlet bileşenlerini çalıştırmak için aşağıdaki adresten Apache Tomcat sunucusunun işletim sisteminize uygun olan versiyonunu indirebilirsiniz. http://tomcat.apache.org/download-60.cgi

http://apache.karegen.com/tomcat/tomcat-6/v6.0.14/bin/apache-tomcat-6.0.14.exe

Windows binary formatında indirilen Tomcat sunucusunun kurulumu aşağıda adım adım göste-rilmiştir.

Kurulum standart Windows uygulaması kurulum biçimindedir.

Uygulamayı kurmadan önce sözleşmenin kabul edilmesi gerekir.

Page 130: Bilge adam java.pdf

Examples seçeneği işaretlenirse JSP ve Servlet bileşenleriyle ilgili örnek uygulamalar yerel ağ üzerinde çalıştırılabilir.

Kurulum için standart dizinden farklı bir dizin de seçilebilir. Uygulamalarda kullanılan Tomcat, standart dizine kurulmuştur.

Kurulumun bu aşamasında Tomcat sunucusunun çalışacağı port numarasının belirlenir ve admin kullanıcısı için şifre oluşturulur. Bilgisayarınızın 8080 numaralı portunu kullanan başka bir uygu-lama yoksa Tomcat sunucusunun 8080 portunu kullanmasını sağlayabilirsiniz. Uygulamalarda kullanılan Tomcat sunucusu 8080 portu üzerinde çalışmaktadır. Admin kullanıcısının şifresinin boş bırakılması genel olarak tavsiye edilmez. Özellikle üzerinde aktif bir biçimde kullanılan uy-gulamalar çalışan bir sunucunun admin şifresinin boş olması uygulamalarda ve sistemde ciddi güvenlik açıklarına neden olur.

124 Bölüm 8

Page 131: Bilge adam java.pdf

Tomcat sunucusu çalışmak Java platformunun 5.0 sürümüne ihtiyaç duyduğundan JRE 5.0 uy-gulamasının yeri belirtilmelidir. Java motoru standart olarak kurulmuşsa bu dizin otomatik olarak belirlenir, aksi takdirde bilgisayar üzerindeki yerinin manuel olarak belirtilmesi gerekir.

Tomcat sunucusunun kurulumu tamamlandı. “Run Apache Tomcat” seçeneği işaretli olarak bıra-kırsa Tomcat sunucusuna ait Windows servisi çalışır.

125JSP

Page 132: Bilge adam java.pdf

Tomcat kurulumu başarılı olduysa ve ilişkili Windows servisi çalıştırıldıysa bilgisayarın sağ alt köşesinde Tomcat’e ait ikon belirir. Tomcat Windows servisi ile ilgili ayarlar bu ikona çift tık-landıktan sonra çıkan pencerede yapılabilir. Tomcat Windows servisi varsayılan olarak manuel çalıştırılacak şekilde ayarlanır. İşletim sisteminin her açılışında Tomcat servisinin otomatik olarak başlaması için servisin Şekil 8’deki gibi ayarlanması gerekir.

Tomcat servisinin bilgisayarın her açılışında otomatik olarak çalışması için “Startup Type” seçe-neği “Automatic” olarak değiştirilir.

Tomcat sunucusunun kurulumu sırasında farklı bir dizin belirtmediyseniz C:\Program Files\Apa-che Software Foundation\Tomcat 6.0 dizinine kurulacaktır. Bu dizinin altındaki webapps dizininin altında bulunan ROOT dizini JSP uygulamalarının barındırıldığı standart dizindir. Tomcat konfigü-rasyonunu değiştirmek için Tomcat ana dizininin altındaki conf dizininde bulunan konfigürasyon dosyaları kullanılabilir.

Webapps dizininin altında bulunan ROOT dizininin içinde yeni bir dizin oluşturalım ve adını Il-kOrnek olarak değiştirelim. Tomcat sunucumuza http://localhost:8080 adresinden, IlkOrnek adı-nı verdiğimiz web uygulamamıza ise http://localhost:8080/IlkOrnek adresi üzerinden ulaşabiliriz. Uygulamamız henüz bir JSP sayfasına sahip olmadığı için web tarayacısı üzerinden bu adrese ulaşmaya çalışırsak hata mesajı alırız.

Notepad veya benzer bir metin editörü kullanarak IlkOrnek dizininin içinde boş bir metin dosyası oluşturalım ve adını ilkornek.jsp olarak değiştirelim. Dosyanın uzantısının .jsp olması gerektiğini unutmamalıyız. Örnek Uygulama 8.1’deki kod bloğunu bu dosyanın içine yazarak dosyayı kay-dedelim.

Örnek Uygulama 8.1:

1<%

2out.println(“IlkOrnek”);

3%>

Tomcat kurulumu başarılı bir şekilde tamamlandıysa web tarayıcısının adres kısmına http://lo-calhost:8080/IlkOrnek/ilkornek.jsp yazıp enter tuşuna bastığımızda Şekil-9’daki gibi bir sayfanın açılması gerekir.

126 Bölüm 8

Page 133: Bilge adam java.pdf

Erişmeye çalıştığımız JSP sayfasının adının küçük-büyük harf duyarlı olduğuna dikkat edelim. http://localhost:8080/IlkOrnek/ilkornek.jsp sayfası yerine http://localhost:8080/IlkOrnek/IlkOrnek.jsp sayfasına ulaşmaya çalışırsak Şekil 10’daki gibi bir hata mesajı alırız.

Oluşturduğumuz JSP sayfasının koduna bir göz atarsak <%�ve�%> etiketlerini görürüz. Bu etiket-lerin arasına yazdığımız bütün kod blokları Java kodu olarak yorumlanır JSP script’leri yazmak için kullanılır. İşletim sistemi üzerinde çalışan Java uygulamalarında kullanılan System.out.println() komutu JSP ortamında out.println() şeklini alır ve istemciye (client) metin çık-tısı vermek için kullanılır.

ROOT dizininin altında JspOrnekleri adında bir dizin oluşturalım ve bundan sonraki örnekleri bu dizinin içine kaydedelim.

Java dilinde standart olarak bulunan komutlar JSP sayfaları oluşturulurken de kullanılır. Az önce yazdığımız metni beş defa yazan bir programı for döngüsü kullanarak oluşturalım. Dongu.jsp adında bir jsp sayfasını Notepad kullanarak JspOrnekleri dizinine kaydedelim. Dongu.jsp sayfa-sını oluşturmak için kullanılan kod aşağıdaki gibidir.

Örnek Uygulama 8.2:

1<%

2 for(inti=0;i<5;i++)

3 out.println(“IlkOrnek<br>”);

4%>

Kodu incelersek, JSP sayfalarında Java ve HTML kodlarının bir arada bulunaibildiğini görürüz. out.println() komutunun sonunda kullandığımız <br> etiketi çıktının bir alt satıra geçmesini

Şekil 9

Şekil 10: Küçük-büyük harf duyarlılığından kaynaklanan sayfa bulunamadı hatası.

127JSP

Page 134: Bilge adam java.pdf

sağlar ve standart HTML etiketlerindendir. Döngü yapısının Java dilinin standart for döngüsü olduğunu görüyoruz.

http://localhost:8080/JspOrnekleri/Dongu.jsp adresi üzerinden sayfayı çalıştırdığımızda Şekil 11’deki gibi bir görünüm elde ederiz.

JSP ortamı; ASP, PHP, ASP.Net, vb. teknolojileri gibi sunucu tarafında çalışır. Bunun anlamı, JSP kodunun sunucunun üzerinde çalışması ve istemci tarafında HTML kodunun gönderilmesi-dir. JSP sayfalarına http://Adres/SayfaAdi.jsp şeklinde ulaşılsa da istemci üzerinde çalışan web tarayıcısına saf HTML ve gerekirse Javascript kodu gelir. Web ortamında çalışan bütün sunucu tabanlı teknolojilerin web tarayıcıları tarafından yorumlanabilmesinin sebebi de budur. Dongu.jsp sayfasına sağ tıkladığımızda karşımıza çıkan menüden “view source” komutunu çalıştırırsak bahsedilen özellik daha iyi anlaşılır. İstemci tarafına gelen HTML kodu aşağıdaki gibidir.

Ilk Ornek<br>

Ilk Ornek<br>

Ilk Ornek<br>

Ilk Ornek<br>

Ilk Ornek<br>

Karşımıza çıkan HTML kodunda aynı ifade beş kere yazılmıştır ve ifadeler arasında bulunan <br> etiketinden dolayı çıktı beş satır halinde görünmektedir. Sunucu tarafında çalışan JSP sayfası üzerinde kullanılan döngü ve “<%”, “%>” etiketleri istemci tarafında görünmez.

JSP Teknolojisinde Kullanılan EtiketlerJSP DirektifleriJSP sayfalarının özelliklerini değiştirmek amacıyla kullanılan yapılardır ve başlarında “@” karak-teri bulunur. JSP direktifleri istemciye çıktı göndermez. En çok “Page” direktifi kullanılır. Page direktifi ile sayfanın script dili, durum yönetimi, buffer gibi özellikleri ile ilgili ayarlar yapılır, harici kütüphanelerin sayfa tarafından kullanılması sağlanır. Örneğin;

<%@ page session=”true” import=”java.util.*” %> direktifi ile sayfada durum yö-netimi etkin hale getirilir ve java.util paketinin içisnde bulunan bileşenler sayfaya eklenerek bu pakette bulunan sınıfların sayfa tarafından kullanılması sağlanır. session=”true” yazmasak bile varsayılan olarak sayfanın session desteği açıktır, kapatmak için session=”false” yaz-mamız gerekir.

Şekil 11: Döngü kullanımı.

128 Bölüm 8

Page 135: Bilge adam java.pdf

JSP Script EtiketleriScript etiketleri, JSP sayfalarında asıl işi yapan etiketlerdir. Sayfada bulunacak Java kodları script etiketleri içine yazılır, sunucu bu etiketler içinde bulunan kodları Java kodu olarak algılar. JSP’de üç çeşit script etiketi bulunur.

Tanımlama etiketleri: Java değişkenlerini tanımlamak için kullanılır ve <%! ... %> şeklinde oluşturulur.

Scriptlet etiketleri: Java ifadelerinden oluşan kod parçalarını çalıştırmak için kullanılır ve <% ... %> şeklinde oluşturulur.

İfade etiketleri: Bütün Java ifadelerini çalıştırmak için kullanılır ve <%= ... %> şeklinde oluştu-rulur.

Bu etiketlerin dışında, JSP sayfaları içinde yorum satırı oluşturmak için <%-- ... --% etiketi kullanılır.

Form Verilerinin KullanılmasıJSP uygulamalarında sayfalar arasında veri taşımak için HTML standartlarının içinde bulunan POST veya GET metodları kullanılabilir. Herhangi bir HTML veya JSP sayfasının içinde oluştu-rulan form alanının içinde bulunan kontrollerin verileri GET veya POST işlemi sırasında üzerinde çalışılan sayfaya veya farklı bir sayfaya gönderilir. Basit bir HTML sayfasından bir JSP sayfasına POST metodu aracılığıyla verilerin gönderilmesi işlemi aşağıdaki gibi yapılabilir.

FormOrnegi.html sayfasını oluşturan HTML kodu aşağıdaki gibidir.

1<html>

2<body>

3 <formmethod=”post”action=”FormData.jsp”>

4 <table>

5 <tr>

6 <td>Ad:</td>

7 <td><inputtype=”text”name=”txtAd”/></td>

8 </tr>

9 <tr>

10 <td>Soyad:</td>

11 <td><inputtype=”text”name=”txtSoyad”/></td>

12 </tr>

13 <tr>

14 <td><inputtype=”submit”name=”btnGonder”value=”Gonder”/><td>

15 </tr>

16 </table>

17 </form>

18 </body>

19 </html>

HTML sayfasında, <body> etiketinin içinde bir form oluşturduk ve POST metodunu kullanaca-ğımızı belirttik. Formun içine eklenen “submit” butonunun tetiklenmesi sonrasında form verileri

129JSP

Page 136: Bilge adam java.pdf

FormData.jsp sayfasına gönderilir. Bu işlem action=”FormData.jsp” satırıyla gerçeklenir. Kullanı-cının ad ve soyad değerlerini girmesi forma iki tane “text” tipinden input ekledik. Kontrollerin ara-yüz üzerinde düzgün bir şekilde görüntülenmesi için standart HTML yapılarından biri olan <table> etiketini kullandık. HTML sayfası aşağıdaki gibi görünür.

Kullanıcı tarafından veri girişi yapıldıktan sonra Gönder butonuna tıklandığında form verileri FormData.jsp sayfasına gönderilir. FormData.jsp adında bir JSP sayfası oluşturarak gönderilen verileri alıp işleyebiliriz.

1<%@pageimport=”java.util.*”%>

2<%

3 out.print(“Ad:”+request.getParameter(“txtAd”));

4 out.print(“<br>Soyad:”+request.getParameter(“txtSoyad”));

5%>

Request.getParameter metodu, herhangi bir form üzerinden FormData.jsp sayfasına gönderilen verileri almak için kullanılır. txtAd ve txtSoyad anahtarları, FormOrnegi.html sayfasında bulunan text türünden veri giriş elemanlarının isim (name) değeridir. Gönder butonuna tıklandıktan sonra FormData.jsp sayfası yüklenir ve aşağıdaki gibi bir görünüm elde edilir.

HTML sayfasında verileri göndermek için POST yerine GET metodunu kullansak da FormData.jsp sayfasından verilere aynı şekilde ulaşabilir. Bu durumda veriler gizli olarak değil URL üzerin-den gönderilecektir. Önemli verilerin GET metodu ile gönderilmesi güvenlik açısından sakıncalı-dır. GET metodu kullanıldığında FormData.jsp sayfası aşağıdaki gibi görünür:

Adres çubuğunda görünen URL değerine dikkat edersek bütün form verilerinin açık bir şekilde ve saf metin formatında aktarıldığını görebiliriz.

Şekil 12

Şekil 13

130 Bölüm 8

Page 137: Bilge adam java.pdf

Durum Yönetimi HTTP protokolü durum özelliğine sahip değildir. Durum mekanizması, bir kullanıcı sisteme bağlı kaldığı sürece verilerinin birden fazla sayfa arasında taşınabilmesine olanak verir. JSP de diğer sunucu tabanlı web teknolojileri gibi kendine özel bir durum yönetimi mekanizmasına sahiptir. JSP’de durum yönetimi session nesnesiyle sağlanır. Session nesnesine request.getSession() metodu aracılığıyla ulaşılır. Basit bir sisteme giriş sayfasıyla kullanıcının bilgilerini session nes-nesine kaydeden ve uygulama içindeki farklı bir sayfadan bu bilgilere ulaşan bir JSP uygulaması yazalım:

1<%---------KullaniciGirisi.jsp---------%>

2<html>

3<body>

4<%

5 out.print(“SessionID:“+session.getId());

6%>

7<formmethod=”post”action=”KullaniciGirisi.jsp”>

8 <table>

9 <tr>

10 <td>Ad:</td>

11 <td><inputtype=”text”name=”txtAd”/></td>

12 </tr>

13 <tr>

14 <td>Sifre:</td>

15 <td><inputtype=”password”name=”txtSifre”/></td>

16 </tr>

17 <tr>

18 <td><inputtype=”submit”name=”btnGonder”value=”Gonder”/><td>

19 </tr>

20 </table>

21 </form>

22 <%

23 Stringad=request.getParameter(“txtAd”);

24 Stringsifre=request.getParameter(“txtSifre”);

25 if(ad!=null&&sifre!=null)

26 {

131JSP

Page 138: Bilge adam java.pdf

27 if(ad.equals(“Yalcin”)&&sifre.equals(“1234”))

28 {

29 session.putValue(“kullaniciAdi”,ad);

30 response.sendRedirect(“SifreDogru.jsp”);

31 }

32 else

33 {

34 out.println(“Kullaniciadiveyasifrehatali”);

35 }

36 }

37 %>

38 </body>

39 </html>

Kullanıcının kullanıcı adı ve şifre bilgilerini girmesi için KullaniciGirisi.jsp adında bir JSP sayfası oluşturduk. Bir önceki örnekten farklı olarak kullanıcıdan gelecek bilgileri HTML sayfası yerine JSP sayfası üzerinden almayı tercih ettik. Bunun sebebi, kullanıcı giriş sayfasında da JSP kullanmayı planlamamız. Sayfanın başında kullandığımız <% out.print(“Session ID: “ + session.getId()); %> komutuyla o anda geçerli olan oturumun ID değerini kullanıcıya gösterdik. Form etiketinin action özelliğinin KullaniciGirisi.jsp sayfasını gösterdiğine dikkat edelim. Kullanıcı bilgilerini aldığımız sayfayla bu bilgilerin geçerliliğini kontrol ettiğimiz sayfa aynı. Form etiketinden sonra kullanıcının girdiği bilgilerin geçerliliğini kontrol etmek için request.getParameter() metodu ile form verilerini aldık. Kullanıcı adı ve şifre bilgilerini sayfanın içinde kontrol ettik; kullanıcı adı olarak “Yalcin”, şifre olark “1234” değerleri girilmişse sisteme giriş yapılabildiğini varsaydık. Gerçek bir uygula-mada kullanıcıdan girilen değerler bir veri kaynağı üzerinden doğrulanır. Eğer kullanıcı sisteme girmeyi başarabilirse kullanıcı adı değeri session nesnesine ekleniyor ve kullanıcı SifreDogru.jsp sayfasına yönlendiriliyor. Sisteme giriş işlemi başarısız olursa “Kullanıcı adı veya şifre hatalı” mesajı veriliyor ve yönlendirme yapılmıyor. KullaniciGirisi.jsp sayfası ilk açıldığında ve şifre yanlış girildiğinde aşağıdaki gibi görünür:

Şifre yanlış girildi. Sayfanın yeniden yüklenmesi sırasında Session nesnesinin ID değerinin de-ğişmediği görülüyor.

Şekil 15: KullaniciGirisi.jsp sayfası ilk defa yüklendi.

132 Bölüm 8

Page 139: Bilge adam java.pdf

Kullanıcı adı ve şifre değerlerinin doğru girilmesi durumunda kullanıcının yönlendirileceği Sifre-Dogru.jsp sayfasının kodu aşağıda verilmiştir:

<%

out.print(“Kullaniciadi:“+session.getValue(“kullaniciAdi”));

out.print(“<br>SessionID:“+session.getId());

%>

Session nesnesine kaydedilmiş olan kullanıcı adı değeri alınıyor ve ekrana basılıyor. Session değişkeninin ID değeri de aynı şekilde ekrana basılıyor.

Kullanıcı SifreDogru.jsp sayfasına yönlendirildiğinde aşağıdaki gibi bir sayfayla karşılaşır:

Kullanıcı adı ve şifre doğru girildi, session nesnesinde bulunan kullanıcı adı değeri ve session ID değeri görüntülendi. Bu sayfadaki session ID değeriyle daha önceki sayfalardaki session ID de-ğerinin aynı olduğunu görüyoruz. Session bilgileri bütün oturum boyunca ve uygulamanın bütün sayfaları arasında geçerli olduğundan ID değeri de aynıdır.

JSP Uygulamalarında JDBC Kullanımı:

JSP uygulamalarının veritabanı sistemleriyle iletişim kurması için Java platformunun JDBC kütüp-hanesi kullanılır. JDBC kütüphanesi kullanarak bir ürün ekleme sayfası oluşturalım.

1<%@pageimport=”java.util.*”%>

2<%@pageimport=”java.sql.Connection”%>

3<%@pageimport=”java.sql.DriverManager”%>

4<%@pageimport=”java.sql.PreparedStatement”%>

5 <%@ page import=”java.sql.SQLException” %>

6

7<html>

8<body>

133JSP

Page 140: Bilge adam java.pdf

9 <formmethod=”post”action=”UrunEkle.jsp”>

10 <table>

11 <tr>

12 <td>Urunadi:</td>

13 <td><inputtype=”text”name=”txtUrunAd”/></td>

14 </tr>

15 <tr>

16 <td>Fiyat:</td>

17 <td><inputtype=”text”name=”txtUrunFiyat”/></td>

18 </tr>

19 <tr>

20 <td><inputtype=”submit”name=”btnUrunKaydet”value=”Kaydet”/><td>

21 </tr>

22 </table>

23 </form>

24 <%

25 StringurunAdi=request.getParameter(“txtUrunAd”);

26 StringurunFiyat=request.getParameter(“txtUrunFiyat”);

27 if(urunAdi!=null&&urunFiyat!=null)

28 {

29 try

30 {

31 doublefiyat=Double.valueOf(urunFiyat);

32 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

33 ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

34 PreparedStatementstatement=dbConnection.prepareStatement(“INSERTINTOUrun(urunAdi,fiyat)VALUES (?, ?)”);

35 statement.setString(1,urunAdi);

36 statement.setDouble(2,fiyat);

37 introwCount=statement.executeUpdate();

38 statement.close();

39 if(rowCount==0)

40 {

41 System.out.println(“Ürünkaydedilemedi”);

42 }

134 Bölüm 8

Page 141: Bilge adam java.pdf

43 }

44 catch(Exceptione)

45 {

46 out.print(“Fiyatalaninasayidegerigirin<br>”);

47 }

48 }

49 %>

50 </body>

51 </html>

Ürün bilgilerini veritabanına kaydetmek için JDBC kütüphanesini kullandık. Veritabanı üzerin-de çalıştırılacak olan sorgunun parametreleri kullanıcıdan alındığından PreparedStatement sınıfı cinsinden bir nesne oluşturarak parametrelerini verdik. Ürün fiyatı alanının cinsi double olması gerektiği için fiyat alanına girilen değeri double’a çevirmeye çalıştık. Uygulamanın akışına göre, fiyat alanının değeri double’a çevrilebilirse sorgu çalıştırılıyor, çevrilemezse kullanıcıya hata me-sajı veriliyor. Bir önceki örnekte olduğu gibi formun action değeri, yani post edildiğinde verilerini göndereceği sayfa, yine formun kendisi.

UrunEkle.jsp sayfası çalıştırılmadan önce ve hatalı veri girildiğinde aşağıdaki gibi görünür.

Veritabanını sorgulayarak sipariş bilgilerini getirmek için JSP sayfalarımızı oluşturalım. Öncelikle veritabanı sunucumuzun arayüz programını açarak sipariş ve sipariş detayı bilgilerini ekleyelim.

INSERTINTOSiparis(musteriID,siparisTarihi)VALUES(1,‘12/2/2007’)

INSERTINTOSiparis(musteriID,siparisTarihi)VALUES(1,‘10/8/2007’)

Şekil 18

Şekil 19: Fiyat alanına double tipine çevrilemeyen veri girildi.

135JSP

Page 142: Bilge adam java.pdf

INSERTINTOSiparis(musteriID,siparisTarihi)VALUES(2,‘5/3/2007’)

INSERTINTOSiparis(musteriID,siparisTarihi)VALUES(3,‘5/8/2007’)

INSERTINTOSiparisDetay(siparisID,urunID,miktar)VALUES(1,1,1)

INSERTINTOSiparisDetay(siparisID,urunID,miktar)VALUES(1,3,2)

INSERTINTOSiparisDetay(siparisID,urunID,miktar)VALUES(2,7,1)

INSERTINTOSiparisDetay(siparisID,urunID,miktar)VALUES(3,5,1)

INSERTINTOSiparisDetay(siparisID,urunID,miktar)VALUES(3,8,3)

INSERTINTOSiparisDetay(siparisID,urunID,miktar)VALUES(4,3,1)

Verileri veritabanına ekledikten sonra JSP sayfalarımızı oluşturmaya başlayabiliriz. Öncelikle ve-rilen siparişleri görüntülemek için Siparis.jsp adında bir JSP sayfası oluşturalım.

1<%@pageimport=”java.util.*”%>

2<%@pageimport=”java.sql.Connection”%>

3<%@pageimport=”java.sql.DriverManager”%>

4<%@pageimport=”java.sql.ResultSet”%>

5<%@pageimport=”java.sql.Statement”%>

6<html>

7<body>

8<%

9 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

10 ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

11 Statementstatement=dbConnection.createStatement();

12 ResultSet resultSet = statement.executeQuery(“SELECT siparisID,siparisTarihi,ad,soyadFROMsiparissJOINMusterimON(s.musteriID=m.musteriID)”);

13 out.println(“Detaybilgileriniogrenmekistediginizsiparisintarihinetiklayin<br><br>”);

14 %>

15 <table>

16 <%

17 while(resultSet.next())

18 {

19 %>

20 <tr>

21 <tdwidth=”100”><ahref=”SiparisDetay.jsp?id=<%out.println(resultSet.getInt(“siparisID”));

136 Bölüm 8

Page 143: Bilge adam java.pdf

22 %>”>

23 <%

24 out.println(resultSet.getDate(“siparisTarihi”).toString());25 %>

26 </a></td>

27 <tdwidth=”60”>

28 <%

29 out.println(resultSet.getString(“ad”));28

30 %>

31 </td>

32 <tdwidth=”60”><%out.println(resultSet.getString(“soyad”));33 %>

34 </td>

35 </tr>

36 <%

27 }

38 %>

39 </table>

40 <%

41 statement.close();

42 %>

43 </body>

44 </html>

Kodun açıklaması: Veritabanı bağlantısı oluşturulduktan sonra sipariş bilgilerini çekmek amacıy-la bir select sorgusu veritabanı üzerinde çalıştırılır ve geri dönen sonuç kümesi ResultSet nesnesi aracılığıyla alınır. Verilerin düzgün bir biçimde görüntülenebilmesi için <table> yapısı kullanılmış-tır. ResultSet nesnesinin her bir kaydı için tabloda bir satır oluşturulmuştur. Bir satır üç sütundan oluşur: İlk sütün siparişin verildiği tarihi içerir ve SiparisDetay.jsp sayfasına bağlantı kurmak ama-cıyla <a href> etiketinden oluşur. SiparisDetay.jsp sayfasına siparis numarası URL aracılığıyla ta-şınacağından her bir kaydın siparisID değeri ile <a href> etiketinin URL alanı belirlenir. Bu alanın değeri SiparisDetay.jsp?id=... şeklinde olup “...” ile ifade edilen yere sipariş numarası gelir. Sayfa yüklendiği zaman aşağıdaki gibi görünür.

Şekil 20

137JSP

Page 144: Bilge adam java.pdf

Sipariş tarihi alanına tıklandığında açılacak olan SiparisDetay.jsp sayfasında seçilen siparişin detay bilgileri veritabanından çekildikten sonra görüntülenecektir. SiparisDetay.jsp sayfasını oluş-turan JSP kodu aşağıdaki gibidir.

1<%@pageimport=”java.util.*”%>

2<%@pageimport=”java.sql.Connection”%>

3<%@pageimport=”java.sql.DriverManager”%>

4<%@pageimport=”java.sql.ResultSet”%>

5<%@pageimport=”java.sql.Statement”%>

6<%@pageimport=”java.sql.PreparedStatement”%>

7<html>

8<body>

9<%

10 if(request.getParameter(“id”)==null)

11 response.sendRedirect(“Siparis.jsp”);

12 Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”);

13 ConnectiondbConnection=DriverManager.getConnection(“jdbc:odbc:AlisverisSitesi”);

14 PreparedStatementstatement=dbConnection.prepareStatement(“SELECTurunAdi,fiyat,miktarFROMSiparisDetaysd JOIN Urun u ON (sd.urunID = u.urunID) WHERE siparisID = ?”);

15 statement.setString(1,request.getParameter(“id”));

16 ResultSet resultSet = statement.executeQuery();

17 %>

18 <table>

19 <%

20 while(resultSet.next())

21 {

22 %>

23 <tr>

24 <tdwidth=”200”>

25 <%

26 out.println(resultSet.getString(“urunAdi”));

27 %>

28 </td>

29 <tdwidth=”100”>

30 <%

31 out.println(resultSet.getDouble(“fiyat”));

32 %>

33 </td>

34 <tdwidth=”100”>

35 <%

36 out.println(resultSet.getInt(“miktar”));

37 %>

38 </td>

138 Bölüm 8

Page 145: Bilge adam java.pdf

39 </tr>

40 <%

41 }

42 %>

43 </table>

44 <%

45 statement.close();

46 %>

47 </body>

48 </html>

Kodun açıklaması: Sayfanın ilk yüklenmesi sırasında URL aracılığıyla “id” değerinin gelip gel-mediği kontrol edilir. Eğer “id” değeri yoksa kullanıcı Siparis.jsp sayfasına yönlendirilir. “id” değeri varsa veritabanı bağlantısı kurulduktan sonra parametreli bir select ifadesi çalıştırmak üzere Pre-paredStatement nesnesi oluşturulur ve sipariş numarası URL aracılığıyla gelen siparişin detay bilgileri veritabanından çekilir. Geri dönen sonuç kümsi ResultSet nesnesi aracılığıyla bir HTML tablosunda kullanıcıya gösterilir.

SiparisDetay.jsp sayfası açıldığında “id” alanının değeri boş değilse aşağıdaki gibi bir sayfa gö-rüntülenir.

Şekil 21

139JSP

Page 146: Bilge adam java.pdf
Page 147: Bilge adam java.pdf

9 JAVA I/O

Page 148: Bilge adam java.pdf

9 JAVA I/ODosyalar ve Dizinler

FilterInputStream Sınıfları

FileInputStream ve FileOutputStream Sınıflarının Kullanımı

Reader ve Writer Sınıfları:

Standart Giriş-Çıkış Biriminin Kullanılması:

Java ile Ağ Programlama

Page 149: Bilge adam java.pdf

JAVA I/O .NET platformunda olduğu gibi Java platformunda da giriş-çıkış işlemleri Stream adı verilen veri yapıları aracılığıyla yapılır. Veri gönderme ve alma kabiliyetine sahip bütün nesneler Stream ola-rak tanımlanabilir. Stream yapısının kullanımıyla, giriş-çıkış birimlerinin içinde bulunan veri ya-zılım ortamından soyutlanmış olur. Java ortamındaki Stream okuma amacıyla kullanılan sınıflar InputStream sınıfından, Stream yazma amacıyla kullanılan sınıflar OutputStream sınıfından tü-retilirler. InputStream türünden sınıflarda bulunan Read() metodu ile byte bazında okuma yapıla-bilir. Benzer bir şekilde OutputStream türünden sınıflarda bulunan sınıfların sahip olduğu Write() metodu ile byte bazında yazma işlemi yapılabilir. Stream yapılarını kullanmak için oluşturulmuş olan InputStream ve OutputStream sınıfları temel olarak byte veri tipinden verilerle çalışsa da Java ortamında bulunan farklı sınıflar kullanılarak char veri tipi ile de işlem yapılabilir. Aşağıdaki veri kaynakları kullanılarak Stream üzerinden okuma veya yazma işlemi gerçekleştirilebilir:

Byte dizileri

Dosyalar

String nesneleri

Ağ (network) kaynakları

Stream yapısının detaylarına girmeden önce dosya sistemi üzerinde duralım.

Dosyalar ve Dizinler Okuma ve yazma işlemleri için disk üzerinde bulunan dosyalara erişilmek istendiğinde File sı-nıfından oluşturulan nesneler kullanılır. File kelimesi sadece dosya kavramını temsil ediyor gibi görünse de dizin kavramını da içerir. Disk üzerinde bulunan dizinlere ve dosyalara erişmek için File nesneleri kullanılır. File nesnesinin bir dosyayı temsil etmesi istendiğinde yapıcı metoduna parametre olarak bu dosyanın yeri, adı ve uzantısı String formatında verilir. Benzer şekilde, File nesnesinin yapıcı metoduna parametre olarak temsil edilecek dizinin yeri ve adı da verilebilir.

File nesnesi kullanılarak C:\Program Files\Java\jre1.6.0_02 dizininin içinde bulunan bütün dosya ve dizinler aşağıdaki gibi görüntülenebilir:

1importjava.io.File;

2publicclassGiris

3{

4 publicstaticvoidmain(String[]args)

5 {

6 FilekaynakDizin=newFile(“C:\\ProgramFiles\\Java\\jre1.6.0_02”);

7 String[]dosyalarVeDizinler=kaynakDizin.list();

8 for(StringdosyaVeyaDizin:dosyalarVeDizinler)

9 {

10 System.out.println(dosyaVeyaDizin);

11 }

12 }

13 }

Kodun açıklaması: File nesnesi oluşturularak C:\Program Files\Java\jre1.6.0_02 dizininin Java programında temsil edilmesi sağlanır. File nesnesinin list() metodu, dizin içinde bulunan bütün dosya ve dizinlerin adını bir String dizisi şeklinde döndürür.

Page 150: Bilge adam java.pdf

Uygulama çalıştırıldığında aşağıdaki gibi bir çıktı alınır:

bin

COPYRIGHT

lib

LICENSE

PATCH.ERR

README.txt

THIRDPARTYLICENSEREADME.txt

Welcome.html

Bilgisayarınızda bu dizin bulunmuyorsa File sınıfının yapıcı metoduna başka bir dizin adını pa-rametre olarak verebilirsiniz. C:\Program Files\Java\jre1.6.0_02 dizininin altında bulunan bütün dosya ve klasörlerin görüntülendiğine ve verilen dizin altında bulunan dizinlerin içindeki dosya ve klasörlerin listelenmediğine dikkat edelim. Sadece dosyaların görüntülenmesi için aşağıdaki kod bloğu kullanılabilir:

1importjava.io.File;

2publicclassGiris

3{

4 publicstaticvoidmain(String[]args)

5 {

6 FilekaynakDizin=newFile(“C:\\ProgramFiles\\Java\\jre1.6.0_02”);

7 File[]dosyalarVeDizinler=kaynakDizin.listFiles();

8 for(FiledosyaVeyaDizin:dosyalarVeDizinler)

9 {

10 if(dosyaVeyaDizin.isFile())

11 {

12 System.out.println(dosyaVeyaDizin.getName());

13 }

14 }

15 }

16 }

Kodun açıklaması: Bir önceki örnekten farklı olarak File nesnesinin listFiles() metodunu kul-landık. Bu metod String dizisi yerine File dizisi döndürür. Böylece verilen dizinin altında bulunan bütün dosya ve dizinler birer tane File nesnesiyle temsil edilmiş olur. Döngü içinde bulunan File nesnesinin isFile() metodu ile temsil edilen yapının dosya olup olmadığını kontrol ediyoruz, eğer dosyaysa dosyanın adını ekrana basıyoruz. Sadece dizinleri görüntülemek isteseydik File nes-nesinin isDirectory() metodunu kullanabilirdik. Uygulama çalıştırıldığında aşağıdaki gibi bir çıktı alınır:

COPYRIGHT

LICENSE

PATCH.ERR

README.txt

144 Bölüm 9

Page 151: Bilge adam java.pdf

THIRDPARTYLICENSEREADME.txt

Welcome.html

InputStream

Çeşitli veri kaynaklarından veri okumak amacıyla aşağıdaki sınıflardan oluşturulan nesneler kul-lanılabilir. Bu sınıflar InputStream sınıfından türetilmiştir.

ByteArrayInputStream: Bellek üzerinde bulunan tampon bölgelerden veri alınması amacıyla kullanılır.

StringBufferInputStream: Bir String nesnesinin InputStream nesnesi olarak kullanılmasını sağ-lar.

FileInputStream: Disk üzerinde bulunan dosyaların okunması için kullanılır.

SequenceInputStream: Birden fazla InputStream nesnesinin tek bir InputStream nesnesine dö-nüştürülmesini sağlar.

PipedInputStream: PipedOutputStream nesnesine yazılan verileri biçimlendirmek için kullanılır.

OutputStream

Çeşitli veri kaynaklarına veri yazmak amacıyla aşağıdaki sınıflardan oluşturulan nesneler kullanı-labilir. Bu sınıflar OutputStream sınıfından türetilmiştir.

ByteArrayOutputStream: Bellek üzerinde buffer bölgesi oluşturulması amacıyla kullanılır. Byte-ArrayOutputStream üzerine yazılan bütün verilen bellekte bulunan tampon bölgeye yazılır.

FileOutputStream: Disk üzerinde bulunan dosyalara veri yazılması için kullanılır.

PipedOutputStream: PipedInputStream nesnesine gönderilecek verileri hazırlamak için kullanı-lır.

Bahsedilen Stream sınıflarından başka, InputStream türevi sınıflardan oluşan nesneler aracılı-ğıyla yapılan okuma işleminin veya OutputStream türevi sınıflardan oluşan nesneler aracılığıyla yapılan yazma işleminin özelliklerinin belirlenmesi amacıyla FilterInputStream ve FilterOutputS-tream sınıfları kullanılır. Byte veri tipinden farklı veri tipleri ile okuma veya yazma yapma, okuna-cak veya yazılacak verilerin bir tampon bölgede tutulması veya tutulmaması gibi özellikler Filter sınıfları aracılığıyla sağlanır. FilterInputStream ve FilterOutputStream sınıfları soyut olarak oluş-turulmuştur, bu sınıflardan türetilen ve yerleşik olarak Java ortamında bulunan sınıflar yardımıyla Stream nesnelerine çeşitli özellikler kazandırılabilir.

FilterInputStream SınıflarıGiriş kaynaklarını biçimlendirmek amacıyla kullanılan sınıfların bir kısmı şunlardır:

DataInputStream: Farklı veri tiplerinde verilerin okunması amacıyla kullanılır.

BufferedInputStream: Her okumada fiziksel kaynağa erişilmesini engeller, okunan verilerin bel-lekte bulunan bir tampon bölgeye aktarılmasını sağlar.

LineNumberInputStream: Giriş kaynağına gelen satır sayısını saklar. Bu sınıfın kullanılması tavsiye edilmez, satır sayısını elde etmek amacıyla kullanılan LineNumberReader sınıfı ileride açıklanacaktır.

Bu sınıfların yapıcı metodları parametre olarak InputStream sınıfından türemiş bir sınıftan oluşan bir nesne alır.

145JAVA I/O

Page 152: Bilge adam java.pdf

FilterOutputStream Sınıfları

Çıkış kaynaklarını biçimlendirmek amacıyla kullanılan sınıfların bir kısmı şunlardır:

DataOutputStream: Farklı veri tiplerinde verilerin yazılması amacıyla kullanılır.

BufferedOutputStream: Her yazma işleminde fiziksel kaynağa erişilmesini engeller, yazılacak verilerin bellekte bulunan bir tampon bölgeye aktarılmasını sağlar.

PrintOutputStream: Çıkış kaynağına gönderilen verilerin görsel olarak biçimlendirilmesini sağ-lar.

Bu sınıfların yapıcı metodları parametre olarak OutputStream sınıfından türemiş bir sınıftan olu-şan bir nesne alır.

FileInputStream ve FileOutputStream Sınıflarının KullanımıDisk üzerinde bulunan bir dosyanın okunarak içeriğinin disk üzerindeki başka bir dosyaya yazıl-masını aşağıdaki kod ile gerçekleştirebiliriz.

1importjava.io.FileInputStream;

2importjava.io.FileOutputStream;

3importjava.io.IOException;

4publicclassDosyaIslemleri

5{

6 publicstaticvoidmain(String[]args)throwsIOException

7 {

8 FileInputStreamokuma=newFileInputStream(“c:\\okunan.txt”);

9 FileOutputStreamyazma=newFileOutputStream(“c:\\yazilan.txt”);

10 intokunanKarakter;

11 while((okunanKarakter=okuma.read())!=-1)

12 {

13 System.out.print((char)okunanKarakter);

14 yazma.write(okunanKarakter);

15 }

16 okuma.close();

17 yazma.close();

18 }

19 }

Kodun açıklaması: C sürücüsünde oluşturduğumuz okunan.txt dosyasını okuyarak içeriğini C sürücüsündeki “yazilan.txt” dosyasında kopyalamak istiyoruz. okunan.txt dosyasını aşağıdaki gibi oluşturabilirsiniz:

Javailedosyadanokuma

islemi yaptık

Dosyadaki verileri okumak için FileInputStream nesnesi, dosyaya yazmak için FileOutputStre-am nesnesi oluşturduk. FileInputStream nesnemizin read() metodu döngünün her dönüşünde bir byte değerini tam sayı olarak okur, ekranda görüntüler ve yazmak için açtığımız dosyaya yazar.

146 Bölüm 9

Page 153: Bilge adam java.pdf

yazilan.txt isimli dosya disk üzerinde bulunmuyorsa FileOutputStream nesnesi tarafından oluştu-rulur, bulunuyorsa içi boşaltılır.

Uygulama çalıştırıldığında ekranda aşağıdaki gibi bir görüntü oluşur. Türkçe karakterlerin düzgün görünmemesinin sebebi, okunan değerlerin unicode desteğine sahip olmamasıdır.

Javailedosyadanokuma

i?lemi yapt?k

“yazilan.txt” dosyasının içeriği ise aşağıdaki gibi olur. Türkçe karakterlerin “yazilan.txt” dosyasına düzgün bir şekilde aktarılmıştır.

Javailedosyadanokuma

işlemi yaptık

Dosyadan okunan karakteri ekrana basmak için tip dönüşümü işlemini kullanarak okunan tam sayı cinsinden verileri karakter tipine çevirdik. Tip dönüşümü yapmasaydık veriler ekrana tam sayı olarak basılırdı. Aşağıdaki veriler, dosyadan okunan karakterlerin tam sayı cinsinden kar-şılığıdır. Println() metodunu kullanırken araya boşluk bırakmadığımız için bütün sayılar aralıksız gösterildi. Bunun sebebi, boşluk karakterinin de tam sayı cinsinden bir karşılığa sahip olmasıdır.

74971189732105108101321001111151219710097110321111071171099713101052541081011091053212197112116253107

Okuma veya yazma işlemini tek bir tamsayı ile sınırlandırmak yerine byte blokları şeklinde de yapabiliriz. Bunun için bir tane byte dizisi tanımlanarak read() ve write() metodlarına parametre olarak verilir. Okunan veriler byte dizisine yazılır, yazma işlemi yapılacaksa byte dizisi kullanılarak yapılır. Örnek kod aşağıda verilmiştir.

1importjava.io.FileInputStream;

2importjava.io.FileOutputStream;

3importjava.io.IOException;

4publicclassDosyaIslemleri

5{

6 publicstaticvoidmain(String[]args)throwsIOException

7 {

8 FileInputStreamokuma=newFileInputStream(“c:\\okunan.txt”);

9 FileOutputStreamyazma=newFileOutputStream(“c:\\yazilan.txt”);

10 byte[]veri=newbyte[1000];

11 intdosyaBoyutu=okuma.read(veri);

12 yazma.write(veri);

13 okuma.close();

14 yazma.close();

15 }

16 }

147JAVA I/O

Page 154: Bilge adam java.pdf

FileInputStream ve FileOutputStream Sınıflarının File Sınıfıyla Birlikte Kullanımı:Duruma göre FileInputStream ve FileOutputStream nesnelerinin yapıcı metodlarına parametre olarak dosya adı yerin File nesneleri de verebiliriz. Uygulamanın kodunun aşağıdaki gibi olması durumunda da ekran çıktısı ve yeni oluşan dosyanın içeriği değişmeyecektir:

1importjava.io.File;

2importjava.io.FileInputStream;

3importjava.io.FileOutputStream;

4importjava.io.IOException;

5publicclassDosyaIslemleri

6{

7 publicstaticvoidmain(String[]args)throwsIOException

8 {

9 FileokunanDosya=newFile(“c:\\okunan.txt”);

10 FileyazilanDosya=newFile(“c:\\yazilan.txt”);

11 FileInputStreamokuma=newFileInputStream(okunanDosya);

12 FileOutputStreamyazma=newFileOutputStream(yazilanDosya);

13 intokunanKarakter;

14 while((okunanKarakter=okuma.read())!=-1)

15 {

16 System.out.print((char)okunanKarakter);

17 yazma.write(okunanKarakter);

18 }

19 okuma.close();

20 yazma.close();

21 }

22 }

DataInputStream ve DataOutputStream Sınıflarının Kullanımı:DataInputStream ve DataOutputStream sınıflarından oluşturulan nesneler kullanılarak çeşitli veri tipleri ile okuma ve yazma işlemi yapılabilir. Bu sınıflardan oluşan nesneler ile UTF formatında veri okunabilir ve yazılabilir. UTF formatında veri yazma kabiliyeti, farklı platformlar arasında veri aktarımı yapılacağında kullanılır.

Aşağıdaki örnekte, bir DataInputStream ile readChar() metodunu kullanarak karakter bazında okuma yaptıktan sonra DataOutputStream nesnesini kullanarak bu karakterleri dosyaya yazdı-racağız.

1importjava.io.DataInputStream;

2importjava.io.DataOutputStream;

3importjava.io.FileInputStream;

4importjava.io.FileNotFoundException;

5importjava.io.FileOutputStream;

6importjava.io.IOException;

148 Bölüm 9

Page 155: Bilge adam java.pdf

7publicclassDosyaIslemleri

8{

9 publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException

10 {

11 FileInputStreamokuma=newFileInputStream(“c:\\okunan.txt”);

12 FileOutputStreamyazma=newFileOutputStream(“c:\\yazilan.txt”);

13 DataInputStreamozellesmisOkuma=newDataInputStream(okuma);

14 DataOutputStreamozellesmisYazma=newDataOutputStream(yazma);

15 while(ozellesmisOkuma.available()!=0)

16 {

17 charokunanKarakter=ozellesmisOkuma.readChar();

18 ozellesmisYazma.writeChar(okunanKarakter);

19 }

20 ozellesmisOkuma.close();

21 ozellesmisYazma.close();

22 okuma.close();

23 yazma.close();

24 }

25 }

Kodun açıklaması: Bir önceki örnekte yaptığımız gibi FileInputStream ve FileOutputStream nesnelerini oluşturduk. Farklı veri tipleri kullanarak okuma yapmak için DataInputStream sınıfını, farklı veri tipleri kullanarak yazma yapmak için DataOutputStream sınıfını kullanacağımızı söy-lemiştik. DataInputStream sınıfının yapıcı metodu parametre olarak bir FileInputStream nesnesi, DataOutputStream sınıfının yapıcı metodu parametre olarak bir FileOutputStream nesnesi alır. Dosyanın sonuna gelinip gelinmediğini, DataInputStream nesnesinin available() metodu ile an-layabiliriz. Bu metod, DataInputStream nesnesinin bulunduğu yerden dosyanın sonuna kadar okunabilecek byte sayısını döndürür. Bu metodun döndürdüğü değer sıfır olduğunda dosyanın sonuna gelinmiş demektir. Uygulamayı çalıştırdığımızda, “yazilan.txt” dosyasının içeriğinin aşa-ğıdaki gibi olduğunu görürüz.

Uygulamayı çalıştırdığımızda, “yazilan.txt” dosyasının içeriğinin aşağıdaki gibi olduğunu görü-rüz.

Javailedosyadanokuma

işlemi yaptık

DataInputStream sınıfında bulunan readChar() metodu ile iki byte uzunluğunda okuma yapılır. Aynı şekilde DataOutputStream sınıfında bulunan writeChar() metodu ile iki byte uzunluğunda yazma gerçekleştirlir. Bu durumda dolayı; DataInputStream sınıfından oluşan bir nesne üzerin-den okunan verileri FileOutputStream sınıfından oluşturulan bir nesne ile başka bir dosyaya ya-zarsak veri kaybıyla karşılaşırız.

Az önce yazdığımız örneği aşağıdaki gibi değiştirelim:

149JAVA I/O

Page 156: Bilge adam java.pdf

1importjava.io.DataInputStream;

2importjava.io.FileInputStream;

3importjava.io.FileNotFoundException;

4importjava.io.FileOutputStream;

5importjava.io.IOException;

6publicclassDosyaIslemleri

7{

8 publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException

9 {

10 FileInputStreamokuma=newFileInputStream(“c:\\okunan.txt”);

11 FileOutputStreamyazma=newFileOutputStream(“c:\\yazilan.txt”);

12 DataInputStreamozellesmisOkuma=newDataInputStream(okuma);

13 while(ozellesmisOkuma.available()!=0)

14 {

15 charokunanKarakter=ozellesmisOkuma.readChar();

16 yazma.write(okunanKarakter);

17 }

18 ozellesmisOkuma.close();

19 okuma.close();

20 yazma.close();

21 }

22 }

Okuma işlemini DataInputStream nesnesi ile, yazma işlemini FileOutputStream nesnesi ile yap-tık. Uygulamayı çalıştırdığımızda oluşan “yazilan.txt” dosyasının içeriği aşağıdaki gibidir.

aaiedsaakm

ilmatk

Dikkat edersek, “okunan.txt” dosyasında bulunan verilen birer karakter atlanarak “yazilan.txt” dosyasına yazılmış olduğunu görürüz.

Reader ve Writer Sınıfları: Java 1.1 sürümünden itibaren platforma Stream’ler üzerinde okuma ve yazma işlemlerini daha işlevsel hale getirmek için Reader ve Writer sınıfları eklenmiştir. Bu sınıflar byte veri tipi yerine unicode karakter tipini kullanırlar. Karakter tipinden verilerin kullanılması yazılımcının işini birçok durumda kolaylaştırdığı gibi desteklenen karakter formatının unicode olması yazılımın farklı dilleri desteklemesini de sağlar. InputStream ve OutputStream sınıfları aracılığıyla okunan ve yazılan veriler 8 bitlik byte tipi verilerden oluştuğu halde, Reader ve Writer sınıfları 16 bitlik veri desteği-ne sahiptir. Reader ve Writer sınıfları birçok durumda InputStream ve OutputStream sınıflarının yerine kullanılabilse de byte bazında işlemlerin yapılması gereken senaryolar da olabilir; bu gibi durumlarda InputStream ve OutputStream sınıflarının ve bu sınıfların türevlerinin kullanılması gerekir. Writer türevi sınıflarla Stream yapıları üzerinde append() işlemi yapılabilir.

150 Bölüm 9

Page 157: Bilge adam java.pdf

Stream sınıflarının Reader ve Writer karşılıkları aşağıdaki tabloda gösterilmiştir.

Verileri ve veri aktarma şekillerini biçimlendirmek amacıyla Stream sınıflarının biçimlendirilmesin-de kullanılan Filter sınıflarına benzer sınıflar da vardır. Bu sınıflar aşağıdaki tabloda gösterilmiş-tir.

FileReader ve FileWriter Sınıflarının Kullanılması:FileReader ve FileWriter sınıflarının kullanımı, FileInputStream ve FileOutputStream sınıflarının kullanımıyla benzerdir. Aşağıdaki örnekte FileReader nesnesi ile dosya içeriği okunmakta ve Fi-leWriter nesnesi ile diğer dosyaya yazılmaktadır. Okuma işlemi için daha önce oluşturduğumuz “okunan.txt” dosyası kullanılmıştır.

1importjava.io.FileNotFoundException;

2importjava.io.FileReader;

3importjava.io.FileWriter;

4importjava.io.IOException;

5publicclassDosyaIslemleri

6{

7 publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException

8 {

9 FileReaderokuma=newFileReader(“c:\\okunan.txt”);

10 FileWriteryazma=newFileWriter(“c:\\yazilan.txt”);

11 intokunanKarakter;

12 while((okunanKarakter=okuma.read())!=-1)

Stream sınıfları Reader ve Writer sınıfları

InputStream Reader

OutputStream Writer

ByteArrayInputStream CharArrayReader

ByteArrayOutputStream CharArrayWriter

FileInputStream FileReader

FileOutputStream FileWriter

PipedInputStream PipedReader

PipedOutputStream PipedWriter

StringBufferInputStream StringReader

Stream sınıfları Reader ve Writer sınıfları

FilterInputStream FilterReader

FilterOutputStream FilterWriter

BufferedInputStream BufferedReader

BufferedOutputStream BufferedWriter

DataInputStream -

PrintStream PrintWriter

LineNumberInputStream LineNumberReader

151JAVA I/O

Page 158: Bilge adam java.pdf

13 {

14 System.out.print((char)okunanKarakter);

15 yazma.write(okunanKarakter);

16 }

17 okuma.close();

18 yazma.close();

19 }

20 }

Uygulama çalıştırıldığında aşağıdaki gibi bir çıktı alınır. FileInputStream sınıfının kullanımında Türkçe karakterler bozuk göründüğü halde FileReader sınıfı kullanıldığında Türkçe karakterler düzgün bir şekilde görünür. “yazilan.txt” dosyası da aynı verileri içerir.

Javailedosyadanokuma

işlemi yaptık

FileInputStream sınıfından oluşan bir nesne ile bir dosyadaki verileri byte dizisi şeklinde okuya-biliyorduk. FileReader sınıfından oluşan bir nesne ile veriler karakter dizisi şeklinde okunabilir. Örnek kullanım aşağıdaki gibidir:

1importjava.io.FileNotFoundException;

2importjava.io.FileReader;

3importjava.io.FileWriter;

4importjava.io.IOException;

5publicclassDosyaIslemleri

6{

7 publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException

8 {

9 FileReaderokuma=newFileReader(“c:\\okunan.txt”);

10 FileWriteryazma=newFileWriter(“c:\\yazilan.txt”);

11 char[]veri=newchar[1000];

12 okuma.read(veri);

13 yazma.write(veri);

14 okuma.close();

15 yazma.close();

16 }

17 }

Uygulama çalıştırıldığında, “yazilan.txt” dosyasının içeriğinin “okunan.txt” dosyasının içeriğiyle aynı olduğu görülür.

BufferedReader Sınıfının Kullanımı:BufferedReader sınıfını kullanarak verileri satır bazında okuyabilir ve yazabiliriz. Örnek kullanım aşağıda verilmiştir.

1importjava.io.BufferedReader;

2importjava.io.FileNotFoundException;

152 Bölüm 9

Page 159: Bilge adam java.pdf

3importjava.io.FileReader;

4importjava.io.FileWriter;

5importjava.io.IOException;

6publicclassDosyaIslemleri

7{

8 publicstaticvoidmain(String[]args)throwsFileNotFoundException,IOException

9 {

10 FileReaderokuma=newFileReader(“c:\\okunan.txt”);

11 FileWriteryazma=newFileWriter(“c:\\yazilan.txt”);

12 BufferedReadertamponOkuma=newBufferedReader(okuma);

13 Stringsatir=newString();

14 StringbutunVeri=newString();

15 while((satir=tamponOkuma.readLine())!=null)

16 {

17 butunVeri+=satir+“\n”;

18 }

19 System.out.println(butunVeri);

20 yazma.write(butunVeri);

21 tamponOkuma.close();

22 okuma.close();

23 yazma.close();

24 }

25 }

Daha önceki örneklerden farklı olarak, dosyada bulunan veriler satır satır okunmuştur. Buffered-Reader nesnesinin readLine() metodu kullanılarak okunan satırlar satir adındaki String değişke-nine aktarılır, her satır butunVeri isimli String değişkenine eklenir. butunVeri değişkeni dosyadan okunan bütün metni saklamak amacıyla kullanılmıştır. Uygulama çalıştırıldığında ekranda ve “ya-zilan.txt” dosyasında aşağıdaki gibi bir görünüm oluşur.

Javailedosyadanokuma

işlemi yaptık

Okunan satır değerinin butunVeri değişkenine eklenmesi sırasında “\n” karakteri kullanılmasaydı bütün satırlar ekran çıktısında yan yana görünür ve “yazilan.txt” dosyasına yan yana yazılırdı. Bunun sebebi, readLine() metodunun satırı okuduktan sonraki “\n” değerini almamasıdır. “\n” karakterinin kullanımaması durumunda dosyadaki veri aşağıdaki gibi olur:

Java ile dosyadan okumaişlemi yaptık

153JAVA I/O

Page 160: Bilge adam java.pdf

Standart Giriş-Çıkış Biriminin Kullanılması:Konsol üzerinden veri okuma ve veri yazma işlemlerinin yapılması için standart giriş-çıkış birimini oluşturan System.in, System.out ve System.err sınıfları kullanılır. Bu sınıflar, .Net platformundaki Console sınıfının karşılığıdır. Genelde konsole üzerinden yapılan readLine() işleminin tampon bellek bölgesi ile kullanımı uygundur.

Konsoldan girilen verileri okuyan ve standart çıkışa yazan bir Java programı aşağıda verilmiştir. Kullanıcı boş satır girdiğinde uygulama sonlanır.

1importjava.io.BufferedReader;

2importjava.io.IOException;

3importjava.io.InputStreamReader;4publicclassKonsol

5{

6 publicstaticvoidmain(String[]args)throwsIOException

7 {

8 InputStreamReadergiris=newInputStreamReader(System.in);

9 BufferedReadertampon=newBufferedReader(giris);

10 Stringsatir;

11 System.out.println(“Uygulamadan çıkmak için enter tuşuna basın”);

12 System.out.print(“Verigirin:“);

13 satir=tampon.readLine();

14 while(satir.length()!=0)

15 {

16 System.out.println(“Girdiğiniz veri: “ + satir);

17 System.out.print(“Verigirin:“);

18 satir=tampon.readLine();

19 }

20 }

21 }

Uygulama çalıştırıldığında kullanıcıdan sürekli veri girmesini bekler, kullanıcı Enter tuşuna bas-tığında uygulama sonlanır. Veri girin metninin doğru yerde görüntülenmesini sağlamak için dön-güden önce readLine() metodu bir kere çalıştırılmıştır. Örnek girişlerle aşağıdaki gibi bir çıkış üretilir:

Uygulamadan çıkmak için enter tuşuna basın

Verigirin:Javaile

Girdiğiniz veri: Java ile

Veri girin: Giriş-Çıkış

Girdiğiniz veri: Giriş-Çıkış

Veri girin: İşlemleri

Girdiğiniz veri: İşlemleri

Verigirin:

154 Bölüm 9

Page 161: Bilge adam java.pdf

Java ile Ağ Programlama: Ağ üzerinde bulunan farklı bilgisayarlar üzerinde çalışan programların haberleşmesi Socket yapı-ları ile sağlanır. Socket’ler, uygulamaların haberleşmesini sağlayan iletişim noktalarıdır. Sunucu tarafında tanımlanan ServerSocket nesnesi ile herhangi bir istemcinin sunucuya belirli bir port üzerinden bağlanması beklenir, istemci bağlandığında sıradaki işlemler gerçekleştirilir. Sunucu ile istemci arasındaki veri aktarımı Socket arabirimleri üzerinden, Stream yapıları kullanılarak gerçekleştirilir. ServerSocket sınıfı adından dolayı özelleşmiş bir Socket yapısı gibi görünse de, temel işlevi sunucunun istemciden gelen isteği beklemesini ve istek geldiğinde bu isteği kabul etmesini sağlamaktır. İstemci sunucuya bağlandığı zaman ServerSocket nesnesi bir Socket nes-nesi oluşturarak döndürür.

ServerSocket ve Socket nesneleri kullanılarak ağ üzerinden sunucu-istemci arasında veri akta-rımı yapan Java dosyaları aşağıda verilmiştir. Sunucu ve istemci için birer tane Java sınıfı oluş-turulmuştur.

1 // Sunucu Uygulaması

2importjava.io.BufferedReader;

3importjava.io.BufferedWriter;

4importjava.io.IOException;

5importjava.io.InputStreamReader;

6importjava.io.OutputStreamWriter;

7importjava.net.ServerSocket;

8importjava.net.Socket;

9publicclassSunucu

10 {

11 publicstaticvoidmain(String[]args)throwsIOException

12 {

13 ServerSocketserverSocket=newServerSocket(60000);

14 System.out.println(“İstemcinin bağlanması bekleniyor”);

15 SocketclientSocket=serverSocket.accept();

16 System.out.println(“İstemci ile bağlantı kuruldu”);

17 InputStreamReaderokuma=newInputStreamReader(System.in);

18 BufferedReadertamponOkuma=newBufferedReader(okuma);

19 OutputStreamWriteryazma=newOutputStreamWriter(clientSocket.getOutputStream());

20 BufferedWritertamponYazma=newBufferedWriter(yazma);

21 Stringveri=newString();

22 while((veri=tamponOkuma.readLine()).length()!=0)

23 {

24 tamponYazma.write(veri);

155JAVA I/O

Page 162: Bilge adam java.pdf

25 tamponYazma.write(“\n”);

26 tamponYazma.flush();

27 System.out.println(“Gönderilenveri:“+veri);

28 }

29 System.out.println(“Bağlantı kesildi”);

30 serverSocket.close();

31 clientSocket.close();

32 okuma.close();

33 yazma.close();

34 tamponOkuma.close();

35 tamponYazma.close();

36 }

37 }

Kodun açıklaması: Sunucu üzerinde tanımlanan ServerSocket nesnesi, daha önce anlatıldığı gibi istemcinin bağlanmasını bekler ve bir istemci bağlanana kadar uygulamanın çalışmasını elin-de tutar. İstemci sunucuya bağlandıktan sonra ServerSocket nesnesinin accept() metodu Socket cinsinden bir nesne döndürür. Bu nesne ile sunucu istemciyle iletişim kurar. “okuma” isimli InputS-treamReader nesnesi, standart giriş-çıkış biriminden veri almak için kullanılır. Standart giriş-çıkış biriminden alınan verileri satır bazında okumak için BufferedReader nesnesi kullanılmıştır. Ben-zer şekilde Socket nesnesi üzerinden istemciye veri göndermek için OutputStreamWriter nesnesi oluşturulmuştur. OutputStreamWriter sınıfının yapıcı metoduna parametre olarak Socket nesne-sinin getOutputStream() metodundan dönen OutputStream nesnesi verilir. Verileri istemciye satır bazında göndermek için BufferedWriter nesnesi kullanılmıştır. Bir döngü içinde standart giriş-çıkış biriminden okunan veriler BufferedWriter nesnesi aracılığıyla istemciye gönderilir. BufferedWriter nesnesine veriyi yazdıktan sonra flush() komutu çalıştırılır. Bunun sebebi satır bazında gönderilen verinin hemen Stream’e yazılmasını sağlamaktır. Kullanıcı boş satır girdiğinde döngü sonlanır ve bağlantı sunucu tarafından kesilir.

1 // İstemci Uygulaması

2importjava.io.BufferedReader;

3importjava.io.IOException;

4importjava.io.InputStreamReader;

5importjava.net.Socket;

6publicclassIstemci

7{

8 publicstaticvoidmain(String[]args)throwsIOException

9 {

10 Socketsocket;

11 try

12 {

13 socket=newSocket(“127.0.0.1”,60000);

14 }

15 catch(IOExceptionex)

16 {

156 Bölüm 9

Page 163: Bilge adam java.pdf

17 System.out.println(“Bağlantı kurulamadı”);

18 return;

19 }

20 InputStreamReaderokuma=newInputStreamReader(socket.getInputStream());

21 BufferedReadertamponOkuma=newBufferedReader(okuma);

22 System.out.println(“Sunucu ile bağlantı kuruldu”);

23 Stringveri=newString();

24 try

25 {

26 while((veri=tamponOkuma.readLine())!=null)

27 {

28 System.out.println(“Gelenveri:“+veri);

29 }

30 System.out.println(“Bağlantı kesildi”);

31 }

32 catch(IOExceptionex)

33 {

34 System.out.println(“Bağlantı hatası”);

35 }

36 finally

37 {

38 okuma.close();

39 tamponOkuma.close();

40 socket.close();

41 }

42 }

43 }

Kodun açıklaması: İstemci tarafında, sunucu ile iletişim kurmak için bir Socket nesnesi tanımla-nır. İstemci üzerinde çalışan uygulamada ServerSocket nesnesi kullanılmamıştır, bunun sebebi istemcinin herhangi bir port üzerinden bağlantı beklememesidir. İstemci sadece sunucuya bağ-lanmak ve veri almak için tasarlanmıştır. Verilen IP adresine belirtilen port üzerinden bağlantı kurulamazsa IOException oluşur ve program sonlanır. Sunucu çalıştırılmadan istemci çalıştırı-lırsa bahsedilen hata mesajı alınır. Sunucu uygulamadan Stream üzerinden gelen verileri almak için InputStreamReader nesnesi, gelen verileri satır bazında işleyebilmek içinse BufferedReader nesnesi kullanılmıştır. Sunucu üzerinde çalışan uygulamada olduğu gibi istemcide de InputS-treamReader sınıfının yapıcı metoduna parametre olarak Socket nesnesinin getInputStream() metodundan dönen InputStream nesnesi verilir. Sunucuyla bağlantı kurulduktan sonra bir sonsuz döngü içinde sunucudan gelen mesajlar BufferedReader nesnesinin readLine() metodu ile satır bazında alınır ve standart çıkışa yazılır. Bu noktadan sonra IOException oluşursa sunucunun kapandığı anlaşılır ve “bağlantı kesildi” mesajı verilir.

157JAVA I/O

Page 164: Bilge adam java.pdf

Her iki uygulamada da Stream ve Socket nesnelerini kapatmayı unutmamalıyız.

Sunucu ve istemci uygulamalarının farklı şekillerde çalıştırılmaları aşağıdaki gibi çıktılar verir.

1. Sunucu çalıştırılmadan istemci çalıştırıldığında:

Bağlantı kurulamadı

2. Sunucu çalıştırıldıktan sonra istemcinin bağlanmasını beklerken:

İstemcinin bağlanması bekleniyor

3. İstemci ile sunucu arasında bağlantı kurulduğunda:

Sunucu tarafı:

İstemcinin bağlanması bekleniyor

İstemci ile bağlantı kuruldu

İstemci tarafı:

Sunucu ile bağlantı kuruldu

4. Sunucudan istemciye mesaj gönderildiğinde:

Sunucu tarafı:

İstemcinin bağlanması bekleniyor

İstemci ile bağlantı kuruldu

Javaile

Gönderilenveri:Javaile

Ağ Programlama

Gönderilen veri: Ağ Programlama

İstemci tarafı:

Sunucu ile bağlantı kuruldu

Gelenveri:Javaile

Gelen veri: Ağ Programlama

5. Bağlantı kesildiğinde:

Sunucu tarafı:

İstemcinin bağlanması bekleniyor

İstemci ile bağlantı kuruldu

Javaile

Gönderilenveri:Javaile

Ağ Programlama

Gönderilen veri: Ağ Programlama

Bağlantı kesildi

İstemci tarafı:

Sunucu ile bağlantı kuruldu

Gelenveri:Javaile

Gelen veri: Ağ Programlama

Bağlantı kesildi

158 Bölüm 9

Page 165: Bilge adam java.pdf

10 Oracle Veritabanı Ailesi

Page 166: Bilge adam java.pdf

10 Oracle Veritabanı Ailesi

Oracle Üzerinde Uygulama Geliştirme

Oracle Veri Tabanı Sisteminin Kurulması

Tablespace

Undo Tablespace

Oracle’da Veri Tabanı Oluşturmak

Temel Veri Tipleri

Page 167: Bilge adam java.pdf

Oracle Veritabanı AilesiOracle Personal Edition: Microsoft SQL Server 2005’teki Express Edition gibi düşünülebilir. Kişisel veritabanıdır. Uygulama geliştirme için kullanılır.

Oracle Standard Edition: Giriş seviyesinde çok kullanıcılı sürümdür. Microsoft SQL Server 2005 Standard Edition’a karşılık olarak düşünülebilir.

Oracle Enterprise Edition: En geniş kapsamlı sürümdür. Microsoft SQL Server 2005 Enterprise Edition’a karşılık olarak düşünülebilir.

Oracle Lite: Mobil uygulamalar için kullanılır.

Oracle Üzerinde Uygulama GeliştirmeOracle üzerinde uygulama geliştirme için kullanılacak çeşitli diller ve ortamlar mevcuttur. Bunlar SQL, PL/SQL, Java olarak sayılabilir. Bunların dışında .NET, C, C++ gibi dil ve ortamlardan erişim yapılabilir.

PL/SQL: Microsoft SQL Server’daki T-SQL’e karşılık olarak düşünülebilecek olan prosedürel SQL genişletmesidir. Oracle üzerinde PL/SQL kullanılarak SP (stored procedure), trigger gibi nesneler oluşturulabilir. T-SQL’deki gibi değişkenler, döngüler ve koşullar PL/SQL’de de mevcuttur. SQL Plus arayüzü kullanılarak ya da TOAD ile PL/SQL yazılabilir.

Java: Microsot SQL Server üzerine .NET ile nesnelerin yazılmasına karşılık olarak, bunun için Oracle tarafında Java kullanılır.

Oracle Veri Tabanı Sisteminin KurulmasıÖncelikle, eğer değilse, bilgisayarınızın bölgesel ayarlarını İngilizce olarak değiştirmeniz ge-rekir. Bunun için, Start > Control Panel > Regional and Language Options’ tan (Başlat > Denetim Masası > Bölge ve Dil Seçenekleri) English (United States) (İngilizce (A.B.D.)) olarak belirleyin.

1�

Page 168: Bilge adam java.pdf

Daha sonra, Advanced (Gelişmiş) sekmesinde kullanılan dil seçeneği olarak yine English (United States) (İngilizce (A.B.D))‘yi seçin ve tamam butonuna tıklayın.

Tamam butonuna tıkladığınızda, gerekli dosyaların bilgisayarınızda yüklü olduğunu ve Setup’ın (Kur) dosyaları buradan kurabileceğini belirten bir uyarı ile karşılaşabilirsiniz. Bu durumda, Yes (Evet) seçeneğini tıklayın. Ardından Windows bilgisayarınızı yeniden başlat-mak isteyebilir. Bu durumda yine Yes (Evet) seçeneğini tıklayarak bilgisayarınızı yeniden başlatın.

Ardından Oracle10g kurulu dosyalarının bulunduğu klasöre giderek setup.exe’yi çalıştırın. Karşınıza ilk olarak daha önce yüklenmiş bir Oracle ürünü olup olmadığını kontrol eden bir işlem penceresi gelecektir.

2.

3�

4.

162 Bölüm 10

Page 169: Bilge adam java.pdf

Kontol işleminin ardından gelen ekranda yükleme seçeneği olarak Basic Installation ve Ad-vanced Installation olmak üzere iki yöntem karşınıza çıkacaktır. Bunlardan Basic Installation seçeneğini seçin. Böylelikle birçok ayarın otomatik olarak yapılması sağlanacaktır.

Oracle Home Location: Veritabanının kurulacağı klasörün yerini belirtir.

Installation Type: Kurulum tipini belirtir. Standart ya da Enterprise Edition olarak belirlenir.

Create Starter Database: Bu seçenek işaretlendiğinde kurulum işlemi gerçekleştikten sonra veritabanı da oluşturulur. Aksi halde sadece Oracle 10g kurulumu gerçekleştirilecek, veritabanı yaratmak için SQL-Plus altından Create Database komutu ile veritabanı oluşturmak gerekecektir. Bu seçeneğin işaretli olmasına dikkat edin.

Global Database Name: Veritabanının adı girilir.

Database Password: Veritabanı şifresi girilir. Bu bölümde girilen şifre kesinlikle unutulmamalıdır. Oracle’da en üst seviyedeki admin kullanıcısı “sys” olarak hazır gelmekte ve burada belirlenen şifre bu kullanıcının şifresi olarak belirlenmektedir.

Confirm Password: Girilen şifre tekrar teyit amacıyla bu bölüme girilir.

Girişleri tamamladıkan sonra Next butonuna tıklayın.

Karşınıza gelen pencerede, kurulum sırasında yaptığınız seçimleri özet olarak görebilirsiniz. Değişiklik yapmak isterseniz Back butonuna tıklayarak geri dönebilirsiniz. Daha sonra Install butonuna tıklayarak devam edin.

5.

1�

163Oracle Veritabanı

Page 170: Bilge adam java.pdf

Kurulum işlemi otomatik olarak başlayacaktır.

Kurulum sırasında belirlenen ayarlar çerçevesinde konfigürasyon işlemleri otomatik olarak gerçekleştirildikten sonra işlemlerin özeti görüntülenir. Yine Next butonuna tıklayın.

2.

3�

164 Bölüm 10

Page 171: Bilge adam java.pdf

Veritabanı otomatik olarak oluşturulur.

Daha sonra, oluşturulan veritabanı ile ilgili bilgilerin özetlendiği ve şifre ayarlarının yapılabil-diği pencere gelir.

4.

5.

165Oracle Veritabanı

Page 172: Bilge adam java.pdf

Özet penceresinde yer alan Password Management butonuna tıklandığında açılan ekrandan, varsayılan kullanıcılara ilişkin şifre değişiklikleri ve kilitli/kilitsiz ayarları yapılabilir.

Belirtilen ayarların yapılmasından sonra, kurulum tamamlanır. Exit butonuna tıklayarak çıkın.

Açılan browserdan Oracle Enterprise Manager’a kullanıcı adı ve şifre ile giriş yapabilirsiniz.

6.

7.

8.

166 Bölüm 10

Page 173: Bilge adam java.pdf

TablespaceMicrosoft SQL Server’da data file olarak geçen MDF ve NDF uzantılı dosyalar Oracle’da tablespace’lerde tutulur.

system Tablespacesystem tablespace’i Oracle’ın veri sözlüğünü barındırır. Bu da Microsoft SQL Server’daki master veritabanındaki metadata tutan sys ile başlayan tablolar gibi düşünülebilir.

sysaux TablespaceEskiden system tablespace’te yer alan birtakım veriler ve özellikler 10g ile birlikte sysaux tablespace’ine alınmıştır. Oracle sisteminin kullandığı bir tablespace olarak düşünülmelidir.

Default Temporary TablespaceDefault Temporary Tablespace ilgili veritabanında çalıştırılan sorgu için bellek alanı yetersiz ge-liyorsa disk üzerinde bellek alanı gibi kullanılır. Windows ve Linux gibi işletim sistemlerinde kulla-nılan swap alanı gibi düşünülebilir.

Undo TablespaceMicrosoft SQL Server’daki Transaction Log Space gibi düşünülebilir. Herhangi bir transaction başladığında rollback ya da commit edilene kadar undo tablespace’te eski veri tutulur.

Arka Planda Çalışan ProcesslerVeritabanı sisteminin düzenli çalışabilmesi için arka planda çalışan birtakım process’lere ihtiyaç vardır. Oracle’da çalışan temel arka plan process’leri şunlardır:

dbwr – Database Writer Process: Tampon bölgelere alınan verilerin veritabanına yazılmasın-dan sorumludur.

lgwr – Log Writer Process: Online redo logları bellekte geçici olarak tutulur. Bu log’ların verita-banına aktarılmasından log writer process sorumludur.

ckpt – Chekpoint Process: Checkpoint işlemi bellekteki verilerin veritabanı üzerinde uygun bö-lümlere yazılmasından sorumludur. Checkpoint process database writer ve log writer’ı tetikleye-bilir.

167Oracle Veritabanı

Page 174: Bilge adam java.pdf

smon – System Monitor Process: System monitor process veritabanlarının bütünlüğü ve tutar-lılığından sorumludur.

pmon – Process Monitor: .NET ortamındaki garbage collector gibi düşünülebilir. Genel olarak kaynak yönetimi yaptığını söyleyebiliriz.

Oracle’da Veri Tabanı OluşturmakOracle’da veri tabanı oluşturmak için kullanılabilecek en kolay yol Oracle Database�Configuration Assistant (DBCA) kullanmaktır. DBCA’e Start > Programs > Oracle Oracle Home > Configuration and Migration Tools > Database Configuration Assistant yoluyla ulaşılır. Program açılınca bir sihirbaz aracılığıyla veri tabanını yapılandırabiliriz.

Sihirbazın ilk adımı sadece bilgilendirici bir ekrandır. Bu adımda Next butonuna tıklayarak devam edebiliriz. Bu adımdan sonra veri tabanını oluşturmak için önümüze çıkan kavramları, opsiyonlar-la birlikte değerlendireceğiz.

Sihirbazın ikinci adımında veri tabanı yönetiminde ne yapacağımızı belitmemiz gerekir. Burada ilk seçenek olan Create a Database (Veri tabanı oluştur) seçeneğini seçeceğiz. Diğer opsiyonlar ve açıklamaları da aşağıdaki gibidir; fakat sihirbazı bu seçeneklere göre ilerletmeyeceğiz.

Şekil 1: DBCA açılış ekranı.

Opsiyon Açıklama

Create a DatabaseSihirbazla adım adım veritabanı oluşturmak için kullanılır. Varolan veri tabanı şablonları kullanılabildiği gibi şablonlardan farklılaştırarak da veri tabanı oluşturulabilir.

Configure Database Options Var olan bir veri tabanının dedicated (adanmış) bir sunucudan Shared (paylaşılan) bir sunucuya taşınması için gerekli işlerin yapılmasını sağlar.

Delete a Database Var olan bir veri tabanının tamamen silinmesini sağlar.

Manage TemplatesVeritabanı şablonlarının yönetilmesini sağlar. Şablonlar yerel diskte XML formatında saklanmaktadır. Mevcut şablonlarda değişiklik yapılabilir ya da yeni bir şablon oluşturulabilir.

168 Bölüm 10

Page 175: Bilge adam java.pdf

Şekil 3’deki veri tabanı şablonu seçim ekranında yeni oluşturulacak veri tabanının yapısı belir-lenir. Herhangi bir şablonu seçerek sağ alt köşedeki Shoe Details butonuna tıklayarak şablo-nun alt yapısı hakkında bilgi alabilirsiniz, ancak bu aşamada kavramlar karmaşık gelebilir. Her şablon için genel veri tabanı özellikleri, başlangıç parametreleri, karakter setleri, veri dosyaları (tablespace’ler), kontrol dosyaları ve redo log grupları hakkında bilgileri bu pop-up’tan görebilir-siniz; ancak mevcut şablonların yapıları üzerinde değişiklik yapamazsınız. Burada hazır olarak göreceğiniz şablonlar Data Warehouse, General Purpose ve Transaction Processing’tir. Burada General Purpose seçeneğini seçip Next butonuna tıklayarak devam edebiliriz.

Şekil 2: DBCA ilk kurulum ekranı.

Şekil 3: DBCA veri tabanı şablonu seçme ekranı.

169Oracle Veritabanı

Page 176: Bilge adam java.pdf

Sihirbazın 3. adımında Şekil 4’te gördüğümüz isimlendirme ekranı gelir. Bu ekranda veri tabanı adı ve SID (system identification)’si tanımlanır. Veri tabanı adı yazarken SID’de de aynı karak-terlerin yazıldığını göreceksiniz. Bir sistemde aynı isimde birden fazla veri tabanı olabilirken aynı SID’ye sahip birden fazla veri tabanı bulunamaz. Aynı zamanda SID’nin maksimum uzunluğu 8 karakterdir. SID kısmına 8 karakterden daha uzun bir ifade yazsanız da SID 8 karaktere kısaltı-lacaktır. Bu ekranda veri tabanı adına ve SID’ye “ornek” yazıp Next butonuna tıklayarak devam edebiliriz.

Şekil 4: DBCA veri tabanı isimlendirme ekranı.

Şekil 5: DBCA yönetim seçenekleri ekranı.

170 Bölüm 10

Page 177: Bilge adam java.pdf

Şekil 5’teki yönetim seçenekleri ekranında veri tabanının Enterprise Manager (EM) ile kontrol edilip edilemeyeceği seçeneği ile birlikte uyarıların e-mail ile gönderilmesi ve backup seçenek-leri tanımlanır. Bu ekranda Configure the Database with Enterprise Manager seçeneğeni işaretli olarak bırakalım. Eğer makinenizde grid kurulumu varsa ilk opsiyon olan Use Grid Control for Database Management opsiyonu da açık olacaktır. Diğer opsiyon olan Use Database Control for Database Management seçeneği mecburen seçili olarak kalarak devam edecektir. Enable Email Notifications ve Enable Daily Backup seçeneklerini işaretlemeden devam edebiliriz.

Şekil 6’daki şifre tanımlama ekranında SYS, SYSTEM, DBSNMP ve SYSMAN kullanıcıları için şifre tanımlamaları yapmamız gerekir. Burada 2 seçenek mevcuttur. Birincisi varsayılan olarak seçili gelen Use the Same Password for All Accounts seçeneğidir. Bu seçenekte yukarıda adı geçen 4 sistem kullanıcısı için de yazılan aynı şifre geçerli olur. Eğer veri tabanını yönetirken bu 4 hesabı tek kişi kullanıyorsa hepsi için tek şifre tanımlamak daha uygun olacaktır. Diğer seçenek olan Use Different Password seçilirse 4 kullanıcının hepsi için farklı farklı şifreler tanımlanabilir. Bu noktada adı geçen kullanıcıların özelliklerini listeleyelim:

Bu ekranda Use the Same Password for All Accounts seçiliyken şifreyi 2 defa yazıp Next butonu-na tıklayarak devam edebiliriz.

Şekil 7’deki saklama seçenekleri ekranında 3 seçenek söz konusudur. Bu ekranda dikkat ede-ceğimiz bir nokta da bu aşamada Finish butonuna tıklayarak veri tabanı oluşturma işlemini ta-mamlayabilecek olmamızdır. Bundan sonraki sihirbaz ekranı buradaki seçime göre değişir. Bu seçeneklerin özellikleri şu şekildedir:

Şekil 6: DBCA şifre tanımlamaları ekranı.

Kullanıcı Özellik

SYS SYS kullanıcısı veri sözlüğünü oluşturan tüm iç Oracle tablolarının sahibidir. SYS kullanıcısıyla hiçbir işlem yapılmaması için bu hesabın kilitlenmesi tercih edilmelidir. SYS kullanıcısının sahibi olduğu nesnelerde de değişiklik yapılmamalıdır.

SYSTEM SYSTEM kullanıcısı birtakım yönetimsel tabloların ve view’ların sahibidir. Yetkisiz kullanım ihtimaline karşı kilitlenmesi ve kullanılmaması tercih edilmelidir.

DBSNMP Veri tabanı hakkında performans istatistiklerini toplamak ve görüntülemek amacıyla Enterprise Manager tarafından kullanılan kullanıcıdır.

SYSMAN Enterprise Manager’da SYS kullanıcısıyla aynı haklara sahiptir.

171Oracle Veritabanı

Page 178: Bilge adam java.pdf

Bu adımda File System seçeneğini işaretleyip Next butonuna tıklayarak devam edebiliriz.

Şekil 8’deki veri tabanı dosyaları ekranında tanımladığımız veri tabanına ait fiziksel dosyaların nereye konulacağı belirtilir. Bu adımda 3 seçenek mevcuttur. Bu seçeneklerin açıklamaları şu şekilde özetlenebilir:

Şekil 7: DBCA Diskte saklama seçenekleri ekranı.

Saklama Seçenekleri Özellik

File System En çok kullanılan seçenektir. Veri tabanının disk üzerinde normal bir veri tabanı gibi oluşturulmasını sağlar.

ASM Storage

ASM (Automatic Storage Management) için öncelikle CSS (Oracle Cluster Synchronization Service) kurulumu yapılması gerekir. Disk yönetimini File System seçeneğine göre kolaylaştırır. Birçok işi veri tabanı yöneticisi yerine Oracle kendisi yapar.

Raw DevicesVeri tabanı dosyalarını işletim sistemi yerine donanım aracılığıyla doğrudan Oracle yönetir. RAC (Real Application Cluster) veri tabanları için paylaşımlı alan olarak kullanılabilir.

Seçenek Açıklama

Use Database File Locations From Template

Daha önce seçilen şablona göre veri tabanı dosyalarının yerleri belirlenir, sonradan değiştirilebilir.

Use Common Location fo All Database Files

Veri tabanı dosyalarının yeri için farklı bir klasör tanımlamak için kullanılır, belirlenen klasör sonradan değiştirilebilir.

Use Oracle-Managed FilesDiskte saklama seçeneklerinde ASM seçildiyse bu seçenek seçilmelidir. Bu seçenek seçildiğinde dosyaların yerleri veya adları ile ilgili sonradan yapılamaz.

172 Bölüm 10

Page 179: Bilge adam java.pdf

Bu adımda Use Database File Locations From Template seçeneğini seçip Next butonuna tıkla-yarak devam edebiliriz.

Şekil 9’daki kurtarma yapılandırası ekranı backup ve kurtarma işlemlerinin yapılandırılması için kullanılır. Bu aşamada 2 seçenek mevcuttur ve her ikisi bir arada da kullanılabilir seçeneklerdir. İlk seçenek olan Specify Flash Recovery Area seçildiğinde ilgili dosyaların nerede saklanacağı ve bu alanın MB cinsinde büyüklüğü tanımlanır. Bu alan tercihen fiziksel olarak veri tabanı dos-yalarının bulunduğu yerden farklı olmalıdır. Diğer seçenek olan Enable Archiving seçeneği seçili olduğunda arşiv loglaması yapacağımızı ifade eder. DBCA kurtarma yapılandırması ekranında

Şekil 8: DBCA dosya konumlandırma ekranı.

Şekil 9: DBCA kurtarma yapılandırması ekranı.

173Oracle Veritabanı

Page 180: Bilge adam java.pdf

sadece Specify Flash Recovery Area seçeneğini işaretleyip Next butonuna tıklayarak devam edebiliriz.

Şekil 10’daki veri tabanı içeriği ekranının Database Components sekmesinde, Oracle Data Mi-ning, Oracle Text, Oracle OLAP gibi Oracle veritabanı bileşenlerinin hangilerinin kurulan verita-banı için kullanılacağı ve hangi tablespace üzerine yerleştirileceği belirlenir. Bu sekmede sample Schemas seçeneğini işaretlemeden Custom Scripts sekmesine geçelim.

Veri tabanı içeriği Custom Scripts sekmesinde, veri tabanı oluşturulduktan sonra üzerinde ça-lışmasını istediğimiz bir SQL script dosyası varsa bu dosyayı seçerek birtakım kurulumların oto-

Şekil 10: DBCA veri tabanı içeriği ekranı, Database Components sekmesi.

Şekil 11: DBCA veri tabanı içeriği ekranı, Custom Scripts sekmesi.

174 Bölüm 10

Page 181: Bilge adam java.pdf

matik olarak yapılmasını sağlayabiliriz. Bu ekranda No scripts to run seçeneğini işaretleyip Next butonuna tıklayarak devam edebiliriz.

Şekil 12’deki başlangıç parametreleri, Memory sekmesinde oluşturduğumuz veritabanı için fizik-sel bellek alanı üzerinde ne kadar yer kullanılacağını tanımlayabiliriz. Typical– Allocate memory as a percentage of total physical memory seçeneği ve Custom seçeneği bulunur. Eğer 1.seçenek seçilirse bellek yönetimini Oracle kendisi yapar. Diğer seçenekte ise bellek yönetiminde SGA (System Global Area) ve PGA (Process Global Area) için bellekte ne kadar yer ayıracağımızı belirtebiliriz. Bu sekmede 1.seçeneği işaretleyerek Sizing sekmesine geçelim.

Şekil 12: DBCA başlangıç parametreleri, Memory sekmesi.

Şekil 13: DBCA başlangıç parametreleri, Sizing sekmesi.

175Oracle Veritabanı

Page 182: Bilge adam java.pdf

Şekil 13’deki başlangıç parametreleri, Sizing sekmesinde Microsoft SQL Server’daki veri sayfa-sına (data page) karşılık gelen blok boyutu girilebilir. Transactional veri tabanları için bu boyut genellikle 8KB’dir. Data warehouse için 16KB ve üstü düşünülmelidir. Processes’de belirtilen sayı işletim sisteminden bu veritabanına açılabilecek maksimum eş zamanlı process sayısını belirtir. En başta belirtilen arka planda çalışan process’ler için en az 6 olarak tanımlanmalıdır. Burada belirtilen sayı büyüdükçe bellekte SGA olarak bu veri tabanı için ayrılacak alan büyüyecektir. Buradaki sayıyı da 150’de bırakarak Character Sets sekmesine geçelim.

Şekil 14’teki başlangıç parametreleri, Character Sets sekmesinde yerelleştirme ayarları yapılır. Bu ayarları Microsoft SQL Server’daki collation yapılandırması gibi düşünebiliriz. Use the default seçeneği işletim sisteminde o andaki seçili karakter setine göre, Use Unicode, Unicode’a göre, Choose from the list of character sets’de seçeceğimiz karakter setine göre veri tabanını yapılan-dırır. Bu 3’lü seçimin altında bulunan National Character Set Unicode olarak tanımlanmayan ka-rakter setine alternatif Unicode karakter setinin eklenmesini sağlar. Default Language, tarih, AM, PM gibi yerel ayarlar ve ORDER BY ile sıralama yapısının hangi dile göre yapılacağını belirler. Default Date Format ise tarih verilerinin hangi ülkeye, dile göre gösterileceğini tanımlar. Bu sek-mede sadece Use the Default seçeneğini seçip, diğer hiçbir seçeneği değiştirmeden Connection Mode sekmesine geçelim.

Şekil 15’teki başlangıç parametreleri, Connection Mode sekmesinde Oracle veri tabanı sunucu-suna bağlantı şekli belirtilir. Burada 2 seçenek mevcuttur. Dedicated Server Mode seçildiğinde veri tabanına bağlanan her istemci için ayrı bir kaynak ayrılır. Eğer veri tabanına bağlanan kulla-nıcı sayısı çok değişken değil ve az sayıdaysa ve bağlanan kullanıcılar çok kısa sürede bağlan-tılarını sonlandırmıyorlarsa bu seçenek seçilmelidir. 2. seçenek olan Shared Server Mode ise bir önceki seçenek için tanımlanan durumların dışında kalan uygulamalar için idealdir. Bu seçenekte kaynakların ortak kullanımı söz konusu olduğundan ne kadar ortak server process’inin oluşturula-cağı tanımlanmalıdır. Genellikle çoğu OLTP veri tabanı için Shared Server Mode, çoğu OLAP veri tabanı için de Dedicated Server Mode daha doğru seçim olacaktır. Bu sekmede Shared Server Mode seçeneğini işaretleyip, Shared Server sayısını 1 bırakıp (bu veri tabanı oluşturma işlemi örnek olduğu için 1’de bıraktık, bu sayı veri tabanının kullanım yoğunluğuna ve gelen istemlerin büyüklüklerine göre ayarlanmalıdır) Next butonuna tıklayarak devam edebiliriz.

Şekil 14: DBCA başlangıç parametreleri, Character Sets sekmesi.

176 Bölüm 10

Page 183: Bilge adam java.pdf

Şekil 16’daki veri tabanı saklama yapısı ekranından daha önce belirlediğimiz (örnek şablona göre seçtiğimiz için tek tek tanımlamadık) veri tabanına yazılacak dosyaların yerleri ve isimleriyle ilgili değişiklikleri yapabilmemizi sağlar. Bu ekrandan soldaki ağaç yapısından kontrol dosyaları, veri dosyaları ve log dosyalarının yerlerini ve yapıları görüntülenip değiştirilebilir. Burada herhangi bir değişiklik yapmadan Next butonuna tıklayarak devam edelim.

Şekil 17’deki veri tabanı oluşturma ekranı DBCA sihirbazının son ekranıdır. Bu ekranda 3 seçenek mevcuttur. Create Database seçeneği tanımladığımız veri tabanının fiziksel olarak oluşturulması-nı sağlar. Save as a Database Template seçeneği yapılandırdığımız veri tabanı yapısının şablon olarak saklanmasını sağlar. Generate Database Creation Scripts seçeneği de yapılandırdığımız

Şekil 15: DBCA başlangıç parametreleri, Connection Mode sekmesi.

Şekil 16: DBCA veri tabanı saklama yapısı ekranı.

177Oracle Veritabanı

Page 184: Bilge adam java.pdf

veri tabanı yapısnın script’inin oluşturulmasını sağlar. Bu ekrandaki seçeneklerini herhangi birini, ikisini ya da hepsini seçebiliriz. Sadece Create Database seçeneğini seçerek Finish butonuna tıklayarak tanımladığımız veri tabanını oluşturalım.

Sihirbaz veri tabanını oluşturmadan önce tüm parametreleri özet şeklinde çıkarır. Bu ekran üze-rinden değişiklik yapılamaz. Save as an HTML file seçeneğiyle bilgi olarak saklamak faydalı ola-bilir. OK butonuna tıkladığımızda veri tabanı oluşturulmaya başlayacaktır.

Şekil 17: DBCA veri tabanı oluşturma ekranı.

Şekil 18: Veri tabanı parametreleri ekranı.

178 Bölüm 10

Page 185: Bilge adam java.pdf

Şekil 19’da veri tabanının oluşturulma sürecini görebilirsiniz. Böylece Oracle üzerinde örnek veri tabanı oluşturma işlemini tamamlamış olduk.

Temel Veri Tiplerivarchar2: 4000 taneye kadar karakter tutabilen veri tipidir. Microsoft SQL Server’daki varchar veri tipi gibi düşünülebilir. Eğer saklanacak verinin başında ya da sonunda boşluk (space) karak-teri varsa bunları silerek tutar.

nvarchar2: 4000 taneye kadar Unicode karakter tutabilen veri tipidir. Microsoft SQL Server’daki nvarchar veri tipi gibi düşünülebilir. Eğer saklanacak verinin başında ya da sonunda boşluk (spa-ce) karakteri varsa bunları silerek tutar.

char: 2000 taneye kadar sabit uzunluklu karakter tutabilen veri tipidir. Microsoft SQL Server’daki char veri tipi gibi düşünülebilir.

nchar: 2000 taneye kadar sabit uzunluklu Unicode karakter tutabilen veri tipidir. Microsoft SQL Server’daki nchar veri tipi gibi düşünülebilir.

number: Her türlü sayısal verilerin tutulabileceği veri tipidir. Microsoft SQL Server’daki int, flo-at gibi veri tiplerine karşılık olarak düşünülebilir. Dikkat edilmesi gereken nokta Microsoft SQL Server’daki decimal gibi tanımlanmasıdır.

date: Saniye bazında tarih ve zaman verisi tutar. Geçerli tarih aralığı MÖ 1 Ocak 4712’den MS 31 Aralık 9999’a kadardır. Microsoft SQL Server’daki smalldatetime veri tipi gibi düşünülebilir.

timestamp: date tipine çok benzeyen bir veri tipidir. date tipine göre daha detaylı zaman bilgisi tutar. Microsoft SQL Server’daki datetime veri tipi gibi düşünülebilir.

clob (character large object): 4 GB’a kadar karakter verisi tutar. varchar2’nin büyütülmüş bir tipi olarak düşünülebilir. Microsoft SQL Server 2005 ile birlikte gelen varchar(max) veri tipi gibi düşünülebilir.

blob (binary large object): clob’a benzer bir veri tipi olmakla birlikte içinde tuttuğu veri tipi binary’dir. Maksimum büyüklüğü 4 GB’tır. Microsoft SQL Server’daki text, image tiplerine ben-zerdir.

Oracle’da Kullanıcı Yönetimi ve GüvenlikOracle sisteminde kullanıcı yönetimi ve güvenlik Microsoft SQL Server’a göre daha detaylıdır; çünkü Microsoft SQL Server sadece Microsoft Windows ailesi işletim sistemlerinde çalışırken

Şekil 19: Veri tabanı oluşturma ekranı.

179Oracle Veritabanı

Page 186: Bilge adam java.pdf

Oracle Microsoft Windows ailesi, UNIX türevleri ve Linux türevleri üzerinde de çalışmaktadır. Bu sebeple kullanıcı yapısı farklılıklar göstermektedir. Örneğin Microsoft SQL Server’da olan “Win-dows Authentication” Oracle için geçerli değildir; ancak bunu karşılayan farklı bir yapı mevcuttur. Ayrıca Oracle’da kullanıcı, hesap ve şema (schema) ifadeleri aynı anlamda kullanılabilir. Kimlik denetleme yöntemlerine geçmeden önce kimlik denetiminde kullanılan bazı kavramları tanımla-yalım.

Default Tablespace: Bir kullanıcının oluşturduğu/oluşturacağı nesnelerin (schema objects), nesne oluşturulurken nesnelerin hangi tablespace üzerinde tutulacağı belirtilmediğinde default olarak tutulduğu tablespace’tir. Kullanıcı tanımlanırken belirtilmezse, veri tabanı kendi default tablespace’ini kullanıcıya da default tablespace olarak atar.

Ara İşlemler İçin Kullanılan (Temporary) Tablespace: Temporary tablespace üzerinde GROUP BY, ORDER BY, DISTINCT, JOIN ve index oluşturma gibi geçici alan ihtiyacı olan işlemlerde kul-lanılan tablespace’tir, aynı zamanda geçici tablolar için de kullanılır. Kullanıcı tanımlanırken belir-tilmezse, veri tabanı kendi default tablespace’ini kullanıcıya da default tablespace olarak atar.

Profiller: Kullanıcı yönetimini kolaylaştıran bir mekanizmadır. Her kullanıcı mutlaka bir profil al-tında tanımlıdır. Kaynakların kullanınımı profil tanımına göre kısıtlar ve şifre kurallarının tanımlan-masını sağlar. Kullanıcı tanımlanırken belirtilmezse, kullanıcı Oracle default profile atanır.

Authentication (Kimlik Denetleme) YöntemleriOracle’da 3 kimlik denetleme yöntemi vardır. Bu yöntemler şu şekildedir:

Password Authentication

External Authentication

Global Authentication

Password AuthenticationMicrosoft SQL Server’daki SQL Authentication ile eşleniktir. Kullanıcılar Oracle veri tabanı üze-rinde tanımlıdır. Oracle kullanıcıya ait şifreyi üzerinde şifreli olarak tutar. Password Authentication ile kullanılacak bir kullanıcı şöyle tanımlanır:

CREATEUSERkayaIDENTIFIEDBYqwedcv89;

Burada “kaya” kullanıcının adıyken “qwedcv89” bu kullanıcın şifresidir.

Bu kullanıcıya ait bir default tablespace; yani oluşturacağı nesnelerin tutulacağı bir tablespace belirtmek istersek;

CREATEUSERkayaIDENTIFIEDBYqwedcv89

DEFAULTTABLESPACExyz;

ifadesini kullandığımızda bu kullanıcının nesnelerinin yaratılacağı default tablespace xyz adlı tablespace olacaktır. Eğer “kaya” kullanıcısı daha önceden oluşturulduysa ALTER ifadesi ile de default tablespace tanımlayabiliriz.

ALTERUSERkayaDEFAULTTABLESPACExyz;

Bu kullanıcı için bir de geçici tablespace tanımlamak istersek;

CREATEUSERkayaIDENTIFIEDBYqwedcv89DEFAULTTABLESPACExyzTEMPORARYTABLESPACEabc;

ifadesini kullanabiliriz. Bu durumda “kaya” kullanıcısının çalıştırdığı büyük veri üzerinde işlem yapıp geçici alanlar kullanan sorgular, geçici tablespace olarak abc tablespace’ini kullanacaktır.

1�

2.

3�

180 Bölüm 10

Page 187: Bilge adam java.pdf

Profil tanımlamak için de şu şekilde bir ifade kullanabilirsiniz:

CREATEUSERkayaIDENTIFIEDBYqwedcv89DEFAULTTABLESPACExyzTEMPORARYTABLESPACEabc

PROFILEprf1;

External AuthenticationExternal authentication Microsoft SQL Server’daki Windows authentication’a çok benzerdir. Kul-lanıcılar yine veri tabanında tutulur; ancak kimlik denetlemesini işletim sistemi yapar. Microsoft SQL Server’daki Windows authentication’dan en önemli farkı sadece Microsoft Windows’la değil diğer işletim sistemleri ile de entegre çalışabilmesidir. Bu tip kullanıcılar OPS$ kullanıcıları olarka da adlandırılırlar. External authentication mekanizmasıyla bir kullanıcı tanımlamak için;

CREATEUSERops$kayaIDENTIFIEDEXTERNALLY;

ifadesini kullanabiliriz. Bu durumda işletim sistemi üzerinde kullancı adı “kaya” olan kullanıcı, Oracle sistemine, ilgili işletim sistemi üzerinden onaylanarak girecektir. Bu işlem Linux ve UNIX türevleri için oldukça kolaydır; ancak Windows üzerinde bir miktar karmaşıktır. Linux ve UNIX türevlerinde /etc/passwd içinde kullanıcının tanımlanmış olması yeterlidir. Windows üzerindeki bir kullanıcıyı Oracle’da tanımlamak için yapmamız gerekenler şu şekildedir:

Windows işletim sistemi üzerinde kullanıcıyı tanımlayın.

Tanımladığınız kullanıcıyı Windows üzerinde ora_dba grubuna ekleyin.

Start > Programs > Oracle - OraDb10g_home1 > Configuration and Migration Tools > Ad-ministration Assistant for Windows üzerinden OS Database Administrators ve OS Database Operators gruplarına ekleyin.

SPFILE dosyasında OS_AUTHENT_PREFIX=OPS$ şeklinde tanımlana yapın.

CREATE USER OPS$kullanici IDENTIFIED EXTERNALLY; ifadesini SQL Plus üzerinde çalıştırın.

Global AuthenticationOracle üzerinde Microsoft SQL Server’dan farklı olarak bulunan bir authentication mekanizması-dır. Authentication işlemi, gelişmiş güvenlik opsiyonu ile sağlanan bir servis aracılığıyla sağlanır ve password authentication’daki şifrelerin tutulması söz konusu değildir. Burada kullanılan me-kanizmalara örnek olarak biyometrik yöntemler, Kerberos ve X.509 sertifikaları sayılabilir. Diğer mekanizmalara göre oldukça detaylı bir yöntemdir.

1�

2.

3�

4.

5.

181Oracle Veritabanı

Page 188: Bilge adam java.pdf
Page 189: Bilge adam java.pdf

11 Oracle Üzerinde Programlama

Page 190: Bilge adam java.pdf

11 Oracle Üzerinde

Programlama

PL/SQL Nedir?

SQL Plus

TOAD

PL/SQL ile Programlama

PL/SQL’de Kontrol Yapıları

PL/SQL’de Alfanümerik Tipler

PL/SQL’de Mantıksal Tipler

PL/SQL’de Tarih ve Zaman Tipleri

Referans Tipleri

LOB (Large Object) Tipleri

Page 191: Bilge adam java.pdf

Oracle Üzerinde ProgramlamaPL/SQL Nedir?PL/SQL’i (Procedural Language Extensions to the Structured Query Language) Microsoft SQL Server’daki T-SQL’in (Transact SQL)�Oracle sistemindeki karşılığı olarak düşünebilirsiniz. T-SQL gibi PL/SQL de standart SQL dilinin, günün gereksinimleri bağlamında yetersiz kalması çerçeve-sinde ortaya çıkmıştır. PL/SQL ile stored procedure, trigger gibi veri tabanı nesneleri oluşturabi-lirsiniz. PL/SQL ifadeleri Oracle veri tabanı üzerinde çalışır.

PL/SQL dil olarak ilk bakışta bir miktar yabancı gelebilir; ancak yeterli veri tabanı bilginiz varsa alışmanız çok zor olmayacaktır. Her dilde olduğu gibi bol bol pratik, PL/SQL’deki yetkinliklerinizi çabuk geliştirmeniz açısından çok faydalı olacaktır. T-SQL’den tanıdığınız standart SQL dilinin kapsadığı bütün ifadeleri burada da kullanabileceksiniz. Bildiğiniz 4 temel SQL ifadesi olan SE-LECT, INSERT, UPDATE, DELETE ifadelerini aynen kullanabilirsiniz.

PL/SQL ifadelerini yazmak için kullanabileceğiniz temel ortam, Oracle yüklemesiyle birlikte gelen SQL Plus’tır. SQL Plus’ı Microsoft SQL Server 2000 ve öncesindeki Query Analyzer, Microsoft SQL Server 2005’te SQL Server Management Studio’daki Query Window’a karşılık gelen bir araç olarak düşünebilirsiniz; ancak her ikisine göre de daha ilkel bulabilirsiniz.

SQL PlusSQL Plus’ı Start > Programs > Oracle – OraDb10g_home1 > Application Development > SQL Plus yoluyla çalıştırabilirsiniz. Çalıştırdığınızda karşınıza Şekil – 1’deki ekran görüntüsü gelecek-tir.

Programı ilk açtığınızda Log On ekranı karşınıza gelecektir. Bu ekranda User Name bölümüne tanımladığınız kullanıcılardan birini girmeniz gerekir. Veri tabanı oluştururken tanımlanan 4 kul-lanıcımız vardı, bunlardan SYSTEM kullanıcısını burada kullanabiliriz. Host String bölümüne de veri tabanımızın adını yazmalıyız. Host String’te kullanabileceğimiz veri tabanlarını tnsnames.ora dosyasından da bulabiliriz. Bunun için Windows Search ile tnsnames.ora dosyasını aratabilirsi-niz. Başarılı bir şekilde login olduğunuzda karşınıza Şekil 2’deki gibi bir ekran gelecektir.

Şekil 1: SQL Plus Açılış Ekranı.

Page 192: Bilge adam java.pdf

Önce SQL Plus üzerinden veri tabanımızda basit bir tablo oluşturalım. Bunun için standart SQL’den bildiğimiz CREATE TABLE ifadesini kullanacağız. Bu tablonun oluşturulmasını Şekil 3’de görebilirsiniz.

Bu tabloyu oluşturduktan sonra tabloya veri girişi için;

INSERT INTO Urun ( UrunId, UrunAdi) VALUES ( 1, ‘Çikolata’);

yazalım. İfadelerin sonunda noktalı virgül “;” koymayı unutmayın. Microsoft SQL Server’da yaz-dığımız ifadelere göre ifadelerin sonunda “;” bulunması gerekir. Ayrıca bu ifadeyi ya da ifade bloğunu çalıştırmak için Enter’a basmanız yeterlidir.

Benzer şekilde bir sorgu yapmak için de SQL Plus’ta

SELECT * FROM Urun;

yazarak Urun tablosunun içindeki verileri inceleyebiliriz. Yazdığımız bu ifadeleri SQL Plus ekra-nında Şekil 4’te görebilirsiniz.

Şekil 2: SQL Plus Açılış Ekranı – 2.

Şekil 3: Tablo oluşturmak.

186 Bölüm 11

Page 193: Bilge adam java.pdf

TOADSQL Plus’a daha iyi bir alternatif olarak TOAD’u kullanabilirsiniz. http://www.toadsoft.com/lic_ag-ree.html adresinden TOAD’un Oracle için ücretsiz (freeware) versiyonunu indirebilirsiniz.

TOAD Oracle, Microsoft SQL Server, IBM DB2 ve mySQL gibi veri tabanları için kullanılabilen bir araçtır. TOAD’u Microsoft SQL Server 2005 Management Studio gibi düşünebilirsiniz. Hem yönetim hem de programlama arayüzlerini birlikte sunar.

Şekil 5’teki TOAD’un login ekranını Microsoft SQL Server Login ekranına benzer olarak düşüne-bilirsiniz. Bağlanacağınız veri tabanını, hangi kullanıcı ile hangi rolle ve hangi sunucuya bağlana-cağınızı belirterek TOAD’un ana ekranına geçebilirsiniz. Dikkat edeceğiniz gibi Windows Authen-tication şeklinde bir seçenek bulunmaz. Oracle’da Windows Authentication şeklinde bir seçenek bulunmaz; ancak external authentication ile Windows kullanıcıları ile Oracle sistemine login ola-bilirsiniz. Bu opsiyonu kurmak Microsoft SQL Server kadar kolay ve düz değildir. Bu sebeple Oracle’ın kendi kullanıcı (schema) sistemini kullanarak devam edeceğiz. TOAD login ekranında bilgileri doğru olarak girip Connect butonuna tıkladığımızda ana ekrana geçebiliriz.

Şekil 4: SQL Plus’ta SQL İfadeleri.

Şekil 5: TOAD Login Ekranı.

187Oracle Üzerinde Programlama ve PL/SQL

Page 194: Bilge adam java.pdf

TOAD ana ekranında Şekil 6’dan gördüğünüz gibi pek çok işi yapabilirsiniz. Buraya standart SQL ve PL/SQL sorgularınızı yazarak çalıştırabilirsiniz. Sorgu yazarken, eğer sorguda nesne kullanı-yorsak dikkat etmemiz gereken nokta nesne adından önce schema adını yazmamız gerekliliği-dir. Schema’ları Microsoft SQL Server 2005’teki schema’lara denk olarak düşünebiliriz. SYSTEM kullanıcısını da Microsoft SQL Server 2005’deki dbo’ya karşılık gibi görebiliriz. Aslında birebir bu şekilde denkleştirmeler söz konusu olmasa da bu benzetmeleri bir kolaylık olarak görebilirsiniz.

Şekil 6: TOAD ana ekranı.

Şekil 7: TOAD’da sorgu.

188 Bölüm 11

Page 195: Bilge adam java.pdf

TOAD’da sorgu yazmayı Şekil 7’de görebilirsiniz. SQL ifadelerinin sonunda “;” kullanmanız ya da kullanmamanız sorgu sonucunu değiştirmez. Sorguda daha önce oluşturduğumuz Urun tab-losunu SYSTEM.Urun olarak kullandığımıza dikkat edin. Bu şekilde yazmazsanız hata alırsınız. Sorguyu çalıştırmak için klavyeden F5 tuşunu kullanabilirsiniz. Bununla birlikte TOAD üzerindeki toolbar’dan da sorguları çalıştırabilirsiniz. Sorgu çalıştırabileceğiniz butonları Şekil 8’den görebi-lirsiniz.

PL/SQL ile ProgramlamaPL/SQL ile programlamaya basit bir örnek ile başlayalım. T-SQL’dekine göre muhtemelen en çok zorlayacak durum PL/SQL içinde kullanılabilecek fonksiyonların çokluğu olacaktır. PL/SQL’de büyük ya da küçük harf kullanarak kod yazabilirsiniz.

Uygulama 1: PL/SQL ile İlk Örnek Uygulama

1DECLARE

2 UrunSayisiINTEGER;

3 BEGIN

4 SELECT

5 COUNT(*)INTOUrunSayisi

6 FROMUrun;

7 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi:‘||UrunSayisi);

8 END;

Uygulama 1’deki kod oldukça basit bir uygulamadır; ancak PL/SQL konusunda oldukça önemli bilgiler verir. Bu örnekte 1 ve 2 numaralı satırlar tanımlama (declaration) bloğudur. Altındaki kod bloğunda kullanılacak değişkenler, parametreler gibi yapılar burada tanımlanır. Örneğimizde 2 numaralı satırda INTEGER tipinde, UrunSayisi adında bir değişken tanımlanmıştır. 3 numaralı satırda çalıştırma bloğunun (execution block) başladığını gösteren BEGIN ifadesi bulunuyor. Ör-nekteki 8 numaralı satırda bulunan END ifadesine kadar tüm ifadeler çalıştırma bloğunun içinde-dir. 4, 5 ve 6 numaralı satırlarda Urun tablosu içindeki satır sayısını UrunSayisi değişkeninin içine atan basit bir sorguyu görebilirsiniz. 5 numaralı satırdaki INTO ifadesini T-SQL’de kullandığımız değişkene değer atamadaki “=” gibi düşünebilirsiniz. 7 numaralı satırda ise T-SQL’deki print�ifadesine benzer bir iş yapan DBMS_OUTPUT.PUT_LINE fonksiyonu bulunuyor. DBMS_OUTPUT.PUT_LINE DBMS Output tamponuna yazma işlemi yapar. Bu fonksiyonun içinde kullandığımız || işaretini T-SQL’de alfanümerik ifadeleri birleştirmek için kullandığımız + işaretinin yerine kul-lanıyoruz. T-SQL’de print ifadesinde bu şekilde bir çıktı almak için ise tanımladığımız int�de-ğişkeni öncelikle alfanümerik bir tipe çevirmemiz gerekir, çünkü print 2 ifadeyi otomatik olarak alfanümeriğe dönüştürmez. Buradan da anlayacağımız gibi DBMS_OUTPUT.PUT_LINE fonksiyo-nu otomatik çevirme (implicit conversion) yapmaktadır. Burada T-SQL’de kullandığımız SELECT @UrunSayisi gibi bir ifade ile değişkenin taşıdığı değeri yazdıramayız. 8 numaralı satırda da çalışma bloğu sona ermektedir. Bu örneğin T-SQL’deki benzer karşılığını Uygulama 1.1’de ince-leyebilirsiniz.

Şekil 8: TOAD sorgu çalıştırma butonları.

189Oracle Üzerinde Programlama ve PL/SQL

Page 196: Bilge adam java.pdf

Uygulama 1.1: Uygulama – 1’deki PL/SQL Kodunun T-SQL’deki Eşleniği

1DECLARE@UrunSayisiint

2SELECT

3 @UrunSayisi=COUNT(*)

4 FROMUrun

5PRINT‘UrunSayisi:’+CONVERT(varchar,@UrunSayisi)

Uygulama 1’deki örneği TOAD’da çalıştırdığınızda herhangi bir çıktı göremezsiniz. Çünkü DBMS_OUTPUT.PUT_LINE fonksiyonu bir çalışma ekranında bir sonuç üretmez bir tampona yazar. TOAD ile bu tampon bölgeyi görüntüleyebiliriz. Bunun için örnek uygulamayı çalıştırmadan önce View menüsünden DBMS Output seçeneğini seçin. Karşınıza boş bir ekran gelecektir. Standart Windows uygulamalarında olduğu gibi, daha önceden kod yazdığınız pencereye dönmek için Ctrl-Tab kullanabilirsiniz ya da TOAD’un Window menüsünden diğer pencereye geçiş yapabilirsiniz.

Şekil 9’da görebileceğiniz gibi burada satır sayısı ile ilgili herhangi bir sonuç göremiyoruz, sadece PL/SQL procedure successfully completed ifadesini görebilirsiniz.

Şekil 9: Uygulama 1’in çalışmasında sorgu ekranı.

Şekil 10: TOAD DBMS Output penceresi.

190 Bölüm 11

Page 197: Bilge adam java.pdf

Şekil 10’da TOAD DBMS Output penceresini görebilirsiniz. Burada DBMS_OUTPUT.PUT_LINE�ifadesinin sonucu olan Urun Sayisi: 2 string’i yazılmıştır.

PL/SQL’de Kontrol YapılarıPL/SQL’de T-SQL’deki gibi IF-THEN-ELSE kontrol yapısı bulunur. Bununla birlikte T-SQL’de bulunmayan CASE yapısı da mevcuttur. CASE yapısı C#’taki ve Java’daki switch yapısı şeklinde çalışır.

IF-THEN-ELSEUygulama 2: PL/SQL ile IF-THEN-ELSE

1DECLARE

2 UrunSayisiINTEGER;

3 BEGIN

4 SELECT

5 COUNT(*)INTOUrunSayisi

6 FROMUrun;

7 IFUrunSayisi<=2

8 THEN

9 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denazyada2’);

10 ELSE

11 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denfazla...’);

12 ENDIF;

13 END;

Uygulama 2’deki kodun 7, 8, 9, 10, 11 ve 12 numaralı satırlarda IF-THEN-ELSE yapısını göre-bilirsiniz. PL/SQL’deki IF-THEN-ELSE yapısı T-SQL’deki IF-ELSE bloğu ile aynı şekilde çalışır. Uygulama 2.1’de Uygulama 1’deki PL/SQL kodunun T-SQL eşleniğini inceleyebilirsiniz.

Uygulama 2.1: Uygulama 1’deki Kodun T-SQL Eşleniği

1DECLARE@UrunSayisiint

2SELECT

3 @UrunSayisi=COUNT(*)

4 FROMUrun

5IF@UrunSayisi<=2

6 PRINT‘Urunsayisi2’+char(39)+‘denazyada2’

7ELSE

8 PRINT‘Urunsayisi2’+char(39)+‘denfazla...’

IF-THEN-ELSIF-ELSEIF yapısının en detaylı şekli ELSIF ile kullanılan şeklidir. ELSIF (ELSE IF’in kısaltması) yapısı T-SQL’deki ELSE IF ile aynı şekilde çalışır. ELSIF, üstündeki IF ya da ELSIF bloğundan false ile çıkıldığında çalışır ve tanımladığı koşul true sonuç veriyorsa bloğu çalıştırır; aksi takdirde ken-dinden sonra gelen bloğa geçer.

191Oracle Üzerinde Programlama ve PL/SQL

Page 198: Bilge adam java.pdf

Uygulama 3: PL/SQL ile ELSIF

1DECLARE

2 UrunSayisiINTEGER;

3 BEGIN

4 SELECT

5 COUNT(*)INTOUrunSayisi

6 FROMUrun;

7 IFUrunSayisi<2

8 THEN

9 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denaz...’);

10 ELSIFUrunSayisi>2

11 THEN

12 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denfazla...’);

13 ELSE

14 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

15 ENDIF;

16 END;

Uygulama 3’de 7 numaralı satırda eğer UrunSayisi 2’den küçük değilse 10 numaralı satırdaki ELSIF çalışır. Eğer UrunSayisi 2’den büyükse 12 numaralı satır çalışır. Eğer UrunSayisi�2’den de büyük değilse 2’ye eşit demektir. Bu durumda da 13 numaralı satırdan dolayı 14 numa-ralı satır çalışır.

Eğer IF yapısı içerisinde bir blok oluşturumak istersek bunun için T-SQL’de olduğu gibi BEGIN-END blok yapılandırıcıları ile bloğu tanımlamalıyız.

Uygulama 3.1: PL/SQL ile ELSIF

1DECLARE

2UrunSayisiINTEGER;

3BEGIN

4SELECT

5COUNT(*)INTOUrunSayisi

6FROMUrun;

7IFUrunSayisi<2

8THEN

9DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denaz...’);

10ELSIFUrunSayisi>2

11THEN

12BEGIN

13DBMS_OUTPUT.PUT_LINE(‘ELSIFblogu...’);

14DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denfazla...’);

15END;

16ELSE

192 Bölüm 11

Page 199: Bilge adam java.pdf

17DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

18ENDIF;

19END;

Uygulama 3.1’de 10 numaralı satırdan başlayan ELSIF bloğu 15 numaralı satıra kadar de-vam eder. Eğer UrunSayisi 2’den büyükse ELSIF içinde tanımlanan her 2 DBMS_OUTPUT.PUT_LINE ifadesi de çalışacaktır. Her ne kadar yazdığımız BEGIN-END blok yapılandırıcılarını kullanmak zorunda olmasak da kodun okunurluğunu artırmak açısından blok yapılandırıcılarını kullanmak faydalıdır.

İç İçe IF YapılarıPL/SQL’de iç içe IF yapıları da kullanılabilir. Çalışma şekli C#, Java ya da T-SQL’den farklı de-ğildir.

Uygulama 4: PL/SQL ile İç İçe IF Yapısı

1DECLARE

2 UrunSayisiINTEGER;

3 UrunSayisiBINTEGER;

4 BEGIN

5 SELECT

6 COUNT(*)INTOUrunSayisi

7 FROMUrun;

8 SELECT

9 COUNT(*)INTOUrunSayisiB

10 FROMUrun

11 WHEREUrunAdiLIKE‘B%’;

12 IFUrunSayisi<2

13 THEN

14 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denaz...’);

15 IFUrunSayisiB=1

16 THEN

17 DBMS_OUTPUT.PUT_LINE(‘Bilebaslayanurunsayisi:’||UrunSayisiB);

18 ENDIF;

19 ELSIFUrunSayisi>2

20 THEN

21 BEGIN

22 DBMS_OUTPUT.PUT_LINE(‘ELSIFblogu...’);

23 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denfazla...’);

24 END;

25 ELSE

26 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

27 ENDIF;

28 END;

193Oracle Üzerinde Programlama ve PL/SQL

Page 200: Bilge adam java.pdf

Uygulama 4’te 8 ile 11 numaralı satırlardaki SELECT ifadesinde UrunSayisiB değişkenine B harfiyle başlayan ürünlerin sayısı atanacaktır. Eğer UrunSayisi 2’den küçükse 15 numaralı satırdaki iç IF yapısı da çalışacaktır. Eğer UrunSayisiB 1’e eşitse de 17 numaralı satır çalışa-caktır.

IF Yapısı ile İlgili Dikkat Edilmesi Gereken NoktalarHer IF için mutlaka bir END IF bulunmalıdır.

Her END IF kendinden önceki ilk IF ifadesine aittir.

END IF birleşik yazılmaz.

END IF’in sonunda mutlaka “;” bulunmalıdır.

ELSIF yazarken ELSE’in son “E” harfi yoktur.

CASECASE yapısı C# ve Java’daki switch yapısı gibi çalışır. IF-THEN-ELSIF-ELSE yapısını daha kolay ve okunaklı hale getirir. PL/SQL’deki CASE yapısını T-SQL’de SELECT ifadesinin içinde kullanılan CASE ifadesiyle karıştırmamak gerekir. T-SQL’deki CASE yapısı result set’in içindeki tüm kayıtlar için tek tek çalışırken PL/SQL’de kayıtlar bazında çalışmaz. Kod yazımı olarak her ikisi de birbirine çok benzerdir.

Uygulama 5: PL/SQL’de CASE Örneği 1

1DECLARE

2 UrunSayisiINTEGER;

3 BEGIN

4 SELECT

5 COUNT(*)INTOUrunSayisi

6 FROMUrun;

7 CASEUrunSayisi

8 WHEN2THEN

9 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

10 WHEN3THEN

11 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

12 ELSE

13 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi3‘||‘’’’||‘tenfazla...’);

14 ENDCASE;

15 END;

Uygulama 4’te 7 – 14 numaralı satırlar CASE bloğunu oluşturur. 7 numaralı satırdaki CASE Urun-Sayisi ifadesi UrunSayisi değişkeninin karşılaştırmada kullanılacağını gösterir. 8 numaralı satır eğer UrunSayisi değişkeninin 2’ye eşitliğini kontrol eder. Eğer 2’ye eşitse 9 numaralı satı-ra geçer, eşit değilse 10 numaralı satır ve UrunSayisi değişkeninin 3’e eşit olup olmadığı kon-trol eder. 3’e eşit olması halinde 11 numaralı satır çalışr; aksi takdirde 12 numaralı satırdaki ELSE�ifadesine gelir. PL/SQL’de CASE yapısında ELSE ifadesi C# ve Java’daki switch ifadesindeki default gibi çalışır. Eğer ELSE’ten önce gelen WHEN ifadelerinin hiçbirinde true oluşmazsa ELSE�bloğu çalışır. WHEN bloklarının sonunda C# ve Java’daki break ifadesinin yerine kullanılması gereken herhangi bir ifade yoktur.

Uygulama 5’teki yapıyı IF-ELSIF-ELSE ile kurmak daha doğru olacaktır. Uygulama 3’deki gibi bir IF yapısını CASE ile yazmak istersek PL/SQL bu konuda bize esneklik sağlamaktadır.

1�

2.

3�

4.

5.

194 Bölüm 11

Page 201: Bilge adam java.pdf

Uygulama 6: PL/SQL’de CASE Örneği 2

1DECLARE

2 UrunSayisiINTEGER;

3 BEGIN

4 SELECT

5 COUNT(*)INTOUrunSayisi

6 FROMUrun;

7 CASETRUE

8 WHENUrunSayisi<2THEN

9 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denaz...’);

10 WHENUrunSayisi>2THEN

11 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denfazla...’);

12 ELSE

13 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

14 ENDCASE;

15 END;

Uygulama 6’da 7 numaralı satır her durumda çalışacaktır. 8 numaralı satırda UrunSayisi�de-ğişkeninin değerinin 2’den küçük olup olmadığı kontrol edilir. Eğer 2’den küçükse 9 numaralı satır çalışır; aksi takdirde 10 numaralı satırda UrunSayisi değişkeninin değerinin 2’den büyük olup olmadığı kontrol edilir. Eğer 2’den büyükse 11 numaralı satır çalışır; aksi takdirde 12 numaralı satırdaki ELSE ifadesi çalışır. Bu noktadan sonraki çalışma Uygulama 5’teki ELSE bloğu ile aynı şekildedir.

Uygulama 6’daki örneğe benzer olarak CASE ifadesinini farklı bir kullanımı daha vardır. CASE’in bu kullanımı esnekliği daha da artırır ve özellikle karmaşık mantıksal işlemler için idealdir.

Uygulama 7: PL/SQL’de CASE Örneği 3

1DECLARE

2UrunSayisiINTEGER;

3UrunSayisiBINTEGER;

4BEGIN

5SELECT

6COUNT(*)INTOUrunSayisi

7FROMUrun;

8SELECT

9COUNT(*)INTOUrunSayisi

10FROMUrun

11WHEREUrunAdiLIKE‘B%’;

12CASE

13WHENUrunSayisi<2ANDUrunSayisiB=1THEN

14DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denaz...’);

15WHENUrunSayisi>2ANDUrunSayisiB<1THEN

195Oracle Üzerinde Programlama ve PL/SQL

Page 202: Bilge adam java.pdf

16 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘||‘’’’||‘denfazla...’);

17 ELSE

18 DBMS_OUTPUT.PUT_LINE(‘UrunSayisi2‘);

19 ENDCASE;

20 END;

Uygulama 7’de 12 numaralı satırdaki CASE ifadesi ne olursa olsun çalışacaktır ve CASE ile 1’den fazla sayıda değişken kontrol edilebilecektir.

Şu ana kadar yaptığımız örnekleri TOAD yerine SQL Plus ile yapmak istediğinizde yazarken dik-kat etmeniz gereken birkaç nokta vardır. DBMS_OUTPUT.PUT_LINE fonksiyonunun çalışması için SET SERVEROUTPUT ON ifadesini bir kere çalıştırmalısınız. Bu ifadeyi Microsoft SQL Server’daki direktiflere benzetebilirsiniz. SET SERVEROUTPUT ON ifadesi TOAD’daki View menüsündeki DBMS Output öğesinin açılması işlevini görür. SET SERVEROUTPUT ON ifadesini çalıştırdıktan sonra PL/SQL bloğunu yazabiliriz. Bloğun sonunda “/” işaretini kullandığımızda yazdığımız blok çalışacaktır. Şekil 11’de SQL Plus ile PL/SQL bloklarının nasıl çalıştırıldığına yönelik ekran çık-tısını görebilirsiniz.

PL/SQL’de DeğişkenlerPL/SQL’de veri tipleri 4 ana gruba ayrılır. Bu gruplar:

Basit (skaler) Tipler: T-SQL’deki basit tiplere ya da Java ve C#’taki değer tipli değişkenlere benzetilebilir. Herhangi bir anda doğrudan tek değer taşırlar, bellekte doğrudan tutulurlar.

Bütünleşik (kompozit) Tipler: Dizi gibi kendi içinde tek tek işlenebilecek, T-SQL’de eksikli-ğini hissettiğimiz tiplerdir. Java ve C#’taki dizilere benzetebiliriz; ancak Java ve C#’ta dizilerin referans tipli olduğunu unutmamak gerekir.

Referans Tipleri: Bir işaretçi (pointer) aracılığıyla taşıdığı değerlere erişilebilen tiplerdir. T-SQL’de doğrudan karşılığı yoktur. Java ve C#’taki referans tipli değişkenlerle benzer mantıkta çalışırlar.

LOB (Large Object) Tipleri: Şekil, metin gibi büyük verileri tutmak için geliştirilmiş tiplerdir. T-SQL’deki text, image gibi düşünülebilir. Özünde referans tipli yapılara çok benzerdirler; çünkü taşıdıkları değer resmin ya da metnin başlangıcını gösteren bir işaretçidir.

1�

2.

3�

4.

Şekil 11: SQL Plus ile PL/SQL bloklarının çalıştırılması.

196 Bölüm 11

Page 203: Bilge adam java.pdf

PL/SQL’de bir değişkeni tanımlarken önce değişkenin adını sonra da tipini yazarız.

DECLARE <değişken adı> <tip adı>;

Herhangi bir değişkene değer ataması yaparken “:=” işaretini kullanırız.

<değişken adı> := <değer>

BASİT TİPLER BÜTÜNLEŞİK TİPLER REFERANS TİPLERİ LOB TİPLERİ

BINARY_DOUBLE RECORD REF CURSOR BFILE

BINARY_FLOAT TABLE REF object_type BLOB

BINARY_INTEGER VARRAY CLOB

DEC NCLOB

DECIMAL

DOUBLE PRECISION

FLOAT

INT

INTEGER

NATURAL

NATURALN

NUMBER

NUMERIC

PLS_INTEGER

POSITIVE

POSITIVEN

REAL

SIGNTYPE

SMALLINT

CHAR

CAHARACTER

LONG

LONG RAW

NCHAR

NVARCHAR2

RAW

ROWID

STRING

UROWID

VARCHAR

VARCHAR2

BOOLEAN

DATE

TIMESTAMP

197Oracle Üzerinde Programlama ve PL/SQL

Page 204: Bilge adam java.pdf

PL/SQL’de Sayısal TiplerSayısal tipler adlarından anlaşılabileceği gibi matematiksel işlemlerde kullanılabilecek tiplerdir. Tam sayıları, reel ve ondalıklı sayıları tutabileceğiniz pek çok tip PL/SQL’de mevcuttur.

BINARY_INTEGER32 bitlik (4 byte) işaretli (signed), tam sayısal tiptir. -231 ile 231 – 1 aralığında değerleri tutar. PLS_INTEGER tipine benzer bir tiptir. NUMBER tipine göre işlem performanı avantajı vardır ve NUMBER�tipine göre daha az yer kaplar.

NATURAL, NATURALN, POSITIVE, POSITIVEN, SIGNTYPE tipleri BINARY_INTEGER tipinin alt tipleridir.

NATURAL�ve�POSITIVE tipleri sadece pozitif sayıları taşırlar. Dolayısıyla işaretsiz tiplerdir diye-biliriz. NATURAL tipinin POSITIVE tipinden tek farkı 0 (sıfır) değerini de alabilmesidir. NATURALN�ve�POSITIVEN tiplerinin NATURAL�ve�POSITIVE tiplerinden tek farkı null değer taşıyamamala-rıdır. NATURAL, POSITIVE, NATURALN ve POSITIVEN tiplerinin taşıyabileceği en büyük değer 231 – 1’dir. SIGNTYPE ise sadece -1, 0 ve 1 değerlerini taşıyabilir.

Örnek 1: BINARY_INTEGER Tanımlama

1DECLARE

2 bixBINARY_INTEGER;

3 nxNATURAL;

4 nnxNATURALN;

5 pxPOSITIVE;

6 pnxPOSITIVEN;

7 stxSIGNTYPE;

8BEGIN

9 bix:=-55;

10 nx:=null;

11 nnx:=0;

12 px:=7;

13 pnx:=88;

14 stx=-1;

15 END;

BINARY_FLOAT ve BINARY_DOUBLEJava ve C#’taki IEEE 754 standardındaki ondalıklı tiplerdir. BINARY_FLOAT bir değer sonuna eklenen ‘f’ harfiyle (1.004f), BINARY_DOUBLE bir değer sonuna eklenen ‘d’ harfiyle (3,05478d) ayrıştırılır.

Örnek 2: BINARY_FLOAT ve BINARY_DOUBLE Tanımlama

1DECLARE

2 bfxBINARY_FLOAT;

3 bdxBINARY_DOUBLE;

4BEGIN

5 bfx:=10.054f;

6 bdx:=10.054d;

7 IFbfx=bdx

198 Bölüm 11

Page 205: Bilge adam java.pdf

8 THEN

9 DBMS_OUTPUT.PUT_LINE(‘Esit’);

10 ELSE

11 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

12 ENDIF;

13 END;

Örnek 2’deki 7 numaralı satırdaki kontrolden FALSE sonucu çıkacaktır. Bu sebeple akış 8 nu-maralı satırdan değil 10 numaralı satırdan devam edecektir ve DBMS Output penceresine “Esit degil” yazacaktır.

NUMBERPL/SQL’deki en genel sayısal tiptir. Hem tam sayıları hem de ondalıklı sayıları tutabilir. Değer aralığı 1E-130 ile 10E125’tir. NUMBER tipinde bir değişkeni sadece NUMBER olarak tanımlaya-bileceğimiz gibi hassasiyet (precission) ve ölçek (scale) değerleriyle birlikte de tanımlayabiliriz. Hassasiyet sayının toplam hane (dijit) sayısıdır, ölçek ise noktadan sonraki hane sayısıdır. Do-layısıyla hassasiyet için yazdığımız değer mutlaka ölçek için yazdığımız değerden büyük olmak zorundadır. NUMBER tipinde bir değişkeni sadece hassasiyet değeri ile de tanımlayabiliriz. Bunun anlamı ölçek değerinin yani ondalık hane sayısının 0 (sıfır) olmasıdır. En fazla 38 hanelik hassa-siyet değeri ile tanımlanabilirken ölçek değeri -84 ile 127 arasında değişir. Ölçek değerinin negatif olması tam sayının yuvarlanması anlamına gelir. Örneğin ölçek değeri -2 olan bir NUMBER değiş-kene 257 değeri 200 olarak atanacaktır.

DEC, DECIMAL, DOUBLE PRECISION, FLOAT, INTEGER, INT, NUMERIC, REAL�ve�SMALLINT�tipleri NUMBER tipinin alt tipleridir.

DEC, DECIMAL�ve�NUMERIC tipleri NUMBER gibi tanımlanırken alabileceği en büyük ölçek değeri 38’dir.

DOUBLE PRECISION� ve�FLOAT tiplerinde ondalıklı kısım 126 bitte tutulur, bu da yaklaşık 38 ondalıklı haneye karşılık gelir.

REAL tipinde ondalıklı kısım 63 bit’te tutulur, bu da yaklaşık 18 ondalıklı haneye karşılık gelir.

INTEGER, INT�ve�SMALLINT tiplerinde de en fazla hassasiyet seviyesi 38’dir. T-SQL’deki tam sayısal tipler gibi düşünmek doğru değildir; çünkü PL/SQL’deki bu tiplerde ondalıklı kısım tanım-lanabilir.

Örnek 3: NUMBER Tanımlama

1DECLARE

2 nx1NUMBER;

3 nx2NUMBER(3);

4 nx3NUMBER(3,2);

5 nx4NUMBER(3,-1);

6 ix1INTEGER;

7 ix2INTEGER(3,1);

8 dpxDOUBLEPRECISION;

9 fxFLOAT;

10 BEGIN

11 nx1:=10;

12 nx2:=267;

199Oracle Üzerinde Programlama ve PL/SQL

Page 206: Bilge adam java.pdf

13 nx3:=1.25;

14 nx4:=254;

15 ix1:=8;

16 ix2:=4.7;

17 dpx:=16.874;

18 fx:=6.8;

19 DBMS_OUTPUT.PUT_LINE(‘nx4:’||nx4);

20 IFfx=dpx

21 THEN

22 DBMS_OUTPUT.PUT_LINE(‘Esit’);

23 ELSE

24 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

25 ENDIF;

26 IFnx4=250

27 THEN

28 DBMS_OUTPUT.PUT_LINE(‘nx4=250’);

29 ELSE

30 DBMS_OUTPUT.PUT_LINE(‘nx4<>250’);

31 ENDIF;

32 END;

Örnek 3’deki kodun DBMS çıktısı;

nx4:250

Esit

nx4=250

şeklinde olacaktır. Bu örnekte nx4 değişkeninin tanımında ölçeğin -1 olmasından dolayı 254 de-ğeri 250’ye dönüştürülecektir. Eğer ölçek -2 olsaydı 200’e dönüştürülecekti. 20 numaralı satırdaki FLOAT tipinde bir değişkenle DOUBLE PRECISION tipinde bir değişkenin karşılaştırılmasında da bu tipler arasında bir önceki örnekte kullandığımız BINARY_FLOAT�ve�BINARY_DOUBLE tiplerin-den farklı olarak eşitlik olduğunu görebilirsiniz.

PLS_INTEGERPLS_INTEGER tipinde de BINARY_INTEGER tipindeki gibi -231 ile 231 – 1 arasındaki tam sayılar tutulabilir. PLS_INTEGER tipi hem NUMBER tipinden hem de BINARY_INTEGER tipinden daha hızlı çalışır. Bunun NUMBER�ve�BINARY_INTEGER işlemleri yazılımsal olarak yaparken PLS_IN-TEGER tipinin donanımsal olarak yapmasıdır.

BINARY_INTEGER tipi eski versiyonlardan bu yana gelen bir tiptir. Eğer yeni bir uygulama geliş-tiriyorsanız PLS_INTEGER tipini kullanmak daha iyi olacaktır.

Örnek 4: PLS_INTEGER Tanımlama

1DECLARE

2 pixPLS_INTEGER;

3 bixBINARY_INTEGER;

4BEGIN

5 pix:=25;

200 Bölüm 11

Page 207: Bilge adam java.pdf

6 bix:=25;

7 IFpix=bix

8 THEN

9 DBMS_OUTPUT.PUT_LINE(‘Esit’);

10 ELSE

11 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

12 ENDIF;

13 END;

Örnek 4’ü çalıştırdığınızda PLS_INTEGER tipinde taşınan bir değerle BINARY_INTEGER tipinde taşınan bir değer eğer aynıysa eşitlik sonucunu üreteceğini görebilirsiniz.

PL/SQL’de Alfanümerik TiplerAlfanümerik tiplerde sayısal olarak yorumlanmayacak karakterler ve string tipler tutulur.

CHARBelli uzunlukta alfanümerik ifadeleri tutmak için kullanılır. En fazla uzunluğu 32767 karakterdir. Eğer bir uzunluk tanımlanmazsa tek karakter tutar. CHARACTER veri tipini CHAR veri tipiyle aynı şekilde kullanabilirsiniz.

Örnek 5: CHAR Tanımlama

1DECLARE

2 cx1CHAR;

3 cx2CHAR;

4 cx3CHAR(4);

5 cx4CHARACTER;

6BEGIN

7 cx1:=‘A’;

8 cx2:=‘a’;

9 cx3:=‘ABCD’;

10 cx4:=‘A’;

11 IFcx1=cx2

12 THEN

13 DBMS_OUTPUT.PUT_LINE(‘Esit’);

14 ELSE

15 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

16 ENDIF;

17 IFcx1=cx4

18 THEN

19 DBMS_OUTPUT.PUT_LINE(‘Esit’);

20 ELSE

21 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

22 ENDIF;

23 IFcx1=SUBSTR(cx3,1,1)

24 THEN

19 DBMS_OUTPUT.PUT_LINE(‘Esit’);

201Oracle Üzerinde Programlama ve PL/SQL

Page 208: Bilge adam java.pdf

20 ELSE

21 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

22 ENDIF;

23 END;

Örnek 5’i çalıştırdığınızda şu şekilde bir DBMS çıktısı ile karşılaşırsınız:

Esitdegil

Esit

Esit

Bu örneğin DBMS çıktısından anlaşılacağı gibi “A” harfi ve “a” harfi birbirine eşit değildir. 23 numaralı satırda kullandığımız SUBSTR() fonksiyonu, adından da anlaşılabileceği gibi alfanü-merik bir yapıdan istediğimiz bir parçayı almak için kullanılır. SUBSTR fonksiyonunun kullanımı T-SQL’deki SUBSTRING() fonksiyonu gibidir. İlk argüman parça alınacak alfanümerik değer ya da değişkendir. İkinci argüman, bu değer ya da değişkenin kaçıncı karakterinden itibaren parça alınacağıdır. Üçüncü argüman, ikinci argümanda belirtilen karakter dahil olmak üzere kaç tane karakter alınacağını gösterir. Eğer üçüncü argüman girilmezse, ilk argümanda belirtilen değer ya da değişkenin, ikinci argümanda belirtilen karakterinden sonuna kadar tüm karakterleri alınır.

LONG ve LONG RAW LONG�ve�LONG RAW tipleri T-SQL’deki LONG tipinden çok farklıdır. PL/SQL’de LONG�ve�LONG RAW�32760 byte’a kadar alfanümerik değer tutar. Dolayısıyla VARCHAR2 tipine benzerdirler. LONG ve LONG RAW tipleri arasında veri tabanına INSERT ve SELECT ile yapılan işlemlerde ve veri tutma biçimlerinde farklılıkları vardır.

Örnek 6: LONG ve LONG RAW Tanımlama

1DECLARE

2 lx1LONG;

3 lrx1LONGRAW;

4 lx2LONG;

5 lx3LONG;

6 lrx2LONGRAW;

7 lx4LONG(3);

8 lrx3LONGRAW(3);

9BEGIN

10 lx1:=‘ABC’;

11 lrx1:=‘ABC’;

12 lx3:=‘ABC’;

13 lx4:=‘ABC’;

14 lrx3=‘ABC’;

15 IFlx1=lrx1

16 THEN

17 DBMS_OUTPUT.PUT_LINE(‘Esit’);

18 ELSE

19 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

20 ENDIF;

21 lx2:=CONCAT(lx1,lrx1);

202 Bölüm 11

Page 209: Bilge adam java.pdf

22 DBMS_OUTPUT.PUT_LINE(lx2);

23 lx2:=CONCAT(lx1,lx3);

24 DBMS_OUTPUT.PUT_LINE(lx2);

25 lrx2:=CONCAT(lx1,lrx1);

26 DBMS_OUTPUT.PUT_LINE(lrx2);

27 END;

Örnek 6’yı çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

Esitdegil

ABC0ABC

ABCABC

0ABC0ABC

15 numaralı satırda LONG tipindeki, tuttuğu değer “ABC” olan lx1 değişkeniyle LONG RAW tipin-deki, tuttuğu değer “ABC” olan lrx1 değişkeni karşılaştırıldığında FALSE sonucu oluşur ve 18 numaralı satırdaki ELSE bloğuna düşer. Dolayısıyla LONG�ve�LONG RAW değişkenleri doğrudan karşılaştırmak istediğimiz sonucu üretmez. 21 numaralı satırda LONG tipindeki lx1�ile�lrx1�de-ğişkenlerini CONCAT() fonksiyonuyla birleştirip LONG tipindeki lx2 değişkenine atadık. 22 nu-maralı satırda lx2 değişkeninin değerinin “ABC0ABC” olduğunu gördük. 23 numaralı satırda LONG tipindeki lx2 değişkenine LONG tipindeki lx1�ve�lx3 değişkenlerinin birleştirilmesi sonucu oluşan değeri atadık ve 24 numaralı satırda lx2 değişkenininin değerinin “ABCABC” olduğunu gördük. Benzer şekilde 25 numaralı satırda bu sefer LONG RAW tipindeki lrx2 değişkeninin içine LONG tipindeki lx1�ve�LONG RAW tipindeki lrx1 değişkenlerinin birleştirilmesi sonucu oluşan değeri atadık ve 26 numaralı satırda sonucun “0ABC0ABC” olduğunu gördük. Dolayısıyla LONG�tipindeki değişkenlerle LONG RAW tipindeki değişkenleri bir arada kullanırken dikkatli olmakta fayda vardır.

Örnek 7: LONG ve LONG RAW Tiplerinin CHAR ile Karşılaştırılması

1DECLARE

2 lx1LONG(3);

3 lrx1LONGRAW(3);

4 cx1CHAR(3);

5BEGIN

6 lx1:=‘ABC’;

7 lrx1:=‘ABC’;

8 cx1:=‘ABC’;

9 IFlx1=lrx1

10 THEN

11 DBMS_OUTPUT.PUT_LINE(‘Esit’);

12 ELSE

13 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

14 ENDIF;

15 IFlx1=cx1

16 THEN

17 DBMS_OUTPUT.PUT_LINE(‘Esit’);

18 ELSE

19 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

203Oracle Üzerinde Programlama ve PL/SQL

Page 210: Bilge adam java.pdf

20 ENDIF;

21 IFcx1=lrx1

22 THEN

23 DBMS_OUTPUT.PUT_LINE(‘Esit’);

24 ELSE

25 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

26 ENDIF;

27 END;

Örnek 7’yi çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

Esitdegil

Esit

Esitdegil

Bu örnekten de anlaşılabileceği gibi CHAR tipindeki verilerle LONG tipindeki veriler karşılaştırılabi-lirken LONG RAW tipindeki verilerin doğrudan karşılaştırılması istediğimiz sonuçları vermeyebilir.

ROWID ve UROWIDT-SQL’de olmayan tiplerdir. ROWID�ve�UROWID herhangi bir tablodaki kaydın yeri hakkında bilgi tutarlar. Bu bilgi fiziksel ve mantıksal olmak üzere 2 şekildedir. Fiziksel rowid herhangi bir tabloda satır için ayırdedici bir özelliktir. Mantıksal rowid üzerinde index olan bir tablo için ayırdedicidir. UROWID hem fiziksel hem de mantıksal rowid tutabilir. Eğer yeni bir uygulama yazıyorsanız ve bu tip bir veriye ihtiyacınız varsa UROWID tipini tercih etmek daha iyi olacaktır. Örneğin ROWID�ve�UROWID tiplerini tüm değerleri aynı olan 2 satırdan birini silerken kullanabilirsiniz.

Örnek 8: ROWID ve UROWID Tipleri

1DECLARE

2 rx1ROWID;

3 urx1UROWID;

4BEGIN

6 SELECT

7 rowid

8 INTOrx1

9 FROMUrun

10 WHEREUrunId=2;

11 SELECT

12 rowid

13 INTOurx1

14 FROMUrun

15 WHEREUrunId=2;

16 DBMS_OUTPUT.PUT_LINE(rx1);

17 DBMS_OUTPUT.PUT_LINE(urx1);

18 IFrx1=urx1

19 THEN

20 DBMS_OUTPUT.PUT_LINE(‘Esit’);

21 ELSE

204 Bölüm 11

Page 211: Bilge adam java.pdf

22 DBMS_OUTPUT.PUT_LINE(‘Esitdegil’);

23 ENDIF;

24 END;

Örnek 8’i çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

AAAM2eAABAAAO5aAAD

AAAM2eAABAAAO5aAAD

Esit

Bu örnekten ROWID tipindeki rx1�ve�UROWID tipindeki urx1 değerlerinin esit olduğunu görebiliriz. Bununla birlikte DBMS çıktısındaki “AAAM2eAABAAAO5aAAD” ifadeleri sizde farklı değerlerde olacaktır. Bu karakter dizisi bir anlam taşır. İlk 6 karakter (örneğimizde “AAAM2e”) veri tabanı segmentini ifade eder. Bu gruba nesne numarası (object number) denir. Sonraki 3 karakter (örne-ğimizde “AAB”) satırın bulunduğu fiziksel dosyayı ifade eder. Bu gruba dosya numarası (file num-ber) denir. Sonraki 6 karakter (örneğimizde “AAAO5a”) veri dosyasının içindeki bloğu ifade eder. Aynı tablespace içinde olan fakat farklı veri dosyasında olan 2 satır aynı blok numarasına sahip olabilir. Bu gruba blok numarası (block number) denir. Son 3 karakter de (örneğimizde “AAD”) blok içindeki satır numarasını ifade eder. Bu gruba satır numarası (row number) denir.

Örnek 9: ROWID ve UROWID Tipleri

1DECLARE

2 rx1ROWID;

3 rx2ROWID;

4BEGIN

6 SELECT

7 rowid

8 INTOrx1

9 FROMUrun

10 WHEREUrunId=2;

11 SELECT

12 rowid

13 INTOrx2

14 FROMUrun

15 WHEREUrunId=3;

16 DBMS_OUTPUT.PUT_LINE(rx1);

17 DBMS_OUTPUT.PUT_LINE(rx2);

18 END;

Örnek 9’u çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

AAAM2eAABAAAO5aAAD

AAAM2eAABAAAO5aAAA

Bu çıktıdan Urun tablosundaki UrunId değerleri 2 ve 3 olan satırların aynı segment’te, aynı veri dosyasında, aynı blok içindeki farklı yerlerde olduğunu görebiliriz.

VARCHAR2Değişken uzunluklu alfanümerik verileri tutmak için kullanılır. Verinin VARCHAR2 tipinde nasıl tu-tulduğu veri tabanının karakter setine göre değişiklik gösterir. En fazla 32767 karakter tutulabilir.

205Oracle Üzerinde Programlama ve PL/SQL

Page 212: Bilge adam java.pdf

2000 byte’tan uzun değerlerde performans düşüşü yükselir. Bu sebeple 2000 byte’tan daha uzun verileri tutarken bu durumu dikkate almakta fayda vardır.

STRING�ve�VARCHAR veri tipleri VARCHAR2 veri tipinin alt tipleridir. VARCHAR�ile�VARCHAR2 veri tipleri aynıdır. VARCHAR veri tipinin varlık sebebi ileri sürümlerde farklı şekilde kullanılabilecek ayrılmış bir tip yaratmaktır. Bu sebeple VARCHAR2 veri tipini kullanmak daha iyi olacaktır.

Örnek 10: VARCHAR2 Tipi ve Diğer Alfanümerik Tiplerle Karşılaştırma

1DECLARE

2 vx1VARCHAR2(10);

3 cx1CHAR(10);

4 sx1STRING(10);

5 lx1LONG(10);

6BEGIN

7 vx1:=‘ABC’;

8 cx1:=‘ABC’;

9 sx1:=‘ABC’;

10 lx1:=‘ABC’;

11 IFvx1!=cx1

12 THEN

13 DBMS_OUTPUT.PUT_LINE(‘vx1!=cx1’);

14 ELSE

15 DBMS_OUTPUT.PUT_LINE(‘vx1=cx1’);

16 ENDIF;

17 IFvx1!=sx1

18 THEN

19 DBMS_OUTPUT.PUT_LINE(‘vx1!=sx1’);

20 ELSE

21 DBMS_OUTPUT.PUT_LINE(‘vx1=sx1’);

22 ENDIF;

23 IFvx1!=lx1

24 THEN

25 DBMS_OUTPUT.PUT_LINE(‘vx1!=lx1’);

26 ELSE

27 DBMS_OUTPUT.PUT_LINE(‘vx1=lx1’);

28 ENDIF;

29 END;

Örnek 10’u çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

vx1!=cx1

vx1=sx1

vx1=lx1

Bu örnekten görebileceğimiz gibi VARCHAR2 tipiyle CHAR tipini karşılaştırmak sakıncalıdır. Her ne kadar LONG tipiyle karşılaştırmak eşit sonucunu verse de LONG tipi ile VARCHAR2 tipinini kapasi-telerinin farklı olması sebebiyle bu tip bir karşılaştırmayı tercih etmemekte fayda vardır.

206 Bölüm 11

Page 213: Bilge adam java.pdf

PL/SQL’de Mantıksal TiplerPL/SQL’de 1 tane mantıksal tip bulunmaktadır. Bu tip BOOLEAN tipidir. Mantıksal bir tip TRUE ya da FALSE değerlerinden birini tutar.

BOOLEANPL/SQL’de BOOLEAN veri tipi TRUE ya da FALSE değerlerini tutar; ancak dikkat edilmesi gereken nokta BOOLEAN bir veri tipini DBMS_OUTPUT.PUT_LINE() fonksiyonu ile yazdıramayız.

Örnek 11: BOOLEAN Veri Tipi

1DECLARE

2 bxBOOLEAN;

3BEGIN

4 bx:=TRUE;

5 IFbx=TRUE

6 THEN

7 DBMS_OUTPUT.PUT_LINE(‘bx=TRUE’);

8 ELSIFbx=FALSE

9 THEN

10 DBMS_OUTPUT.PUT_LINE(‘bx=FALSE’);

11 ELSE

12 DBMS_OUTPUT.PUT_LINE(‘bx=null’);

13 ENDIF;

14 END;

Örnek 10’u çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

bx=TRUE

Bu örnekte 10 numaralı satırdaki ELSE bloğunu eklemimizin sebebi eğer bx değişkeni tanımlan-mazsa ya da bx değişkenine null değeri atanırsa 11 numaralı satırdaki ELSE bloğuna girilecek ve DBMS çıktısı olarak “bx = null” yazılacaktır.

PL/SQL’de Tarih ve Zaman TipleriTarih ve zaman tipleri herhangi bir tarihi ya da saati tutar. PL/SQL’de pek çok tarihsel gösterim şekli olmasına rağmen bu tipleri temel olarak inceleyeceğiz.

DATEDATE veri tipi Saniye detayında tarih ve zaman verisi tutar.

Örnek 12: DATE Veri Tipi

1DECLARE

2 dxDATE;

3BEGIN

4 dx:=SYSDATE;

5 DBMS_OUTPUT.PUT_LINE(dx);

6END;

Örnek 12’yi çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

02-DEC-07

207Oracle Üzerinde Programlama ve PL/SQL

Page 214: Bilge adam java.pdf

SYSDATE() fonksiyonu T-SQL’deki GETDATE() fonksiyonuna karşılık gelmektedir ve sistem ta-rih ve zamanını getirir. Bu noktadan itibaren INTERVAL yapısına geçebiliriz.

Örnek 13: INTERVAL YEAR TO MONTH

1DECLARE

2 BaslangicTarihiDATE;

3 BitisTarihiDATE;

4 ixINTERVALYEAR(3)TOMONTH;

5 cYilFarkiCHAR(3);

6 cAyFarkiCHAR(2);

7 iYilFarkiINT;

8 iAyFarkiINT;

7BEGIN

8 BaslangicTarihi:=’01-JAN-00’;

9 BitisTarihi:=SYSDATE;

10 DBMS_OUTPUT.PUT_LINE(‘GunFarki:’||TO_CHAR(BitisTarihi-BaslangicTarihi));

11 iYilFarki:=FLOOR((BitisTarihi-BaslangicTarihi)/365);

12 cYilFarki:=TO_CHAR(iYilFarki);

13 iAyFarki:=FLOOR(((BitisTarihi-BaslangicTarihi)–iYilFarki*365)/30);

14 cAyFarki:=TO_CHAR(iAyFarki);

15 ix:=CONCAT(CONCAT(TRIM(iYilFarki),‘-‘),TRIM(iAyFarki));

16 DBMS_OUTPUT.PUT_LINE(ix);

17 END;

Örnek 13’ü çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

GunFarki:2892

+007-11

Bu örnekten görebileceğimiz gibi uygulamanın çalıştığı tarih (2 Aralık 2007) ile 1 Ocak 2000 tarihi arasında 2892 gün vardır. 2892 gün de 7 yıl 11 aya karşılık gelmektedir. Bu örnekte TO_CHAR()�fonksiyonu herhangi bir tipi CHAR tipine çeviren fonksiyondur. BOOLEAN tipini CHAR tipine çevire-mez. TO_CHAR() fonksiyonunu T-SQL’deki CONVERT() fonksiyonunun özelleşmiş bir hali olarak düşünebiliriz. FLOOR() fonksiyonu burada, ondalıklı sayının ondalıklı kısmını atarak tam sayı kısmını almamızı sağlar. Bu örnekten de görebileceğiniz gibi INTERVAL YEAR TO MONTH tipine CHAR tipinde YIL-AY değerini alabilmektedir.

Örnek 14: INTERVAL YEAR TO MONTH

1DECLARE

2 ix1INTERVALYEAR(3)TOMONTH;

3 ix2INTERVALYEAR(3)TOMONTH;

4 ix3INTERVALYEAR(3)TOMONTH;

5 ix4INTERVALYEAR(3)TOMONTH;

6 dxDATE;

208 Bölüm 11

Page 215: Bilge adam java.pdf

7BEGIN

8 ix1:=INTERVAL’10-7’YEARTOMONTH;

9 ix2:=INTERVAL’10’YEAR;

10 ix3:=INTERVAL’7’MONTH;

11 ix4:=ix2+ix3;

12 DBMS_OUTPUT.PUT_LINE(ix4);

13 dx:=SYSDATE;

14 dx:=dx+ix4;

15 DBMS_OUTPUT.PUT_LINE(dx);

12 END;

Örnek 14’ü çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

+010-07

02-JUL-18

Bu örnekten görülebileceği gibi 11 numaralı satırda 2 INTERVAL YEAR TO MONTH toplanabil-mektedir. 14 numaralı satırda da INTERVAL YEAR TO MONTH tipinin DATE tipiyle toplanabildiğini görüyoruz. Bu örnekteki INTERVAL YEAR TO MONTH tipindeki değişkenler tanımlanırken YEAR�ifadesinin yanındaki 3 rakamı en fazla 3 haneli yıl değeri taşıyabileceğini gösterir ve en fazla 4 olabilir.

Benzer şekilde kullanabileceğimiz INTERVAL DAY TO SECOND tipi de mevcuttur.

DATE ve INTERVAL İşlemleri

TIMESTAMPTIMESTAMP veri tipi DATE veri tipinin bir varyasyonudur. DATE tipi gibi kullanılabilir.

Örnek 15: TIMESTAMP Veri Tipi

1DECLARE

2 txTIMESTAMP;

3BEGIN

4 tx:=SYSDATE;

5 DBMS_OUTPUT.PUT_LINE(tx);

6 tx:=’05-JUL-0710:42:35.313PM’

7END;4

1. Argüman İşlem 2. Argüman Sonuç Tipi

DATE + INTERVAL DATEDATE - INTERVAL DATE

INTERVAL + DATE DATE

DATE - DATE INTERVAL

INTERVAL + INTERVAL INTERVAL

INTERVAL - INTERVAL INTERVAL

INTERVAL * NUMERIC INTERVAL

NUMERIC * INTERVAL INTERVALINTERVAL / NUMERIC INTERVAL

209Oracle Üzerinde Programlama ve PL/SQL

Page 216: Bilge adam java.pdf

Örnek 15’i çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

02-DEC-0712.00.00.000000000

6 numaralı satırdaki gibi TIMESTAMP tipine değer ataması yapılabilir.

Bütünleşik TiplerBütünleşik tipler herhangi bir basit tipten, referans tipinden ya da LOB tipinden türetilebilen dizi-lerdir.

Örnek 16: VARRAY Veri Tipi

1DECLARE

2 TYPEPIXAISVARRAY(4)OFPLS_INTEGER;

3 pxPIXA;

4BEGIN

5 px:=PIXA(0,0,0,0);

6 px(1):=3;

7 px(2):=4;

8 DBMS_OUTPUT.PUT_LINE(px(1));

9 DBMS_OUTPUT.PUT_LINE(px(2));

10 END;

Örnek 16’yı çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

3

4

Bu örnekte göreceğiniz gibi bir diziyi kullanmadan önce bir tip olarak tanımlamamız gerekmekte-dir. 2 numaralı satırda bu tanım yapılmaktadır. En genel şekilde tip tanımlaması şu şekildedir:

TYPE <yeni tip adı> IS VARRAY(<eleman sayısı>) OF <tip>

Burada yeni tip adı oluşturduğumuz dizi tipine verdiğimiz addır, tip ise mevcut tiplerden biridir. Dizi indis değerleri 1’den başlar.

Bu örnekte gördüğümüzün dışında bütünleşik tip tanımları da söz konusudur.

Örnek 17: Bileşik Tipler

1DECLARE

2 TYPETBLARRAYISTABLEOFVARCHAR2(3);

3 TYPETBLARRAY2ISTABLEOFPLS_INTEGERINDEXBYPLS_INTEGER;

4 TYPETBLARRAY3ISTABLEOFPLS_INTEGERINDEXBYVARCHAR(3);

5 tx1TBLARRAY;

6 tx2TBLARRAY2;

7 tx3TBLARRAY3;

8BEGIN

9 tx1:=TBLARRAY(‘’,‘’,‘’);

10 tx1(1):=‘ABC’;

11 tx1(2):=‘DEF’;

210 Bölüm 11

Page 217: Bilge adam java.pdf

12 DBMS_OUTPUT.PUT_LINE(tx1(1));

13 DBMS_OUTPUT.PUT_LINE(tx1(2));

14 tx2(1):=10;

15 tx2(2):=15;

16 DBMS_OUTPUT.PUT_LINE(tx2(1));

17 DBMS_OUTPUT.PUT_LINE(tx2(2));

18 tx3(‘abc’):=20;

19 tx3(‘def’):=25;

20 DBMS_OUTPUT.PUT_LINE(tx3(‘abc’));

21 DBMS_OUTPUT.PUT_LINE(tx3(‘def’));

22 END;

Örnek 17’yi çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

ABC

DEF

10

15

20

25

Bu örnekte göreceğiniz gibi PL/SQL, herhangi bir genel amaçlı programlama diline göre bile zen-gin sayılabilecek seçenekler sunmaktadır. 2 numaralı satırda gördüğümüz tanımlama Örnek 16’ya göre eleman sayısı tanımlamamaktadır. Böylece TBLARRAY tipinde tanımladığımız herhangi bir değişkenin eleman sayısı sınır lı olmaktan çıkmıştır; ancak hala Örnek 16’daki gibi 9 numaralı sa-tırda TBLARRAY tipinde tanımladığımız değişkene ilk değerlerini vermek durumundayız. TBLAR-RAY tipi PLS_INTEGER tipindeki değerlerden oluşan bir dizi tipidir. 3 numaralı satırda, TBLARRAY�tipine göre oluşturduğumuz farklılık INDEX BY ifadesidir. INDEX BY ifadesi dizi tipini tanımlarken indis değerlerinin hangi tipte olduğunu tanımlamaya yarar. TBLARRAY2 tipinde ilk PLS_INTEGER�ifadesi, TBLARRAY2 tipinden oluşturulacak bir değişkenin PLS_INTEGER tipinde değerler tuta-cağını gösterirken, satırın sonundaki INDEX BY PLS_INTEGER ifadesi de değişkenin indis de-ğerlerinin PLS_INTEGER ile gösterileceğini ifade eder. 14 ve 15 numaralı satırlarda gördüğünüz gibi tx2 tipinin indisleri de değerleri de PLS_INTEGER tipindedir. Ayrıca bu tanımla artık dizinin ilk değerlerini önceden vermek zorunluluğumuz ortadan kalktı. 4 numaralı satırdaki tip tanımında ise 3 numaralı satırdan sadece değişken indislerinin nasıl tutulacağı değişmiştir. TBLARRAY3 tipinde tanımlanan bir dizinin indisleri VARCHAR2(3) tipinde olacaktır ve içinde PLS_INTEGER tipinde değerler tutacaktır. Buna ait kullanımı da 18 ve 19 numaralı satırlarda görebilirsiniz. Herhangi bir dizide dizinin ilk elemanına erişmek için FIRST, son elemanına erişmek için de LAST ifadelerini kullanabiliriz. Bununla ilgili örneği Örnek 18’de görebilirsiniz:

Örnek 18: FIRST ve LAST

1DECLARE

2 TYPETBLARRAYISTABLEOFVARCHAR2(3);

3 TYPETBLARRAY2ISTABLEOFPLS_INTEGERINDEXBYPLS_INTEGER;

4 TYPETBLARRAY3ISTABLEOFPLS_INTEGERINDEXBYVARCHAR(3);

5 tx1TBLARRAY;

6 tx2TBLARRAY2;

211Oracle Üzerinde Programlama ve PL/SQL

Page 218: Bilge adam java.pdf

7 tx3TBLARRAY3;

8BEGIN

9 tx1:=TBLARRAY(‘’,‘’,‘’);

10 tx1(1):=‘ABC’;

11 tx1(2):=‘DEF’;

12 DBMS_OUTPUT.PUT_LINE(tx1(1));

13 DBMS_OUTPUT.PUT_LINE(tx1(tx1.LAST));

14 tx2(1):=10;

15 tx2(2):=15;

16 DBMS_OUTPUT.PUT_LINE(tx2(tx2.FIRST));

17 DBMS_OUTPUT.PUT_LINE(tx2(2));

18 tx3(‘abc’):=20;

19 tx3(‘def’):=25;

20 DBMS_OUTPUT.PUT_LINE(tx3(‘abc’));

21 DBMS_OUTPUT.PUT_LINE(tx3(tx3.LAST));

22 END;

Örnek 18’i çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

ABC

10

15

20

25

Bu örnekte 13 numaralı satırın çalışmasından sonucu oluşmaktadır; çünkü 9 numaralı satırda dizinin 3. elemanını olarak tanımladık.

RECORDRECORD tipi T-SQL’de olmayan bir tiptir. C#’taki struct gibi düşünülebilir.

Örnek 19: RECORD Tanımlama

1DECLARE

2 TYPEREC_URUNISRECORD(IDINTEGER,ADVARCHAR2(10));

3 rUrunREC_URUN;

4BEGIN

5 SELECT;

6 UrunId,UrunAdi

7 INTOrUrun

8 FROMUrun

9 WHEREROWNUM=1;

10 DBMS_OUTPUT.PUT_LINE(‘UrunID:’||rUrun.ID||‘Adi:’||rUrun.AD);

11 END;

212 Bölüm 11

Page 219: Bilge adam java.pdf

Örnek 19’u çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

UrunID:1

Adi:Bisküvi

2 numaralı satırda INTEGER tipinde bir değer ve VARCHAR2 tipinde bir değer alan REC_URUN�adında bir RECORD oluşturduk. 3 numaralı satırda bu tipte bir değişken tanımladık. 5, 6, 7, 8 ve 9 numaralı satırlardan oluşan SELECT cümleciği ile rUrun değişkeninin içine ID�ve�AD bilgileri ata-dık. SELECT cümleciğinde T-SQL’de olmayan bir alan olan ROWNUM’ı kullanıdk. ROWNUM, SELECT�ifadesinin sonucunda oluşan kümenin sıra numarasını alan bir değerdir. Dolayısıyla ROWNUM = 1 olduğu için ilk satır verilerini RECORD’ın içine atmış durumdayız. 10 numaralı satırda da bu de-ğerleri tek tek yazdırdık. RECORD, CURSOR ile birlikte kullanıldığında daha güçlü bir yapıyla karşı karşıya kalacağız.

Referans TipleriReferans tipleri bir işaretçi aracılığıyla bellekte asıl veri bloğunun tutulduğu adresi gösteren veri tipidir. Esnek tipler olışturabilmek açısından oldukça önemlidir.

REF CURSORREF CURSOR tipine geçmeden önce daha basit bir tip olan CURSOR tipinden bahsetmek gere-kir. CURSOR tipi T-SQL’deki CURSOR’lara karşılık gelir; ancak kullanımında çok sayıda detay vardır. Mantıksal olarak da T-SQL’deki CURSOR’larla aynı mantıkta çalışır.

Örnek 20: CURSOR Tanımlama

1DECLARE

2 CURSORcurUrunIS

3 SELECT

4 UrunId,UrunAdi

5 FROMUrun;

6 IDINTEGER;

7 ADVARCHAR2(10);

8BEGIN

9 OPENcurUrun;

10 LOOP

11 FETCHcurUrunINTOID,AD;

12 EXITWHENNOTcurUrun%FOUND;

13 DBMS_OUTPUT.PUT_LINE(ID||‘–‘||AD);

14 ENDLOOP;

15 CLOSEcurUrun;

16 END;

Örnek 20’yi çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

1-Bisküvi

2 - Çikolata

2, 3, 4 ve 5 numaralı satırlar CURSOR tanımını oluşturur. 3, 4 ve 5 numaralı satırlardaki SELECT�cümleciğinin sonucu curUrun adlı CURSOR içine satır satır atılacaktır; ancak bu işlem bu bölüm-de yapılmaz. Burada sadece CURSOR için tanım mevcuttur. 9 numaralı satırda CURSOR açıldıktan sonra, bir sonraki konuda işleyeceğimiz LOOP döngüsü içinde CURSOR tanımına göre satır satır işleme yapılacaktır. 11 numaralı satırda ilk staır CURSOR değişkenleri olan ID�ve�AD değişkenle-

213Oracle Üzerinde Programlama ve PL/SQL

Page 220: Bilge adam java.pdf

rine alınır. 12 numaralı satır LOOP döngüsünün curUrun içinde satır bulunamadığında çıkması için yazılmıştır. curUrun%FOUND ifadesi T-SQL’deki CURSOR için kullandığımız WHILE döngü-sündeki @@FETCH_STATUS != -1 ifadesi ile aynı şekilde çalışır. 13 numaralı satırda CURSOR�değişkenleri DBMS çıktısı olarak yazılır. 15 numaralı satırda da CURSOR kapatılır. OPEN ile açılan bir CURSOR belleğin etkin kullanımı açısından mutlaka CLOSE ile kapatılmalıdır.

Örnek 20: T-SQL’de CURSOR Tanımlama

1DECLARE@IDINT,@ADVARCHAR(10)

2 DECLAREcurUrunINSENSITIVECURSORFOR

3 SELECT

4 UrunId,UrunAdi

5 FROMUrun

6 OPENvurUrun

7 FETCHNEXTFROMcurUrunINTO@ID,@AD

8 WHILE@@FETCH_STATUS!=-1

9 BEGIN

10 PRINTCONVERT(VARCHAR,@ID)+‘–‘+@AD

11 FETCHNEXTFROMcurUrunINTOID,AD

12 END

13 CLOSEcurUrun

14 DEALLOCATEcurUrun

Örnek 20.1’de Örnek 20’deki PL/SQL ile kullanılan CURSOR yapısnın T-SQL karşılığını görebi-lirsiniz.

Örnek 21: CURSOR Değerlerinin RECORD İçine Atılması

1DECLARE

2 TYPEREC_URUNISRECORD(IDINTEGER,ADVARCHAR2(10));

3 TYPEREC_URUN_ARRISTABLEOFREC_URUNINDEXBYPLS_INTEGER;

4 rUrunREC_URUN;

5 rUrunArrREC_URUN_ARR;

6 CURSORcurUrunIS

7 SELECT

8 UrunId,UrunAdi

9 FROMUrun;

10 ROWNPLS_INTEGER;

11 BEGIN

12 OPENcurUrun;

13 ROWN:=1;

14 LOOP

15 FETCHcurUrunINTOrUrun;

16 EXITWHENNOTcurUrun%FOUND;

17 rUrunArr(ROWN):=rUrun;

18 DBMS_OUTPUT.PUT_LINE(rUrunArr(ROWN).ID||‘–‘||rUrunArr(ROWN).AD);

214 Bölüm 11

Page 221: Bilge adam java.pdf

19 ENDLOOP;

20 CLOSEcurUrun;

21 END;

Örnek 21’i çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

1-Bisküvi

2 - Çikolata

2 numaralı satırda CURSOR için çalışan SELECT sorgusunun kayıt desenine uygun şekilde bir RECORD oluşturduk. 3 numaralı satırda da CURSOR üzerinden REC_URUN tipindeki kayıtlarımızı toplayacağımız değişken uzunluklu, PLS_INTEGER indisli, REC_URUN tipinde bir dizi tipi tanımla-dık. 4 numaralı satırda CURSOR’dan dönen her satırı tutacağımız kayıt değişkenini tanımladık. 5 numaralı satırda da bu kayıt değişkenlerinin hepsini toplayacağımız diziyi tanımladık. 10 numaralı satırda REC_URUN_ARR tipindeki dizinin indisini tutmak için PLS_INTEGER tipinde bir değişken tanımladık. 13 numaralı satırda dizi indisleri 1’den başladığı için ROWN değerini 1 yaptık. 15 nu-maralı satırda Örnek 20’ye göre farklı olarak CURSOR’dan dönen kaydı olduğu gibi REC_URUN ti-pindeki rUrun adlı kayıt değişkenine atadık. 17 numaralı satırda da REC_URUN_ARR tipindeki rU-runArr dizisinin ROWN numaralı indisindeki alana rUrun kaydını yerleştirdik. 18 numaralı satırda rUrunArr(ROWN).ID�ve�rUrunArr(ROWN).AD ifadelerini rUrunArr dizisinin her elemanının REC_URUN kayıt tipinde olmasından dolayı, kayıt deseninde tanımlı değişkenlerle kullanabildik.

Örnek 22: REF CURSOR Değerlerinin RECORD İçine Atılması

1DECLARE

2 TYPEREC_URUNISRECORD(IDINTEGER,ADVARCHAR2(10));

3 TYPEURUN_CUR_TYPEISREFCURSORRETURNREC_URUN;

4 rUrunREC_URUN;

5 cUrunTypeURUN_CUR_TYPE;

6BEGIN

7 OPENcUrunTypeFOR

8 SELECT

9 UrunId,UrunAdi

10 FROMUrun;

11 LOOP

12 FETCHcUrunTypeINTOrUrun;

13 EXITWHENNOTcUrunType%FOUND;

14 DBMS_OUTPUT.PUT_LINE(rUrun.ID||‘–‘||rUrun.AD);

15 ENDLOOP;

16 CLOSEcUrunType;

17 END;

Örnek 22’yi çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

1-Bisküvi

2 - Çikolata

2 numaralı satırda Örnek 21’deki gibi RECORD tipinde kayıt desenimizi tanımladık. 3 numaralı satırda da REF CURSOR tipimizi tanımladık. 4 ve 5 numaralı satırlarda bu tiplere ait değişkenleri-mizi oluşturduk. 7, 8, 9 ve 10 numaralı satırlarda URUN_CUR_TYPE adında REF CURSOR tipinde

215Oracle Üzerinde Programlama ve PL/SQL

Page 222: Bilge adam java.pdf

REC_URUN tipinde değer döndüren CURSOR yapımızı hem tanımladık, hem de açtık. Bu yapı T-SQL’deki CURSOR yapısına daha çok benzemektedir; ancak T-SQL’de RECORD yapısına benzer yapılar olmadığı için bu örneğin bire bir T-SQL karşılığı yoktur. 12 numaralı satırda oluşturduğu-muz REF CURSOR tipinin içindeki değeri REC_URUN tipinin içine yerleştirdik. 14 numaralı satırda da o satır için rUrun adlı kayıttaki ID�ve�AD alanlarının değerlerini yazdırdık.

LOB (Large Object) TipleriYapısal olmayan büyük verilerin tutulması için kullanışlı tiplerdir. En fazla tutabilecekleri veri mik-tarı 4GB’tır. Asıl verilerini işaretçi mantığıyla tutarlar.

BFILEBFILE veri tipi, büyük verilerinin veri tabanı üzerinde değil işletim sisteminin üzerindeki dosya sistemi üzerinde tutulmasını sağlayan bir tiptir. BFILE aslında bu fiziksel dosyaya ait adresi tutar. BFILE tipindeki veri değiştirilemez. Kullanımı transaction mantığı çerçevesinde risklidir; çünkü transaction ile çalışan bir tip değildir ve transaction’a dahil edilmezler. Replikasyon ile replike edilemezler.

BLOB (Binary Large Object)BLOB veri tipinin BFILE veri tipinden farkları, tuttuğu verinin veri tabanı dosyaları içinde tutulması ve transaction’a dahil olması ve replike edilebilir olmasıdır. BLOB veri tipinde veri binary olarak saklanır. Microsoft SQL Server 2005 ile birlikte gelen BLOB tipi gibidir.

CLOB (Character Large Object)CLOB veri tipinin BLOB veri tipinden farkı tuttuğu verinin binary yerine alfanümerik olmasıdır. Diğer özellikleri BLOB tipi gibidir. Microsoft SQL Server 2005 ile birlikte gelen CLOB tipi gibidir.

NCLOBNCLOB veri tipinin CLOB veri tipinden farkı NCHAR tipinden oluşmasıdır. Bunun anlamı yerel alfa-belerin de rahatlıkla kullanılabileceğidir.

PL/SQL’de Döngü YapılarıLOOP DöngüsüLOOP döngüsü normalde koşulsuz bir döngü tipidir. EXIT ifadesi işletilene kadar döngü tekrarla-maya devam eder. LOOP ile CURSOR konusunda da örnek görmüştük.

Örnek 23: LOOP Döngüsü

1DECLARE

2 ixPLS_INTEGER;

3BEGIN

4 ix:=1;

5 LOOP

6 IFix!=5

7 THEN

8 ix:=ix+1;

9 DBMS_OUTPUT.PUT_LINE(ix);

10 ELSE

11 EXIT;

12 ENDIF;

13 ENDLOOP;

14 END;

216 Bölüm 11

Page 223: Bilge adam java.pdf

Örnek 23’ü çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

2

3

4

5

Bu örnekte dikkat etmemiz gereken en önemli nokta 4 numaralı satırda eğer ix değişkenine de-ğer ataması yapmazsak 6 numaralı satırdaki karşılaştırmadan beklenmedik şekilde FALSE değeri üretilmesidir. Bu sebeple LOOP döngü yapısını kullanırken kontrol değişkenine ilk değer ataması-nı yapmak önemlidir. 5 ile 13 numaralı satırlar arasında tanımlanan LOOP döngüsünden çıkmak için bu blok içinde kod akışında mutlaka EXIT ifadesinin çalışması gerekir; aksi takdirde sonsuz döngü oluşacaktır. Örneğimizde eğer ix değişkeninin değeri 5’e eşit olursa 10 numaralı satırdaki ELSE bloğu çalışır ve EXIT ifadesi de böylece çalışmış olur ve LOOP döngüsü sonlandırılarak program akışı 13 numaralı satırdan itibaren devam eder.

EXIT WHEN İfadesiLOOP döngüsünde koşullu çıkışı sağlamak için kullanılan bir ifadedir. IF bloğu yerine kullanıla-bilir.

Örnek 24: LOOP Döngüsü ve EXIT WHEN İfadesi

1DECLARE

2 ixPLS_INTEGER;

3BEGIN

4 ix:=1;

5 LOOP

6 EXITWHENix=5;

7 ix:=ix+1;

8 ENDLOOP;

9END;

Örnek 24’ü çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

2

3

4

5

Bu örnekte LOOP döngüsü her döndüğünde 6 numaralı satırda EXIT WHEN ix = 5 ifadesiyle karşılaşarak ix değerinin 5’e eşit olup olmadığını kontrol edecektir. Eğer ix 5’e eşitse EXIT ifa-desi çalışacak ve program akışı 8 numaralı satırdan devam edecektir.

WHILE – LOOP DöngüsüWHILE – LOOP döngüsü EXIT WHEN ifadesi ile kullanılan LOOP döngüsüne çok benzerdir. Bu döngü tipinde WHILE ile tanımlanan koşul sağlandığı sürece döngü iterasyona devam eder.

Örnek 25: WHILE - LOOP Döngüsü

1DECLARE

2 ixPLS_INTEGER;

3BEGIN

217Oracle Üzerinde Programlama ve PL/SQL

Page 224: Bilge adam java.pdf

4 ix:=1;

5 WHILEix<5

6 LOOP

7 ix:=ix+1;

8 ENDLOOP;

9END;

Örnek 25’i çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

2

3

4

5

Bu örnekte 5 numaralı satırdaki ix < 5 koşulu sağlandığı sürece program akışı 8 numaralı satıra gelmez. Dolayısıyla koşul sağlanana kadar kaç defa çalışacağını bilmediğimiz yapılarda kullanılması uygundur. EXIT ifadesinin olmaması sebebiyle koşullu çıkışın sağlanması semantik olarak sağlandığı için LOOP döngüsüne tercih edilmelidir. WHILE ifadesinin yanındaki koşulun tipi mutlaka BOOLEAN olmalıdır. 0 (sıfır) dışındaki tüm değerler TRUE, 0 (sıfır) FALSE’tur gibi bir durum söz konusu değildir.

FOR – LOOP DöngüsüFOR – LOOP döngüsü de WHILE – LOOP döngüsüne benzer yapıdadır; ancak en önemli farkı koşula bağlı olmaktan çok iterasyon sayısının bilindiği yapılarda kullanılır. WHILE ile geçişken-dir.

Örnek 26: FOR - LOOP Döngüsü

1BEGIN

2 FORixIN2..5

3 LOOP

4 DBMS_OUTPUT.PUT_LINE(ix);

5 ENDLOOP;

6END;

Örnek 26’yı çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

2

3

4

5

Bu örnekte WHILE – LOOP döngüsüne göre kontrol ettiğimizde DECLARE bölümünde bir değiş-ken tanımlamaya ihtiyacımız yoktur. 2 numaralı satırdaki FOR ix IN 2..5 ifadesi ile ix değiş-keni otomatikman tanımlanmış olur. 2 numaralı satırın anlamı, 2’den 5’e kadar olan sayıları her döngüde 1’er artırarak ix değişkenine atama yapmaktır.

Örnek 27: FOR - LOOP Döngüsü

1BEGIN

2 FORixINREVERSE2..5

3 LOOP

218 Bölüm 11

Page 225: Bilge adam java.pdf

4 DBMS_OUTPUT.PUT_LINE(ix);

5 ENDLOOP;

6END;

Örnek 27’yi çalıştırdığımızda aldığımız DBMS çıktısı şu şekildedir:

5

4

3

2

Bu örnekte 2 numaralı satırda IN ifadesinden sonra kullandığımız REVERSE ifadesi döngünün 2’den 5’e kadar 1’er artırarak değil, 5’ten 2’ye kadar 1’er eksilterek dönmesini sağlayacaktır ve her seferinde ix değişkenine 5’ten itibaren 1’er eksilterek değer ataması yapacaktır.

Procedure OluşturmakPL/SQL’de procedure olışturmak T-SQL’den çok farklı değildir. PL/SQL’de Procedure’lar T-SQL’deki SP (stored procedure)’ler gibi IN,�OUT� ve�IN OUT yönlü parametrelere sahiptirler, PL/SQL’deki procedure’larda RETURN yoktur, bunun yerine FUNCTION kullanılır.

Örnek 28: PL/SQL’de Procedure

1CREATEORREPLACEPROCEDUREUrunYaz

2(

3 IDINPLS_INTEGER,

4 ADINVARCHAR2

5)

6AS

7 RowCountPLS_INTEGER;

8BEGIN

9 SELECT

10 COUNT(*)INTORowCount

11 FROMUrun

12 WHEREUrunId=ID;

13 IFRowCount=0

14 THEN

15 INSERTINTOUrun(UrunId,UrunAdi)VALUES(ID,AD);

16 ENDIF;

17 END;

Örnek 28’deki kodu çalıştırdığınızda UrunYaz adında bir procedure SYSTEM schema’sı için login olduğumuz veri tabanı üzerinde daha önceden yazılmamışsa yaratılacaktır, eğer daha önceden varsa üstüne yazılacaktır. Bunu sağlayan 1 numaralı saturdaki CREATE OR REPLACE ifadesidir. Bunun yerine sadece CREATE ya da REPLACE de kullanılabilir. 3 ve 4 numaralı satırlarda Urun-Yaz procedure’ının argümanlarıdır. 3 numaralı satırda ID adında, PLS_INTEGER tipinde, IN yani dışarıdan gelen bir argüman tanımlanmıştır. 4 numaralı satırda AD adında, VARCHAR2 tipinde, IN�yönünde diğer argüman tanımlanmıştır. 7 numaralı satırda procedure’ın içinde kullanacağımız RowCount adında, PLS_INTEGER tipinde bir değişken aynı ID’ye sahip tabloda başka kayıt olup olmadığını kontrol etmek amacıyla, satır sayısını tutmak üzere tanımlanmıştır. 9, 10, 11 ve

219Oracle Üzerinde Programlama ve PL/SQL

Page 226: Bilge adam java.pdf

12 numaralı satırlardali SELECT cümleciğiyle RowCount değerine UrunYaz procedure’ına ID�argümanıyla gelen değere sahip UrunId’li alanların sayısı atanmıştır. 13 numaralı satırda eğer bu ID’ye sahip bir kayıt yoksa 15 numaralı satırdaki INSERT cümleciği çalışması için RowCount�değişkeninin 0 olup olmadığı kontrol edilmektedir. Eğer RowCount 0 ise INSERT çalışır, aksi takdirde procedure sonlanır.

Bu procedure’ı çalıştırmak için yazmamız gereken kod Örnek – 29’daki gibidir:

Örnek 29: PL/SQL ile Procedure Çalıştırmak

1DECLARE

2 IDxPLS_INTEGER:=4;

3 ADxVARCHAR2(10):=‘Gofret’;

4BEGIN

5 UrunYaz(ID=>IDx,AD=>ADx);

6END;

Örnek 29’da 2 ve 3 numaralı satırlarda UrunYaz procedure’ına argüman olarak göndereceğimiz değerleri tanımladık. 5 numaralı satırda da UrunYaz procedure’ını bu değerlerle çalıştırdık.

Örnek 30: PL/SQL ile OUT Parametreli Procedure

1CREATEORREPLACEPROCEDUREUrunYazOut

2(

3 IDINPLS_INTEGER,

4 ADINVARCHAR2,

5 EKLENDIOUTBOOLEAN

6)

7AS

8 RowCountPLS_INTEGER;

9BEGIN

10 SELECT

11 COUNT(*)INTORowCount

12 FROMUrun

13 WHEREUrunId=ID;

14 IFRowCount=0

15 THEN

16 INSERTINTOUrun(UrunId,UrunAdi)VALUES(ID,AD);

17 EKLENDI:=TRUE;

18 ELSE

19 EKLENDI:=FALSE;

20 ENDIF;

21 END;

Örnek 30’da 5 numaralı satırda EKLENDI adında, BOOLEAN tipinde, OUT yönlü bir argüman ta-nımladık. Eğer 16 numaralı satırda INSERT işlemine gelinirse EKLENDI değeri TRUE olur; aksi takdirde FALSE olur. Örnek – 31’de de UrunYazOut procedure’ının nasıl çalıştırıldığını görebi-lirsiniz.

220 Bölüm 11

Page 227: Bilge adam java.pdf

Örnek 31: PL/SQL ile Out Argümanlı Procedure Çalıştırmak

1DECLARE

2 IDxPLS_INTEGER:=4;

3 ADxVARCHAR2(10):=‘Gofret’;

4 DURUMBOOLEAN;

5BEGIN

6 UrunYazOut(ID=>IDx,AD=>ADx,EKLENDI=>DURUM);

7 IFDURUM=TRUE

8 THEN

9 DBMS_OUTPUT.PUT_LINE(‘Eklendi’);

10 ELSE

11 DBMS_OUTPUT.PUT_LINE(‘Eklenmedi’);

12 ENDIF;

13 END;

Örnek 31’de 4 numaralı satırda UrunYazOut procedure’ından OUT parametre (argüman) yoluyla gelecek değeri tutmak için bir BOOLEAN değişken oluşturduk. 6 numaralı satırda da IN yönlü ar-gümanlar gibi OUT yönlü argümanımızı da oluşturduk. 7 numaralı satırdan itibaren IF bloğundan DURUM değişkeninin değerine göre DBMS çıktısına ‘Eklendi’ ya da ‘Eklenmedi’ yazacaktır.

Fonksiyon OluşturmakPL/SQL’de fonksiyonlar T-SQL’deki fonksiyonlara çok benzer özellikler gösterir. IN, OUT�ve�IN OUT yönlü argümanlarla çalışırlar ve RETURN ifadesi ile bir değer döndürürler. C# ve Java’daki dönmüş tipi void olmayan metotlar gibidir.

Örnek 32: PL/SQL’de Fonksiyon

1CREATEORREPLACEFUNCTIONUrunAdiOku

2(

3 IDINPLS_INTEGER

4)

5RETURNVARCHAR2

6AS

7 ADVARCHAR2(10);

8BEGIN

9 SELECT

10 UrunAdiINTOAD

11 FROMUrun

12 WHEREUrunId=ID;

13 RETURNAD;

14 END;

Örnek 32’deki kodu çalıştırdığınızda UrunAdiOku adında fonksiyonumuz eğer daha önce yara-tılmamışsa yaratılacaktır; aksi takdirde üstüne yazılacaktır. Procedure’lardaki gibi fonksiyonlarda da CREATE�ve�REPLACE ifadeleri tek başlarına kullanılabilir.

221Oracle Üzerinde Programlama ve PL/SQL

Page 228: Bilge adam java.pdf

Örnek 33: PL/SQL ile Fonksiyon Çalıştırmak

1DECLARE

2 IDxPLS_INTEGER:=4;

3 ADxVARCHAR2(10);

4BEGIN

5 ADx:=UrunAdiOku(ID=>IDx);

6 DBMS_OUTPUT.PUT_LINE(ADx);

7END;

Örnek 33’de 3 numaralı satırda VARCHAR2(10) tipinde tanımalanan ADx isimli değişken Uru-nAdiOku fonksiyonundan dönen değeri tutacak değişkendir. 5 numaralı satırda ADx değişkenine UrunAdiOku fonksiyonundan dönen değerin ataması yapılmıştır. Bu atama sırasında tip uyumu çok önemlidir. Eğer uyumsuz tipler kullanırsanız istenmeyen sonuçlarla karşılaşabilirsiniz. 6 nu-maralı satırda da ADx değişkenine atanan fonksiyon dönüş değeri DBMS çıktısına yazdırılır.

222 Bölüm 11