Feed Rss



Ноя 09 2009

Hibernate vs Doctrine

рубрика: Java,PHP Автор:

На выходных дошли руки, наконец-то, опробовать производительность другого аспекта миграции с PHP на Java. Мне нужен был ORM, да не просто ОРМ, а ОРМИЩЕ! О hibernate я слышал давно и все отзывы хорошие, да и к тому же Spring прекрасно с ним дружит. На этом и остановился — ман по hibernate + попытка ввинтить его в примитивное SpringMVC приложение вылилось следующими синтетическими тестами:

В качестве испытуемого было выбрана хорошо мне знакомая MySQL. В каждом ORM создавался примитивный объект User:

package domain;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name="users")
public class User {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="id")
	private Long id;
 
	private String email;
 
	public Long getId() {
		return this.id;
	}
 
	public User() {}
 
	public User( String email ) {
		this.email = email;
	}
 
	public String getEmail() {
		return this.email;
	}
 
	public void setEmail(String email) {
		this.email = email;
	}
}

и в PHPDoctrine:

< ?php
class User extends Record {
 
    public function setTableDefinition() {
        $this->setTableName( 'users' );
        $this->hasIdColumn();
 
        $this->hasColumn( "email", "string", array(
            "notnull" => TRUE
        ) );
    }
 
    public function setEmail( $email ) {
        $this->email = $email;
        return $this;
    }
 
    public function getEmail() {
        return $this->email;
    }
 
 
    public function getId() {
        return $this->id; // свойство вымышлено - в Doctrine для этого нужны танцы и бубен
    }
}

Далее шло тестирование вставки и чтения новых объектов в БД.
Результаты:

1000 вставок
    Hibernate ~11сек
    Doctrine ~1.4сек

Чтение 2000 записей из БД и создание их сущностей
    Hibernate ~0.4сек
    Doctrine ~1.16сек

Не понятно откуда такая большя разница при вставке, но что-то мне подсказывает, что Hibernate (или спринговский HibernateTemplate) по-умолчанию оборачивает методы записи в транзакции. Пока что не разобрался как их отключить или настроить, посему просто привожу часть конфигурации сервлета:

[...skipped...]
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
	    <property name="dataSource" ref="myDataSource"/>
	    <property name="hibernateProperties">
	     <props>
	       <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
	       <prop key="hibernate.hbm2ddl.auto">create</prop>
	     </props>
	   </property>
	    <property name="annotatedClasses">
	       <list>
	           <value>domain.User</value>
	       </list>
	    </property>
	</bean>
 
	<bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref local="sessionFactory" />
        </property>
    </bean> 
 
    <bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor">
        <property name="sessionFactory"><ref local="sessionFactory"/></property>
    </bean> 
[...skipped...]

Кстати хочу обратить ваше внимание на то, что в Java называется POJO(Plain Old Java Objects). Этим термином называют классы, которые самодостаточны, а значит переносимы; то-есть они не наследуют никаких базовых классов, протиктованых фреймворками и не реализуют никаких интерфейсов. Таким образом класс User выглядит более самостоятельным в Java, чем его брат в PHP, которому пришлось унаследоваться от Record, использовать метод setTabkeDefinition, для описания связей, и навсегда забыть о родном конструкторе, так как он нужен Doctrine для внутренних нужд.

Понравился пост? Подпишись на RSS!

Метки: , , , , ,

10 ответов на “Hibernate vs Doctrine”

  1. chichikoff says:

    Спасибо за пост. Сам давно уже задумался над тем чтобы выучить java. Да всё времени не хватает. А doctrine полностью доволен.

  2. env0der says:

    В Doctrine 2.0 будут POHO — тоже ничего не надо будет наследовать, а маппинги будут задаваться с помощью аннотаций. Я считаю, что это будет большой прорыв среди ОРМ-движков для PHP.

    А с чем связан переход на джаву?

    • Алексей Токарь says:

      Тут прорыв больше в РНР5.3 и старше, когда разрешили в рефлексиях получать доступ к закрытым свойствам объектов.
      Единственно чего я боюсь, что используя повсеместно доступ через рефлексию, не пострадает ли производительность еще больше?

      А на java я решил переходить по многим причинам, но основная из них — java гараздо строже PHP.

      • S says:

        Как на счёт Python?

      • Павел Корягин says:

        Алексей, а можете привести пример, показывающий преимущество строгости?

        Благодарю.

        • Алексей Токарь says:

          привожу.
          над проектом работает N человек.
          в проекте есть класс с методом A(). метод принимает три аргумента:
          a, b, c

          в случае PHP необходимо либо написать PHPDoc и воспользоваться IDE умеющей читать этот блок, либо пойти в метод и изучить что он делает и как. В типизированых языках не нужно себя насиловать описанием типов переменных и любая IDE сможет дать адекватную подсказку. + исключены ситуации случайной передачи неверного типа в метод.

          пример номер два — перегрузка. То как она реализована в РНР сейчас — убожество.

          • Andrey Korolyov says:

            Начнём с того что в PHP вообще перегрузки как таковой нету.
            А чем тебя смущает Function(MyObject $var, array $varArr, MyObjectSecond $var2) ?

  3. Doctrine vs Hibernate 2 | Писать не обещаю, но буду... says:

    [...] несколько месяцев назад я уже проводил тест производительности двух сабжевых продуктов. Тогда я, правда, оговорился в [...]