Merhaba arkadaşlar, yazımıza kaldığımız yerden devam ediyoruz.
Dersimizden önce şunu demek istiyorum. Yazılarımı olduğunca basit düzeyde yazıyorum. Hibernate yeni başlayan kişiler için ağır ve anlam karmaşası yaratacak terimler kullanmak yerine o an aklımdan bu yazı ile ilgili ne geçiyorsa ona göre yazıyorum. Eğer daha detaylı öğrenmek isterseniz Levent hocamızın ‘injavawetrust’ bloguna bakmanızı tavsiye ederim.
Bu hafta tablolar arasındaki ilişkileri işleyeceğiz.
İlk örneğimize başlayalım o zaman 🙂
Bu örneğimizde @Embedable – @Embeded annotations(dipnot) işleyeceğiz.
@Embedable – @Embeded nedir?
Bu dipnotları şöyle düşünebiliriz. Her tabloda ortak kullanacağımız sütunları bir @Embedable sınıfında tanımlıyoruz ve ihtiyacımız olan propertyleri/instance veriable’leri başka tablolara ekliyoruz.
Şöyle bir örnek verebilirim.
Diyelim ki bir Öğretmen, Öğrenci, Mühendis tablolarımız var. Bunların hepsinin ortak özellikleri nedir? Hepsinin bir adı, soyadı ve yaşı var. Biz bunların ortak özelliği olan property’leri @Embedable sınıfında tanımlarsak ve bunu da ihtiyacımız olan sınıflarda @Embeded dipnotu kullanarak tabloya gömebiliriz.
Şimdi nasıl kullanıldığına bakalım..
Resimde de görüldüğü gibi @Entity dipnotu yerine burada @Embedable annotation’u kullandık. Bu sınıfın artık gömülebilir sınıf olduğunu belirtmiş olduk.
Kodlarımız ise ;
import javax.persistence.Embeddable; @Embeddable public class People { private String name; private String surname; private int year; public People() { } public People(String name, String surname, int year) { this.name = name; this.surname = surname; this.year = year; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } }
Şimdi ise People sınıfı gömeceğimiz sınıfa geliyoruz. Ben Students.class içine gömdüm sizde başka örnekler yapabilirsiniz.
Resimde de görüldüğü üzere People class’ın nesnesini oluşturduk ve üzerinde de @Embeded dipnotunun tanımladık. Burada artık People class’ının özelliklerini buraya da vermiş olduk.
Kodlarımız;
import javax.persistence.Column; import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Students { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int studentId; // Normalde böyle bir kullanım olmaz ama ben sadece burada nasıl bir class'ı başka bir class'a //gömebileceğimiz göstermek istedim @Embedded private People people; @Column(name = "SCHOOL") private String schoolName; public Students() { // TODO Auto-generated constructor stub } public Students(People people, String schoolName) { this.people = people; this.schoolName = schoolName; } public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public People getPeople() { return people; } public void setPeople(People people) { this.people = people; } public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } }
People sınıfını birde teacher sınıfımıza gömüyoruz.
Resimde görüldüğü gibi People sınıfımızın ortak kullanacağımız özelliklerini birden fazla tabloya gömebiliyoruz. Peki bize ne faydası oldu her tabloda name, surname, year tanımlamak yerine bir sınıf ta tanımladık ve ihtiyacımız gerektiğinde @Embeded dipnotunu kullanarak gömme işlemi yaptık.
Kodlarımız ise;
import javax.persistence.Embedded; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Teacher { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int teacherId; @Embedded private People people; private String teacherBranch; public Teacher() { // TODO Auto-generated constructor stub } public Teacher(People people, String teacherBranch) { this.people = people; this.teacherBranch = teacherBranch; } public int getTeacherId() { return teacherId; } public void setTeacherId(int teacherId) { this.teacherId = teacherId; } public People getPeople() { return people; } public void setPeople(People people) { this.people = people; } public String getTeacherBranch() { return teacherBranch; } public void setTeacherBranch(String teacherBranch) { this.teacherBranch = teacherBranch; } }
Sıra geldi ‘hibernate.cfg.xml’ dosyamıza burada oluşturduğumuz @Entity’leri orada tanıtmamız gerekiyordu. Bu örneğimizde üç sınıf kullandık. İki tanesi @Entity bir tanesi ise @Embedable kullandık. Biz sadece @Entity’leri hibernate.cfg.xml dosyamızda tanımlıyoruz. Hangi classlar tablolanacaksa o sınfıların ismini veriyoruz.
hibernate.cfg.xml dosyamızın kodları ise ;
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory name=""> <property name="hibernate.connection.driver_class">org.postgresql.Driver</property> <property name="hibernate.connection.url">jdbc:postgresql://127.0.0.1:5432/Hibernate</property> <property name="hibernate.connection.username">postgres</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property> <property name="hibernate.hbm2ddl.auto">create</property> <property name="hibernate.show_sql">true</property> <mapping class="Students"/> <mapping class="Teacher"/> </session-factory> </hibernate-configuration>
ilk dersimizde ‘hibernate.cfg.xml’ dosyasından bahsetmiştik.
Burada oluşturduğumuz @Entity’leri burada bildirmiş olduk.
<mapping class="Students"/> <mapping class="Teacher"/>
Main methodumuzun bulunduğu sınıfta ise;
Bu resimde de görüldüğü gibi ben 5 tane kişi nesnesi oluşturdum ve bu nesneleri Student ve Teacher sınıfında oluşturduğum constructor’lara parametre olarak gönderdim.
Ve veritabanımıza kaydedilecek olan nesneleri, ‘session’ nesnesini kullanarak ekleme işlemi yaptım.
Kodlarımız ise;
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] args) { People person1 = new People("Ferhat", "Aykan", 1994); People person2 = new People("Enes", "Çınar", 1994); People person3 = new People("Uğur", "Baş", 1995); People person4 = new People("Hasan", "Yildiz", 1970); People person5 = new People("Osman", "Kaya", 1980); Teacher teacher1 = new Teacher(person4, "Matematik"); Teacher teacher2 = new Teacher(person5, "Fizik"); Students student1 = new Students(person1, "DPU"); Students student2 = new Students(person2, "ODTU"); Students student3 = new Students(person3, "YTU"); SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); Session session = sessionFactory.openSession(); session.save(teacher1); session.save(teacher2); session.save(student1); session.save(student2); session.save(student3); session.beginTransaction().commit(); session.close(); } }
Uygulamamızı çalıştırdığımızda ise;
Resimde de görüldüğü gibi iki tablo oluştuğunu görmekteyiz. Birinci örneğimizi bitirdik.
Şimdi yeni bir maven projesi açıyoruz. İlk dersimizde nasıl açılacağını detaylı bir şekilde anlattım. Gerekli Jar dosyalarını da ekledikten sonra ilişkilere devam edelim.
Bu örneğimizde @ElementCollection‘dan bahsedeceğim. Bunu şöyle düşünebiliriz.
Bir kişinin birden fazla ’email’ adresi yada telefon numarası olabilir. Biz bu verileri aynı topla da tutmayız farklı bir tablo oluşturur oraya o kişinin foreign key’ini veririz. Şuan belki tam anlaşılır değil ama örneğimizi yaptıktan sonra mantığınıza oturacaktır.
Yeni bir proje açmıştık. Bu örneğimizde yeniden Student Class açıyoruz ve @Entity olarak tanımlayıp ‘hibernate.cfg.xml’ dosyamızda bildiriyoruz.
Şimdi Student sınıfımıza bakalım;
Burada List yapısını birden fazla numara ve email için kullandık ve içine ekleyeceğimiz verilerin type String dedik.
Üzerinde de @ElementCollection dipnotunu tanımladık. Burada bize başka bir tablo oluşturup List’in içindeki verileri oraya ekleyeceğimi belirttik ve her @ElementCollection için yeni bir tablo oluşturuyor.
Kodlarımız;
import java.util.List; import javax.persistence.ElementCollection; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Student { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int studentId; private String name; private String surname; private int year; @ElementCollection private List<String> emails; @ElementCollection private List<String> phoneNumbers; public Student() { } public Student(String name, String surname, int year, List<String> emails, List<String> phoneNumbers) { this.name = name; this.surname = surname; this.year = year; this.emails = emails; this.phoneNumbers = phoneNumbers; } public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public List<String> getEmails() { return emails; } public void setEmails(List<String> emails) { this.emails = emails; } public List<String> getPhoneNumbers() { return phoneNumbers; } public void setPhoneNumbers(List<String> phoneNumbers) { this.phoneNumbers = phoneNumbers; } }
Main methodumuzun bulunduğu sınıfa bakalım.
Burada 2 tane List oluşturuyoruz ve bu listlerin nesnelerini Student sınıfımızdaki constructor’a parametre olarak yolluyoruz.
Resimde de görüldüğü üzere 2 tane list oluşturup parametre olarak gönderdik.
Kodlarımız;
import java.util.ArrayList; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class Test { public static void main(String[] args) { List<String> emails = new ArrayList<String>(); List<String> phoneNumbers = new ArrayList<String>(); emails.add("[email protected]"); emails.add("[email protected]"); emails.add("[email protected]"); phoneNumbers.add("055555"); phoneNumbers.add("066666"); phoneNumbers.add("077777"); Student student = new Student("Ferhat", "Aykna", 1994, emails, phoneNumbers); SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory(); Session session = sessionFactory.openSession(); session.save(student); session.beginTransaction().commit(); session.close(); } }
Uygulamamızı çalıştırdığımızda ise 3 tane tablo oluştuğunu görmekteyiz. Student , student_emails ve students_phonenumbers şeklinde.
Peki oluşturduğumuz tabloların adlarını nasıl değiştireceğiz.
Bunun içinde yeni bir dipnot kullanıyoruz.
@CollectionTable(name = “TABLO ADI” , JoinColumn = @JoinColumn(name = “FOREIGN KEY ADI”) şeklinde tanımlıyoruz.
Yukararıdaki örneğimiz de ufak bir değişiklik yapıyoruz.
@ElementCollection @CollectionTable(name = "STUDENT_EMAİL", joinColumns = @JoinColumn(name = "student_id")) @Column(name = "EMAIL") private List<String> emails; @ElementCollection @CollectionTable(name = "STUDENT_PHONENUMBER", joinColumns = @JoinColumn(name = "student_id")) @Column(name = "phone_number") private List<String> phoneNumbers;
Bu şekilde tanımladığımızda tablomuzun isimleri ve oraya eklediğimiz foreign key isimleri değişmektedir.
@Column dipnotuyla da emails column’un adını değiştirdik.
Bu yazımı burada sonlandırıyorum. Önümüzdeki hafta ilişkilere kaldığımız yerden devam edeceğiz. Kolay gelsin 🙂