جاوا و تکنولوژی های آن

java programming language

در این وبلاگ به بررسی نکات موجود در جاوا و تکنولوژی های آن می پردازیم

طبقه بندی موضوعی


ORM : Object Relational Mapping

فرق دنیای Objective و Relational : 

برای نگه داری دیتا ما دو دنیای متفاوت داریم یا Objective است یا Relational 

 

در ابجکت ها هیچ چیز به جز اشیاء نداریم 

دیتا ها در قالب field نگهداری میشوند 

ابجکت ها بین خودشان ارث بری ، Composition و رابطه یک به یک ، یک به چند و چند به چند دارند

میتوانیم یکتایی و تساوی ابجکت ها را باهم مقایسه کنیم و بفهمیم 

 

اما در دنیای Relational :

دیتا ها در قالب سطر و ستون ذخیر میشوند

حق ندارند مقدار تکراری داشته باشند

حتما باید مقدار داشته باشد

رابطه ها یک به یک هستند و فقط F.key داریم

ارث بری ندارند

قابلیت درک یکسان بودن اطلاعات را نداریم و فقط با P.key میتوان متوجه شد اطلاعات مربوط به record یکسان است یا نه

و محدودیت زیادی دارد که باعث میشود با دنیای Objective نا متناجس شود

 

وقتی بخواهد دنیای Objective با دنیای Relational ارتباط بر قرار کند نیاز به یک واسط داریم که مسایل و پیچیدگی ها و محیط ها نا متناجس را برای ما قابل استفاده و هماهنگ کند که این نیاز با وجود ORM ها متناظر میگردد

 

در فایل hibernate.cfg.xml میتوان تنظیمات اولیه را تعریف کرد :

 

<?xml version = "1.0" encoding = "utf-8"?>
<!DOCTYPE hibernate-configuration SYSTEM 
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
   <session-factory>
   
      <property name = "hibernate.connection.driver_class">
         com.mysql.jdbc.Driver
      </property>
      
      <property name = "hibernate.connection.url">
         jdbc:mysql://localhost:3307/schema_name
      </property>
      
      <property name = "hibernate.connection.username">
         root
      </property>
      
      <property name = "hibernate.connection.password">
         pass1234
      </property>
   
      <property name = "hibernate.dialect">
         org.hibernate.dialect.MySQLDialect
      </property>
      
      <mapping resource = "Student.hbm.xml"/>
      
   </session-factory>
</hibernate-configuration>

 

که session-factory : در هایبرنیت هر connection ای که ایجاد و تراکنش ها انجام میشود را یک session مینامد و session-factory کارش تولید این session ها است 

 

dialect : زبان مشترک پایگاه داده های رابطه ای SQL است ولی هر پایگاه داده در زبان ارتباطیش تغییراتی را نیز دارد و هایبرنیت برای اینکه متوجه شود با چه نوع از اون تغییرات باید با پایگاه داده صحبت کند از این تعریف استفاده میکند و جدیدا نیازی به تعریف این هم نیست و از روی نام درایور پاس شده خودش اتوماتیک ست میشود 

 

mapping : در قدیم برای تعریف رابطه کلاس ها و جداول و کوئری های آن از یک فایل xml برای تعریف آنها استفاده میشد که اکنون این مشکل با وجود annotation ها برطرف شده

 

Connection - Pool : در هایبرنیت یک connection pool داخلی خودش دارد ولی اگر بخواهیم از یک connection pool دیگر استفاده کنیم میتوانیم با jndi آنرا به هایبرنیت معرفی کنیم 

 

 

ایجاد کلاس Entity : 

@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  

  setters ...
  getters ...

}

 

در کلاس‌های Entity در کجا میتوان Annotation ها را بکار برد ؟

هایبرنیت از روی Id@ میتواند تشخیص دهد که annotation ها روی field ها هستند یا روی getter method ها و با Access@ روی کلاس Entity هم میتوان صراحتاً مشخص کرد که annotation ها روی Field هستند یا روی Property ها و بعد هایبرنت به دنبال چک کردن Id@ می‌رود که روی Field قرار گرفته یا روی Property ها و اگر Access@ روی فیلد باشد و Id@ روی property قرار گرفته باشد خطا پرتاب میشود

 

برای field های از نوع []byte که در دیتابیس بصورت blob ذخیره میشوند باید از Lob@ استفاده کرد و از نظر اصول طراحی بهتر است fetch type این نوع فیلد ها را از نوع LAZY بگیریم چون حجم آن زیاد است ، fetch type را میتوان در Basic@ تعریف کرد ولی این نکته را باید در نظر داشت که حتی در صورتی که از LAZY روی blob ها درBasic@ استفاده کنیم هایبرنیت باز بصورت EAGER آنرا دریافت میکند

 

برای اعمال کانفیگ روی هایبرنیت :

 

    private static SessionFactory sessionFactory = null;
  
    static {

        try{

        Configuration configuration = new Configuration();
        configuration.configure("/hibernate.cfg.xml");
        configuration.addAnnotatedClass(Employee.class);
        ServiceRegistry srvcReg = new StandardServiceRegistryBuilder()
            .applySettings(configuration.getProperties()).build();
        sessionFactory = configuration.buildSessionFactory(srvcReg);

        }catch(Exception e){
            System.err.println("Exception while initializing hibernate util.. ");
            e.printStackTrace();
        }
    }
 
 
    public static Session getSession() throws HibernateException {
 
        Session retSession=null;
            try {
                retSession = sessionFactory.openSession();
            }catch(Throwable t){
            System.err.println("Exception while getting session.. ");
            t.printStackTrace();
            }
            if(retSession == null) {
                System.err.println("session is discovered null");
            }
 
            return retSession;
    }

 

برای کار با هایبرنیت نیاز به session داریم که session ها توسط session factory تولید میشوند ، حال برای ایجاد ابجکت session factory مطابق کد بالا کانفیگ ها را اعمال میکنیم که :

تنظیماتی که در فایل xml ایجاد کردیم مثل url/user:pass/dialect ... را که در شاخه resources وجود دارد را توسط متد configure ارسال میکنیم

با addAnotatedClass میتوان لیست کلاس های Entity را ارسال کنیم که به عنوان مدل آنرا در نظر بگیرد

 

روی ابجکت sessionFactory با openSession یک session به ما میدهد که حتما باید در انتها آنرا close کنیم یا با try-with-close استفاده کنیم 

 

 

گرفتن لیستی از ابجکت های Entity :

 

try ( Session session = sessionFactoy.openSession() ){

         session.createQuery("from EntityClass").list();

}

 

ذخیره کردن یک ابجکت در دیتابیس : 

 

public void setPersistEntityClass(EntityClass enClass){

   try ( Session session = sessionFactoy.openSession() ){
          session.beginTransaction();
          session.save(enClass);
          session.getTransaction().commit();
   }
}

 

گرفتن یک ابجکت از دیتابیس :

 

public EntityClass findEntityClassById (int Id){

   try ( Session session = sessionFactoy.openSession() ){
          EntityClass enClass = session.find(EntityClass.class , Id);
          return enClass;
   }
}

 

در کد بالا از find استفاده شده ، find آن ابجکت هایی که در session معرفی شده را میشناسد ولی اگر ابجکت در session معرفی نشده بود میتوان از متد load که سرعت کمتری هم دارد استفاده کرد در روش load هایبرنیت یک پروکسی برای آن کوئری میسازد تا عملیات mapping را انجام دهد

 

کانفیگ های مربوط به DDL:

 

<hibernate-configuration>
<session-factory>

<property name="hbm2ddl.auto">value</property>

</session-factory>
</hibernate-configuration>

 

جای value میتوان مقادیر زیر را بکار برد :

 

none : غیر فعال میکند

validate : تنها چک میکند که جداول طبق مدل ها معتبر و قابل استفاده باشند و تغییری در دیتابیس ایجاد نمیکند و اگر تفاوتی در جداول و Entity Model ها وجود داشت هایبرنیت اجرا نمیشود

create : اولین بار که بالا میاد جداول را drop میکند و از اول create میکند

create-drop : اول کلیه جداول را create میکند و در انتهای اتمام اجرای برنامه هنگامی که Session Factory را close بکنیم کلیه جداول را drop میکند و برای تست کاربرد دارد 

update : اگر تغییراتی در مدل ها اعمال شده بود با جداول چک میکند و اگر چیزی کم و زیاد بود آنرا تغییر میدهد 

 

**Java Persistence API  نکته : jcp یک استانداردی برای پیاده سازی ORM ها ارائه داد تا همه ORM ها را استاندارد سازی و رفتاری یکسان داشته باشند بنام JPA  و در هایبرنیت برای تعریف کلاس های Entity میتوان از annotaion های jpa نیز استفاده کرد و بهتر است ما نیز استفاده کنیم تا بعدا ORM را عوض کردیم وابستگی به یک orm خاص نداشته باشیم ، annotation ها و کلاس های JPA در javax.persistence قرار دارند

 

دیدن Query ها بصورت format شده در خروجی کنسول : 

کافی است دو کانفیگ زیر را به xml اضافه کنیم 

<hibernate-configuration>
<session-factory>

<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>

</session-factory>
</hibernate-configuration>

 

 

 

نظرات  (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی