26 Mart 2020 Perşembe

Oracle Sql Developer Windows 10 Donma Problemi


Merhaba Arkadaşlar,

Windows10 işletim sistemine sahip bilgisayarıma doğru adımlarla uyumlu JDK ve SDK versiyonları ile kurmama rağmen arayüz eksik bileşenli  ve donmuş şekildeydi. Sorunun çözümünü bulmak biraz sıkıntılı olsa da Türkçe kaynak olmadığından benzer sorunu yaşayan arkadaşlarla bu çözümü paylaşmak istedim.

Ekran donmuş ve parçalı halde karşınıza çıksa da siz sabırlı bir şekilde arayüzde mouseunuzu gezdirmeye devam ederek en üstteki Tools-> Preferences kısmından default olarak Oracle olarak seçili olan kısmı Windows olarak değiştirin. Muhtemelen aşağıdaki Tamam butonunu göremeyeceksiniz. 



Yukarıda yerini paylaştığım yerdeki Tamam butonuna sanki gözüküyormuş gibi tıklayıp deneyin olana kadar. Tamam butonuna tıklayabilmişseniz eğer
yukarıdaki şekilde bir kutucuk karşınıza çıkacaktır. Burada da Yes yerini görünmese dahi denk getirmeye çalışın. Tıklayabilmişseniz eğer restart edecek ve Oracle Sql Developer'ınız tekrar başlayarak doğru şekilde çalışmaya başlayacaktır.

Umarım işinize yarar :)


15 Mayıs 2015 Cuma

Kalıtımsal Eşleme


Herkese merhabalar.

    Bugün sizlere kalıtımsal eşleme ve nasıl gerçekleştireceğimizden bahsedeceğim. Kalıtım denilince benim aklıma gelen ilk şey ata bir sınıf ve bu ata sınıftan türeyen bir alt sınıftır. Gelin kalıtım konusunu bir detaylandıralım. C# nesne tabanlı bir programlama dilidir, ve bu özellik C#'ın en önemli özelliklerinden biridir. C# yüzde yüz nesne tabanlı dil olması nedeniyle programcılara birçok yönden kolaylıklar sağlamaktadır. Peki bu kalıtım nedir ne işe yarar program geliştiricilere ne gibi kolaylıklar sağlar [1].

    Kalıtım, nesne yönelimli programlamanın en önemli özelliklerinden biridir. Miras alma yolu ile sınıflar birbirinden türetilebilir. Yani mevcut sınıflardan yeni bir sınıf üretme şekli olarak tanımlanabilmektedir. Bu işlemde, türeyen sınıflar türemiş sınıf, kendisinden yeni sınıfların oluşturulduğu sınıflara ise temel sınıf adı verilir [2].

    Türeyen sınıflar, türedikleri sınıfların özelliklerini devralırlar, bununla birlikte kendilerine de özel olarak özellikleri mevcuttur. .NET ortamında bir sınıf sadece bir sınıftan türeyebilir; fakat bir temel sınıf bir çok sınıf türetebilir. Miras almanın temel amacı sınıflar arasında ilişki kurmaktır [2]. Gelin hep birlikte kalıtımın Fluent NHibernate'deki kullanımına bir bakalım.

Kalıtımın Fluent NHibernate'deki kullanımı aşağıdaki üç şekilde gerçekleşmektedir.

  • Table Per Hierarchy (TPH);
  • Table Per Type (TPT);
  • Table Per Concrete Class (TPC).


Table Per Hierarchy (TPH):


    TPH kalıtım yönteminde kalıtım, veritabanının discriminator kısmı gibi herhangi bir koşul ile tanımlanan  koşullu eşleştirmeye bağımlıdır. Ayrıca, kalıtım ağacı sadece bir tablodan üretilmiştir [3].

Table Per Type (TPT):


    TPT, veritabanının ayrı tablolarında açıklanan kalıtımdır. Her tablo ilave olarak detay bulundurur. Bu detaylar, tablonun atasına bağlı olan yeni tipleri açıklamaktadır [3].

Table Per Concrete Class (TPC)


    Bu tip kalıtımda, her sınıf kendi tablosunu içerdiği bir kalıtım hiyerarşisi içerisindedir. Genel özellikler, ayrı bir tabloya konmaktansa her bir tablo içerisine tekrar tekrar yazılır [3].

Kalıtım tiplerini inceledikten sonra gelin hep birlikte bir örnek üzerinden kalıtımı daha iyi anlayalım.

 public class Iletisim  
 {  
   public virtual Guid Id { get; set; }  
   public virtual string Baslik{ get; set; }  
   public virtual string İcerik { get; set; }  
 }  
 public class SMS : Iletisim  
 {  
 }  
 public class Mail : Iletisim  
 {  
 }  


 public class IletisimMap : ClassMap<Iletisim>  
 {  
   public IletisimMap()  
   {  
     Table("Iletisim");  
     Id(x => x.Id).GeneratedBy.GuidComb();  
     DiscriminateSubClassesOnColumn("IletisimTip");  
     Map(x => x.Baslik);  
     Map(x => x.Icerik);  
   }  
 }  

 public class SMSMap : SubclassMap<SMS>  
 {  
   public SMSMap()  
   {  
     DiscriminatorValue(1);  
   }  
 }  
 public class MailMap : SubclassMap<Mail>  
 {  
   public MailMap()  
   {  
     DiscriminatorValue(2);  
   }  
 }  

Yukarıda oluşturulan yapıda Iletisim isimli bir ana sınıf ve bu sınıftan türeyen iki alt sınıf olan SMS ve Mail sınıfları bulunmaktadır. Kullanılan DescriminateSubClassesOnColumn metodu ile hangi alt sınıfın yaratılacağı belirlenir. Ayrıca belirlenmiş olan Discriminator değerleri ile iletişim tipi belirlenerek hangi alt sınıfın yaratılacağının Fluent NHibernate tarafından anlaşılması sağlanmış olur [4].

Yukarıda kurmuş olduğumuz yapı ile kalıtım sağlanmış olur ve discriminator kullanımının ne işe yaradığını da görmüş oluyoruz. Bu haftalık anlatacaklarım bu kadar, umarım faydalı bir yaz olmuştur hoşçakalın..

Kaynaklar 


[1]C# İle Kalıtım(inheritance)- Override ve Virtual Metodlar, http://www.ramazancelikkaya.com/makaleOku/CSharp/131/C, Mayıs 7, 2015.

[2]Inheritence – Miras Alma (Kalıtım), http://www.ismailgursoy.com.tr/inheritence-miras-alma-kalitim/, Mayıs 8, 2015.

[3]Inheritance mapping strategies in Fluent Nhibernate, http://www.codeproject.com/Articles/232034/Inheritance-mapping-strategies-in-Fluent-Nhibernat, Mayıs 8, 2015.

[4]Fluent NHibernate - Table Inheritance - Discriminators, http://www.philliphaydon.com/2011/08/fluent-nhibernate-table-inheritance-discriminators/, Mayıs 9, 2015.

1 Mayıs 2015 Cuma

Convention Sınıflarının Yeniden Yazılması


Herkese merhabalar.

 Bugün sizlere, önceki yazılarda bahsetmiş olduğum convention sınıflarını nasıl kendimize göre değiştirebileceğimizden bahsedeceğim. Öncelikle convention sınıflarının ne olduğunu bir hatırlayalım. Convention sınıfları, tablo ve kolon isimlendirmelerini yaparken bize yardımcı olan default sınıflardır. İsimlendirme sınıflarından bazılarını hatırlayalım. Önceki haftalarda detaylı bir şekilde anlattığım için sadece bazı isimlerini hatırlatacağım [1].

  • ColumnNullabilityConvention
  • PrimaryKeyNameConvention
  • StringColumnLengthConvention
  • IClassConvention
  • IIdConvention
  • IHasManyConvention
  • IReferenceConvention 

 
      İsimlendirme sınıflarını neden değiştirelim ki dediğinizi duyar gibiyim. Örneğin; StringColumnLengthConvention'ın default sınıfında, string tipindeki kolonun uzunluk sınırı belirtilmediyse bu sınıf sayesinde otomatik olarak uzunluk 100 olarak atanır [1]. Eğer bu uzunluğun 100 değil de 50 olmasını istiyorsanız, default olan isimlendirme sınıfını kendinize göre uyarlayıp bu yapıyı kullanabilmeniz gerekiyor.

    İsimlendirme sınıfları(conventions), birçok interface ve ana sınıflar kullanılarak oluşmuş olan sınıflardır [2]. Bu sınıfların her birinde Apply metodu tanımlanmıştır. Bu metot, isimlendirme sınıfının çeşidine göre parametreler almaktadır [3]. Bu metot, eşleştirmelerinize yapmış olduğunuz değişimin yapıldığı yerdir [2]. Eşleştirme sınıfınızın yapısını oluşturduktan sonra default olan isimlendirme sınıfları uygulanır. Aşağıdaki örnek ile isimlendirme sınıflarının mantığını daha iyi anlayacaksınız.

 public class KisiMap : ClassMap<Kisi>  
 {  
  public KisiMap()  
  {  
   Id(x => x.Id);  
   Map(x => x.Ad)  
    .Column("TumAd")  
    .Length(100);  
   Map(x => x.Yas);  
  }  
 }  

Yukarıda belirlemiş olduğumuz mapping sınıfımıza göre, isimlendirmemizin akış şeklini açıklayacağım; kullanmış olduğunuz high-level metodlara bakarak, convention sınıfı mapping sınıfınızın Kisi sınıfı olduğunu, Ad ve Yas olarak iki özelliğinizin olduğuna karar verir. Daha sonra, convention sınıfları, kolon isimleri, uzunluğu gibi değerlere uygulanır [2]. Convention(isimlendirme) sınıflarımızın çalışma yapısını anladıktan sonra, gelin kendi örneğimize bir bakalım.

 public class LowercaseTableNameConvention : IClassConvention  
 {  
  public void Apply(IClassInstance instance)  
  {  
   // değiştirme yapılacak yer..  
  }  
 }  

Yukarıdaki kod ile tablo ismimizi belirleyebilmemiz mümkün; ancak Apply metodunun içerisine tablo isimlerimizin ne yapıda olacağını yazmalıyız.

 public void Apply(IClassInstance instance)  
 {  
  instance.Table("tbl_" + instance.EntityType.Ad);  
 }  

Yukarıda gördüğünüz üzere, IClassInstance interface'i sayesinde Table metodunu kullanarak convention sınıfımızın tablo ismini kendimize göre yazmak bu kadar kolay [2]. Dilediğiniz convention sınıfını Apply metodu sayesinde yukarıdaki şekilde kendinize göre uyarlayabilirsiniz.

Bu haftalık anlatacaklarım bu kadar. Bir sonraki yazıda buluşmak üzere, hoşçakalın..


Kaynaklar


[1] Fluent NHibernate conventions-examples, http://marcinobel.com/index.php/fluent-nhibernate-conventions-examples/, Nisan 27, 2015.

[2] Conventions, https://github.com/jagregory/fluent-nhibernate/wiki/Conventions, Nisan 27, 2015.

[3] Changing The FluentNHibernate Id Conventions, http://candland.net/2009/09/14/changing-the-fluentnhibernate-id-conventions/, Nisan 27, 2015.




26 Nisan 2015 Pazar

Fluent NHibernate Automapping(Otomatik Eşleme)


    Herkese merhabalar.

   Bugün sizlere Fluent NHibernate'in sağlamış olduğu kolaylıklardan bir tanesi olan otomatik eşlemeden bahsedeceğim.  Büyük uygulamalarda modellerinizin eşleştirmelerini yapmak size oldukça sıkıcı gelebilir. Bu durumdan sizi kurtarmak üzere otomatik eşleştirme yardımınıza koşacak. Automapping kavramı; isimlendirme grupları kullanılarak gerçekleştirilen ve objelerinizi otomatik bir şekilde sınıflandıran mekanizmadır [1]. Otomatik eşleştirmede isimlendirme gruplarına(conventions) neden ihtiyaç duyuyoruz dediğinizi duyar gibiyim. Otomatik eşleştirme yaparken eğer convention sınıflarınızı default olarak kullanıyorsanız, otomatik eşleştirici eşleştirme yaparken örneğin; Id isimli integer tipindeki değişkeninizin otomatik olarak artış gösteren bir öncül anahtar(primary key) olduğunu anlaması gerekmektedir [2]. Aşağıdaki örnek ile otomatik eşleştirmenin yapılmasını sağlayan bazı kavramları öğreneceğiz.

 public class Yiyecek  
 {  
  public int Id { get; set; }  
  public virtual string Ad { get; set; }  
  public virtual decimal Fiyat { get; set; }  
 }  
 public class Buzdolabı  
 {  
  public virtual int Id { get; set; }  
  public virtual IList<Yiyecek> Yiyecekler { get; set; }  
 }  

Yukarıdaki kod ile one-to-many ilişkisi kurulmuştur. Bir buzdolabında birden fazla yiyecek bulunabilir. Otomatik eşleştirmemizi yapabilmemiz için Automap sınıfını, fluent konfigürasyon API kombinasyonu ile kullanmalıyız.

 AutoMap.AssemblyOf<T>  

Yukarıdaki kod parçası generic bir tip alan statik bir metottur. Otomatik eşleştirmenizi yapmak istediğiniz sınıfınızı T değişkeninin yerine yazmalısınız. İşte otomatik eşleştirme yapmak bu kadar kolay.  AutoMap.AssemblyOf<Yiyecek>  kodunu çağırdığınız zaman;  Yiyecek sınıfının tanımlandığı assembly'ye bağlanan AutoPersisteneceModel objesi üretilir [3]. Kullanacağımız SessionFactory'i yaratmak için aşağıdaki kod parçasını kullanmalıyız.

 var sessionFactory = Fluently.Configure()  
  .Database(/* database config */)  
  .Mappings(m =>  
   m.AutoMappings  
    .Add(AutoMap.AssemblyOf<Yiyecek>()))  
  .BuildSessionFactory();  

    Automapper, hangi sınıfın objeniz veya servisiniz olduğunu ayırt edemez. Bu yüzden ihtiyacımız olan final bir metot olan Where(Func)'i kullanmalıyız. Bu metot ile genellikle namespace sınırlaması konulur; ancak siz Type objesi ile istediğiniz sınırlamayı koyabilirsiniz [1]. Bu örnekte ben de namespace sınırlamasına ihtiyaç duyuyorum.


 var autoMappings = AutoPersistenceModel  
  .MapEntitiesFromAssemblyOf<Yiyecek>()  
  .Where(t => t.Namespace == "Mutfak.Entities");  
 var sessionFactory = new Configuration()  
  .AddProperty(ConnectionString, ApplicationConnectionString)  
  .AddAutoMappings(autoMappings)  
  .BuildSessionFactory();  

Yukarıdaki şekilde namespace sınırlamamızı koyduktan sonra otomatik eşleştirmemizi tamamlamış olduk. Gördüğünüz gibi yukarıdaki yapıyı kullanarak otomatik eşleştirme yapmak bu kadar basit.  Bu haftalık anlatacaklarım bu kadar. Bir sonraki hafta; isimlendirme sınıflarımızı kendimize göre nasıl uyarlayabileceğimizden bahseceğiz, hoşçakalın..

Kaynaklar


[1] Fluent NHibernate: Auto Mapping Introduction, http://www.jagregory.com/writings/fluent-nhibernate-auto-mapping-introduction/, Nisan 22, 2015.

[2]GETTING STARTED WITH FLUENT NHIBERNATE AND AUTO MAPPING IN C#, http://blog.json.codes/web-development/getting-started-with-fluent-nhibernate-and-auto-mapping-in-c/, Nisan 22, 2015.

[3] Auto mapping, https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping, Nisan 23, 2015.

19 Nisan 2015 Pazar

Fluent NHibernate ile Kullanıcı Tanımlı Tipler Kullanmak



    Herkese merhabalar.


    Bugün sizlere, Fluent NHibernate kullanırken kullanıcı tanımlı tiplerin nasıl kullanıldığından bahsedeceğim. Kullanıcı tanımlı tip derken ne demek istediğimi enum(enumeration) kavramını açıklayarak ifade etmek istiyorum. Program içerisinde kullanılan sabitlerin anlamlandırılması ile sabitlere isim vererek bir grup altında toplayabiliriz. İşte bu gruplara enum(enumaretion) denmektedir. Enum içerisindeki elemanlar, dizilerdeki gibi 0 sıra numarasından başlamak üzere sıralanır [1]. Enum kullanımını daha iyi anlamamız açısından, enum denilince akla gelen klasik örneği sizlerle paylaşmak istiyorum.

   Örneğin; programımızda haftanın günlerini kullanmak isteyelim. Bu günler ile karmaşık işlemler yapmak isteyelim. Bunun için  her güne sayısal değer vermemiz bizim işimizi görecektir. Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi, ve Pazar’a 0,1,2,3,4,5 ve 6 tam sayı değerlerini tanımlamamız yeterli olacak ve bu tam sayılar üzerinden işlemlerimizi gerçekleştireceğiz. Öte yandan, sıfırı (0) kullandıktan ve bir süre sonra koda baktığımızda sıfırın Pazartesi gününü ifade ettiğini hatırlayamayabiliriz. Bu durumda, C# bizlere güzel bir çözüm sunar. Bu çözümde; değerlerin grup sembolik bir ad ile bildirilebileceği "enum" anahtar sözcüğü kullanılır [2]. Enumeration türünü aşağıdaki şekilde tanımlayabiliriz.

 Enum HaftaGunler  
 {  
 Pazartesi,  
 Sali,  
 Carsamba,  
 Persembe,  
 Cuma,  
 Cumartesi,  
 Pazar  
  }  

Enumeration türünü yukarıdaki şekilde tanımladıktan sonra aşağıdaki şekilde erişebiliriz.


 HaftaGunler gun = HaftaGunler.Pazar;  
 MessageBox.Show(gun.ToString());  

Böylelikle, mesaj kutumuzda "6" yazacaktır. Haftanın günlerinin hepsini birden almak istersek .GetNames() metodunu kullanırız. Bu metot yardımıyla enum içerisinde kullandığımız değerleri  string formatında bir dizide aşağıdaki şekilde kullanabiliriz [2].

  string[] gunler = Enum.GetNames(typeof(HaftaGunler));  

    Şimdi de enumların Fluent NHibernate'teki kullanımına bakalım. Fluent NHibernate ile özel bir kullanıcı tipi tanımlanmak istendiğinde, IUserType arayüzünden kalıtılmış bir sınıf ile ilgili tipi tanımlayabiliriz [3]. Aşağıdaki kod örneğinde, lisans ve yüksek lisans öğrenci tipini içeren enum kullanılmıştır [4].

 public enum Ogrencitipi  
 {  
   Lisans,  
   Yukseklisans  
 }  

 using System;  
 using System.Data;  
 using NHibernate.SqlTypes;  
 using NHibernate.UserTypes;  
 namespace YourNamespace.Persistence.Mappings.CustomTypes  
 {  
   public class OgrencitipiMap : IUserType  
   {  
     new public bool Equals(object x, object y)  
     {  
       return object.Equals(x, y);  
     }  
     public int GetHashCode(object x)  
     {  
       return x.GetHashCode();  
     }  
     public object NullSafeGet(IDataReader rs, string[] names, object owner)  
     {  
       object r = rs[names[0]];  
       var value = (string)r;  
       if (string.IsNullOrEmpty(value))  
         throw new Exception("Geçersiz!");  
       switch (value)  
       {  
         case "L":  
           return Ogrencitipi.Lisans;  
         case "Y":  
           return Ogrencitipi.Yukseklisans;  
         default:  
          throw new Exception("Geçersiz öğrenci tipi!");  
       }  
     }  
     public void NullSafeSet(IDbCommand cmd, object value, int index)  
     {  
       object paramVal = 0;  
       switch ((Ogrencitipi)value)  
       {  
         case Ogrencitipi.Lisans: paramVal =  
          "L"; break;  
       case Ogrencitipi.Yukseklisans: paramVal =  
          "Y"; break;  
         default:  
           throw new Exception("Geçersiz öğrenci tipi!");  
       }  
       var parameter = (IDataParameter)cmd.Parameters[index];  
       parameter.Value = paramVal;  
     }  
     public object DeepCopy(object value)  
     {  
       return value;  
     }  
     public object Replace(object original, object target, object owner)  
     {  
       return original;  
     }  
     public object Assemble(object cached, object owner)  
     {  
       return cached;  
     }  
     public object Disassemble(object value)  
     {  
       return value;  
     }  
     public SqlType[] SqlTypes  
     {  
       get { return new SqlType[] { new StringSqlType() }; }  
     }  
     public Type ReturnedType  
     {  
       get { return typeof(Ogrencitipi); }  
     }  
     public bool IsMutable  
     {  
       get { return false; }  
     }  
   }  
 }  

Mapping sınıfınızda aşağıdaki şekilde eşleştirmenizi yapabilirsiniz.

  //NHibernate 2.X  
   Map(x=>x.Ogrencitipi).CustomType<OgrencitipiMap>();  
   //NHibernate 3.X  
   Map(x=>x.Ogrencitipi).CustomTypeIs<OgrencitipiMap>();  

Yukarıdaki örnekte gördüğünüz gibi enum yapısını kullanarak istediğiniz verileri Fluent NHibernate projenizde kullanabilirsiniz. Enum kullanımının faydaları; kod okunabilirliğini arttırması, muhtemel değer kümesinin daraltılması ve tip güvenliğini sağlaması dolayısıyla hata payını en aza indirmesidir [5]. Böylelikle yeri geldiğinde projemizde enum kullanımının nasıl gerçekleşeceğini görmüş olduk.

    Umarım faydalı bir yazı olmuştur, hoşçakalın..

Kaynaklar


[1]C# ile Enum Kullanımı, http://sanalkurs.net/c-ile-enum-kullanimi-8423.html, Nisan 15, 2015.

[2]C# ve Enumeration (Enum) Kullanımı, http://emraheroglu.blogspot.com.tr/2010/01/c-ve-enumeration-enum-kullanm.html, Nisan 16, 2015.

[3]Fluent NHibernate ile kullanıcı tanımlı tipler kullanmak, http://b.zor.lu/fluent-nhibernate-ile-kullanici-tanimli-tipler-kullanmak/, Nisan 16, 2015.

[4]USING AN ENUM ON A FLUENTNHIBERNATE MAPPING [C#], http://crodrigues.com/using-a-enum-on-a-fluentnhibernate-mapping-c/, Nisan 17, 2015.

[5]Daha Okunabilir Kod ve Yaşanabilir Dünya İçin Enum’lar, http://kodcu.com/2014/08/okunabilir-kod-ve-enum/, Nisan 17, 2015.

11 Nisan 2015 Cumartesi

HQL (Hibernate Query Language)

Herkese merhabalar.

   Doğrudan SQL sorgularını kullanarak veritabanı üzerinde işlemler gerçekleştirmek istemiyorsanız; nesneler üzerinde işlem yaparak da veritabanı işlemlerinizi gerçekleştirebileceğiniz bir sorgu dili mevcut. Bugün sizlere Hibernate'in sorgu dilinden bahsetmek istiyorum. Hibernate sorgu dili, SQL'e benzer özellikleri olan nesne tabanlı bir sorgu dilidir. HQL'in SQL'den en önemli bilinmesi gereken farkı; SQL kolonlar ve tablolar üzerinde işlem yaparken, HQL objeler ve diğer özellikler üzerinde işlemlerini gerçekleştirir. HQL, Hibernate tarafından, veritabanı üzerinde doğrudan işlem gerçekleştirebilen SQL'e dönüştürülür. Şu unutulmamalıdır ki veritabanı ile en yakın olan katman her zaman SQL'dir [1]. 

   HQL yazarken büyük-küçük harf duyarlılığına dikkat edilmelidir. WHERE, SELECT, FROM gibi kelimeler de  büyük-küçük harf duyarlılığı aranmazken; tablo ve kolon isimleri gibi özellikler yazılırken büyük-küçük harf duyarlılığı mevcuttur. Şunu da eklemek istiyorum; HQL'in güzel özelliklerinden birisi de  veritabanından bağımsız yazılan bir sorgu dili olmasıdır [1].  Gelin hep birlikte HQL'de en çok kullanılan kalıplara bakalım.

from ve as 

 from obje [as nil_obje]*   
 obje_adi  
  
   Genellikle select ile kullanılır. Sorguda istenilen cevabın hangi tablodan çekileceğini belirtir. "as" ifadesi ile uzun ve kullanımı zor olan tablo veya alan adlarına geçici olarak kısa isimler vererek bunları kodlamamızda kullanabiliriz [2]. Böylece mevcut tablo yapımız bozulmadan dinamik olarak belirlediğimiz isimleri kullanabilmekteyiz.

select


Sorgunun sonuç kümesinde ne olacağını belirten sözcüktür [2].

 select ogrenciisim from bilgisayarMuhendisligi as bilgisayarogrencisi  


where


   Sorgu kümesinde dönmesi istenen durumların istenen koşullar doğrultusunda dönmesini sağlayan sözcüktür. =, >, AND, NOT  gibi operatörler kullanılır [2].

  select ogrenciisim from bilgisayarMuhendisligi as bilgisayarogrencisi where ogrenci_no > 10   

Birleşik Değerli Fonksiyonlar


   Birleşik değerli fonskiyonlar kullanılarak, yapılan sorgulama alanı daraltılarak çalışma süresi optimize edilebilir [2,3].

  • avg(): Ortalama değeri döndürür.
  • count(): İstenilen değere bağlı kayıt sayısını döndürür. Boş değer içeren kaydı saymaz.
  • count(*): İstenilen değere bağlı kayıt sayısını döndürür. Boş değer içeren kaydı sayar.
  • first(): İlk değeri döndürür.
  • last(): Son değeri döndürür.
  • max(): En büyük değeri döndürür.
  • min(): En küçük değeri döndürür.
  • sum(): Toplam değeri döndürür.


 select count(Meslek) from tblKomsular  


Insert Kullanımının SQL'den Farkı



   Bilinmesi gereken önemli noktalardan birisi; HQL'de doğrudan tabloya ekleme yapamazsınız; ancak bir tablodan diğer tabloya ekleme yapabilirsiniz [1].

Alt Sorguların Kullanımı


   Alt sorgular, sorgusu oldukları ana sorgudan önce çalıştırılırlar. Parantez içine yazılılırlar ve "where" sözcüğüyle birlikte kullanılarak istenilen sorgu yanıtının aralığını daraltmaya yardımcı olurlar [1,4].

 select bolumad from bolumler as bolum where bolumgelir> (bolumgelir avg() from bolum)  

Örnek HQL Sorgusu

 var bloglar = s.CreateQuery("from Blog b where b.Baslik = :baslik and b.Altbaslik = :altbaslik")  
   .SetParameter("baslik","Nil Busra Ozer Kisisel Blog")  
   .SetParameter("altbaslik", "Hibernate Query Language")  
   .List<Blog>();  

 
   Bugünlük anlatacaklarım bu kadar. HQL çok derin bir konu olduğu için özellikle temel kullanımlarına değinmek istedim. Bir sonraki yazımda görüşmek üzere, hoşçakalın..

Kaynaklar


[1]HibernateQueryLanguage,http://www.tutorialspoint.com/hibernate/hibernate_query_language.htm, Nisan 8, 2015.

[2]Introducing HQL: The Object-Oriented Query Language from Hibernate, http://www.developer.com/open/article.php/3322131/Introducing-HQL-The-Object-Oriented-Query-Language-from-Hibernate.htm, Nisan 8, 2015.

[3]Using HQL (Hibernate Query Langıage), http://docs.castleproject.org/Active%20Record.Using%20HQL%20(Hibernate%20Query%20language).ashx, Nisan 9, 2015.

[4]NHibernate Queries-Examples, http://ayende.com/blog/4023/nhibernate-queries-examples, Nisan 9, 2015.



5 Nisan 2015 Pazar

Fluent NHibernate CRUD İşlemleri


Herkese merhabalar.

   Bugün sizlere Fluent NHibernate'in temel konusu olan CRUD işlemlerinden bahsedeceğim. Bu işlemleri gerçekleştirmeyi öğrendiğinizde Fluent NHibernate'i daha iyi kavramaya başlayacağınızı fark edeceksiniz. Gelin hep birlikte aşağıdaki örneğimiz ile bu işlemleri anlayalım.

   Örneğimizde teknoloji isimli bir veritabanımız olacak. Bu veritabanımızda, Marka, Telefon ve Televizyon tablolarını oluşturup bunlar üzerinde okuma, kayıt ekleme, kayıt silme ve kayıt güncelleme işlemlerini gerçekleştireceğiz.

   Önceki yazımda bahsettiğim şekilde gerekli dll dosyalarımızı projemize ekleyelim.



   Solution explorer'ımıza aşağıdaki şekilde uygun klasörlerin altında sınıflarımızı  oluşturalım.

   Örneğimizde; iki teknolojik cihaz ve bunların markaları üzerinden gideceğiz. Telefonun marka ile ve Televizyonun marka ile many-to-one ilişkisi vardır. Şöyle ki; bir telefonun bir markası var iken bir marka birden fazla telefona hatta farklı televizyon gibi telefondan farklı cihazların markası olabilmektedir.


Marka.cs


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace TelefonFluentHibernate.Entites  
 {  
   class Marka  
   {  
     public virtual int MarkaId { get; set; }  
     public virtual string MarkaAd { get; set; }  
   }  
 }  

Telefon.cs


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace TelefonFluentHibernate.Entites  
 {  
   class Telefon  
   {  
     public virtual int telefonId{get; set;}  
     public virtual string telefonAd { get; set;}  
     public virtual string telefonRenk { get; set; }  
     public virtual int telefonFiyat { get; set; }  
     public virtual Marka telefonMarka { get; set; }  
   }  
 }  

Televizyon.cs


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace TelefonFluentHibernate.Entites  
 {  
   class Televizyon  
   {  
     public virtual int televizyonId { get; set; }  
     public virtual string televizyonAd { get; set; }  
     public virtual string televizyonRenk { get; set; }  
     public virtual int televizyonFiyat { get; set; }  
     public virtual Marka televizyonMarka { get; set; }  
   }  
 }  

MarkaMap.cs

 using FluentNHibernate.Mapping;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate.Mapping  
 {  
   class MarkaMap : ClassMap <Marka>  
   {  
     public MarkaMap()  
     {  
       Id(x => x.MarkaId);  
       Map(x => x.MarkaAd);  
       Table("Marka");  
     }  
   }  
 }  

TelefonMap.cs

 using FluentNHibernate.Mapping;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate.Mapping  
 {  
   class TelefonMap : ClassMap <Telefon>  
   {  
     public TelefonMap()  
     {  
       Id(x => x.telefonId);  
       Map(x => x.telefonAd);  
       Map(x => x.telefonFiyat);  
       Map(x => x.telefonRenk);  
       References(x => x.telefonMarka).Column("MarkaId");  
       Table("Telefon");  
     }  
   }  
 }  

TelevizyonMap.cs

 using FluentNHibernate.Mapping;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate.Mapping  
 {  
   class TelevizyonMap : ClassMap <Televizyon>  
   {  
     public TelevizyonMap()  
     {  
       Id(x => x.televizyonId);  
       Map(x => x.televizyonAd);  
       Map(x => x.televizyonFiyat);  
       Map(x => x.televizyonRenk);  
       References(x => x.televizyonMarka).Column("MarkaId");  
       Table("Televizyon");  
     }  
   }  
 }  

NHibernateHelper.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using FluentNHibernate.Cfg;  
 using FluentNHibernate.Cfg.Db;  
 using NHibernate;  
 using NHibernate.Tool.hbm2ddl;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate  
 {  
   public class NHibernateHelper  
   {  
     private static ISessionFactory _sessionFactory;  
     private static ISessionFactory SessionFactory  
     {  
       get  
       {  
         if (_sessionFactory == null)  
           InitializeSessionFactory();  
         return _sessionFactory;  
       }  
     }  
     private static void InitializeSessionFactory()  
     {  
       _sessionFactory = Fluently.Configure()  
         .Database(MySQLConfiguration.Standard  
                .ConnectionString(  
                  @"Server=localhost; Port=3306;Database=teknoloji; Uid=root; Pwd=;")  
                .ShowSql()  
         )  
         .Mappings(m =>  
              m.FluentMappings  
                .AddFromAssemblyOf<Program>())  
         .ExposeConfiguration(cfg => new SchemaExport(cfg)  
                         .Create(true, true))  
         .BuildSessionFactory();  
     }  
     public static ISession OpenSession()  
     {  
       return SessionFactory.OpenSession();  
     }  
   }  
 }  

Program.cs

 using NHibernate;  
 using NHibernate.Criterion;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate  
 {  
   class Program  
   {  
     static void Main(string[] args)  
     {  
       var telefonNNote4 = new Telefon  
       {  
         telefonAd = "note 4",  
         telefonFiyat = 500,  
         telefonRenk = "beyaz"  
       };  
       var televizyon = new Televizyon  
       {  
         televizyonAd = "tv1",  
         televizyonRenk = "siyah",  
         televizyonFiyat = 1000  
       };  
       var televizyon2 = new Televizyon  
       {  
         televizyonAd = "tv2",  
         televizyonRenk = "beyaz",  
         televizyonFiyat = 1430  
       };  
       var markaSamsung = new Marka  
       {  
         MarkaAd = "samsung"  
       };  
       var markaApple = new Marka  
       {  
         MarkaAd = "apple"  
       };  
       //Create kısmı. Telefon Ekle  
       Ekle<Telefon>(telefonNNote4);  
       //Televizyon ekle  
       Ekle<Televizyon>(televizyon);  
       Ekle<Televizyon>(televizyon2);  
       //Marka ekle  
       Ekle<Marka>(markaSamsung);  
       Ekle<Marka>(markaApple);  
       //Update kısmı. Telefonu güncelle  
       telefonNNote4.telefonMarka = markaSamsung;  
       Guncelle<Telefon>(telefonNNote4);  
       //Televizyonu güncelle  
       televizyon.televizyonMarka = markaApple;  
       televizyon.televizyonRenk = "pembe";  
       Guncelle<Televizyon>(televizyon);  
       televizyon2.televizyonMarka = markaApple;  
       Guncelle<Televizyon>(televizyon2);  
       //Read kısmı   
       Marka marka = Oku("apple");  
       Console.WriteLine("Okunan satir: "+marka.MarkaId+" - "+marka.MarkaAd);  
       //Delete kısmı. Televizyon sil  
       Sil<Televizyon>(televizyon);  
     }  
     private static void Ekle<T>(T yeniKayit)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           session.Save(yeniKayit);  
           transaction.Commit();  
           Console.WriteLine("Yeni kayıt eklendi.");  
         }  
       }  
     }  
     private static void Guncelle<T>(T guncelKayit)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           session.SaveOrUpdate(guncelKayit);  
           transaction.Commit();  
           Console.WriteLine("Kayit güncellendi. ");  
         }  
       }  
     }  
     private static void Sil<T>(T silKayit)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           session.Delete(silKayit);  
           transaction.Commit();  
           Console.WriteLine("Kayit silindi. ");  
         }  
       }  
     }  
     private static Marka Oku(string markaAdi)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         Marka markaQuery = (from markaNesnesi in session.QueryOver<Marka>()  
                   where markaNesnesi.MarkaAd == markaAdi  
                   select markaNesnesi).SingleOrDefault();  
         /*IQuery q2 = session.CreateQuery("from Marka WHERE markaAd='" + markaAdi + "';");  
         var markaListesi = q2.List<Marka>();*/  
         Console.WriteLine("Uygun satır bulundu: " + markaQuery.MarkaAd);  
         return markaQuery;  
       }  
     }  
   }  
 }  

Konsol Çıktısı

 alter table telefon drop foreign key FKA4173F7AC8A29C0D  
 alter table Televizyon drop foreign key FK7ADB542AC8A29C0D  
   drop table if exists Marka  
   drop table if exists telefon  
   drop table if exists Televizyon  
   create table Marka (  
     MarkaId INTEGER NOT NULL AUTO_INCREMENT,  
     MarkaAd VARCHAR(255),  
     primary key (MarkaId)  
   )  
   create table telefon (  
     telefonId INTEGER NOT NULL AUTO_INCREMENT,  
     telefonAd VARCHAR(255),  
     telefonFiyat INTEGER,  
     telefonRenk VARCHAR(255),  
     MarkaId INTEGER,  
     primary key (telefonId)  
   )  
   create table Televizyon (  
     televizyonId INTEGER NOT NULL AUTO_INCREMENT,  
     televizyonAd VARCHAR(255),  
     televizyonFiyat INTEGER,  
     televizyonRenk VARCHAR(255),  
     MarkaId INTEGER,  
     primary key (televizyonId)  
   )  
   alter table telefon  
     add index (MarkaId),  
     add constraint FKA4173F7AC8A29C0D  
     foreign key (MarkaId)  
     references Marka (MarkaId)  
   alter table Televizyon  
     add index (MarkaId),  
     add constraint FK7ADB542AC8A29C0D  
     foreign key (MarkaId)  
     references Marka (MarkaId)  
 NHibernate: INSERT INTO telefon (telefonAd, telefonFiyat, telefonRenk, MarkaId)  
 VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 'note 4' [Type: String (6)], ?p1 = 500 [Type:  
 Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 = NULL [Type: Int32 (0)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Televizyon (televizyonAd, televizyonFiyat, televizyonRen  
 k, MarkaId) VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 'tv1' [Type: String (3)], ?p1 = 10  
 00 [Type: Int32 (0)], ?p2 = 'siyah' [Type: String (5)], ?p3 = NULL [Type: Int32  
 (0)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Televizyon (televizyonAd, televizyonFiyat, televizyonRen  
 k, MarkaId) VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 'tv2' [Type: String (3)], ?p1 = 14  
 30 [Type: Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 = NULL [Type: Int32  
 (0)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Marka (MarkaAd) VALUES (?p0);?p0 = 'samsung' [Type: Stri  
 ng (7)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Marka (MarkaAd) VALUES (?p0);?p0 = 'apple' [Type: String  
  (5)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: UPDATE telefon SET telefonAd = ?p0, telefonFiyat = ?p1, telefonRenk  
 = ?p2, MarkaId = ?p3 WHERE telefonId = ?p4;?p0 = 'note 4' [Type: String (6)], ?p  
 1 = 500 [Type: Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 = 1 [Type: Int3  
 2 (0)], ?p4 = 1 [Type: Int32 (0)]  
 Kayit güncellendi.  
 NHibernate: UPDATE Televizyon SET televizyonAd = ?p0, televizyonFiyat = ?p1, tel  
 evizyonRenk = ?p2, MarkaId = ?p3 WHERE televizyonId = ?p4;?p0 = 'tv1' [Type: Str  
 ing (3)], ?p1 = 1000 [Type: Int32 (0)], ?p2 = 'pembe' [Type: String (5)], ?p3 =  
 2 [Type: Int32 (0)], ?p4 = 1 [Type: Int32 (0)]  
 Kayit güncellendi.  
 NHibernate: UPDATE Televizyon SET televizyonAd = ?p0, televizyonFiyat = ?p1, tel  
 evizyonRenk = ?p2, MarkaId = ?p3 WHERE televizyonId = ?p4;?p0 = 'tv2' [Type: Str  
 ing (3)], ?p1 = 1430 [Type: Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 =  
 2 [Type: Int32 (0)], ?p4 = 2 [Type: Int32 (0)]  
 Kayit güncellendi.  
 NHibernate: SELECT this_.MarkaId as MarkaId0_0_, this_.MarkaAd as MarkaAd0_0_ FR  
 OM Marka this_ WHERE this_.MarkaAd = ?p0;?p0 = 'apple' [Type: String (5)]  
 Uygun satır bulundu: apple  
 Okunan satir: 2 - apple  
 NHibernate: DELETE FROM Televizyon WHERE televizyonId = ?p0;?p0 = 1 [Type: Int32  
  (0)]  
 Kayit silindi.  

    Yukarıdaki örnekte kodu yorumları ile birlikte çok rahat anlayacaksınız. Sadece üç tane entity ve üç tane mapping sınıfımız var ve bunlar üzerinde; ekleme, okuma, güncelleme ve silme işlemlerini gerçekleştiriyoruz. Dikkat etmeniz gereken özellikle önemli gördüğüm noktalara değinmek istiyorum. Marka ile Telefon veya Marka ile Televizyon arasındaki ilişki many-to-one olduğundan dolayı; referans olarak many olan tarafta yani Telefonda ve Televizyonda Marka'yı belirtmek zorundayız. "References" kullanımını many olan kısımda yazdığımızı üzerine basa basa söylemek istiyorum aksi taktirde durduk yere hatalar ile karşılaşırsınız. İkinci olarak söylemek istediğim; Marka tipindeki Oku metodu ile markayı okuduğumuz zaman karşımıza çıkan ilk kaydı döndürmek istersek, aşağıdaki şekilde SingleOrDefault yapısını kullanmalıyız.

 Marka markaQuery = (from markaNesnesi in session.QueryOver<Marka>()  
                   where markaNesnesi.MarkaAd == markaAdi  
                   select markaNesnesi).SingleOrDefault();  

   Eğer aradığımız marka adına sahip tüm nesneleri döndürmek istiyorsak, aşağıdaki kod parçasının yardımı ile okuma yapmalıyız.

 IQuery q2 = session.CreateQuery("from Marka WHERE markaAd='" + markaAdi + "';");  
         var markaListesi = q2.List<Marka>();  

   Bugünlük anlatacaklarım bu kadar. Herkese bol kodlu günler.

Referanslar

[1] Create, read, update and delete, http://en.wikipedia.org/wiki/Create,_read,_update_and_delete, Nisan 2, 2015.

[2]Simplify Database Operations with Generic Fluent NHibernate, http://www.codeproject.com/Articles/380022/Simplify-Database-Operations-with-Generic-Fluent-N, Nisan 3, 2015.

[3]Tutorial on NHibernate and FluentNhibernate,  https://thehelios.wordpress.com/2011/07/11/tutorial-on-nhibernate-and-fluentnhibernate/, Nisan 4, 2015.