Введение в объектно-ориентированные базы данных

    ООСУБДОбъектно-ориентированные базы данных – базы данных, в которых информация представлена в виде объектов, как в объектно-ориентированных языках программирования.

    Применять или не применять объектно-ориентированные системы управления базами данных (ООСУБД) в реальных проектах сегодня? В каких случаях их применять, а в каких нет?

    Вот преимущества использования ООСУБД:
    • Отсутствует проблема несоответствия модели данных в приложении и БД (impedance mismatch). Все данные сохраняются в БД в том же виде, что и в модели приложения.
    • Не требуется отдельно поддерживать модель данных на стороне СУБД.
    • Все объекты на уровне источника данных строго типизированы. Больше никаких строковых имен колонок! Рефакторинг объектно-ориентированной базы данных и работающего с ней кода теперь автоматизированный, а не однообразный и скучный процесс.
    Интересно? Тогда стоит попробовать!

    В статье описано все, что требуется для начала работы с ООСУБД db4o.

    Установка db4o


    На сегодняшний день db4o – одна из самых популярных объектно-ориентированных систем управления базами данных.

    Для начала скачиваем дистрибутив последней версии с сайта db4o (есть версии для Java, .NET 2.0, 3.5). На момент написания статьи последняя версия – 7.9. В дистрибутив также входит Object Manager Enterprise (OME) – полезный плагин для IDE (Eclipse, Visual Studio), который позволяет работать с базой данных автономно. В последнюю продуктивную поставку (на данный момент — 7.4) OME не входит, поэтому для ознакомления c ООСУБД рекомендуется версия 7.9.

    Далее в статье для примеров будет использоваться язык C#. Для Java примеры аналогичны, за исключением раздела про LINQ, где необходимым условием является использование .NET 3.5.

    После установки db4o в соответствующем месте можно найти отличный tutorial, входящий в комплект. Именно к нему я рекомендую обратиться после прочтения данной статьи, если сама тема покажется вам интересной.

    Отмечаю, что все ПО для работы с db4o и сама СУБД бесплатны для некоммерческого использования.

    Cоединение с БД


    Для проведения экспериментов над db4o создаем в нашей IDE проект любого типа, например, консольное приложение и добавляем ссылки на сборки (пакеты) db4o: Db4objects.Db4o.dll и Db4objects.Db4o.Linq.dll (если требуется).

    Чтобы выполнять какие-либо действия над объектной базой в приложении, первым делом необходимо получить объект типа IObjectContainer. Это фасад к базе данных: через него выполняются запросы к БД на выборку, сохранение, добавление и удаление данных.

    Способ получения объекта зависит от типа соединения с базой данных.

    Самый простой способ – база данных размещается в локальном файле, к которому приложение получает доступ напрямую. Делается это так:
    // получаем доступ к файлу БД
    IObjectContainer db = Db4oFactory.OpenFile(filename);
    try
    {
        // работаем с ООБД
    }
    finally
    {
        // закрываем файл, освобождаем ресурсы
        db.Close();
    }


    * This source code was highlighted with Source Code Highlighter.

    Файл базы данных в этом случае открывается в эксклюзивном режиме и, следовательно, возникают трудности при реализации многопользовательских приложений. Однако такое решение отлично подходит для однопользовательских stand-alone приложений, которые имеют сложную модель данных и которым необходимо сохранять эти данные между запусками приложения. Пример, САПР-приложения.

    Следующий способ. Для поддержки многопользовательского режима, то есть возможности существования нескольких IObjectContainer для одной базы данных одновременно, следует использовать клиент-серверную архитектуру. В случае, когда клиент и сервер работают в рамках одного приложения, это делается так:
    // создаем сервер
    IObjectServer server = Db4oFactory.OpenServer(filename, 0);
    try
    {
        // подключаем клиентов
        IObjectContainer client = server.OpenClient();
        IObjectContainer client2 = server.OpenClient();

        // работаем с ООБД через экземпляры IObjectContainer

        client.Close();
        client2.Close();
    }
    finally
    {
        // закрываем файл, освобождаем ресурсы сервера
        server.Close();
    }


    * This source code was highlighted with Source Code Highlighter.

    В данном случае при создании сервера все равно приходится указывать файл базы данных. Это необходимо делать для всех типов подключения к БД — привязка к файлу остается всегда (один файл — одна БД). Кстати, такой файл создается автоматически по первому требованию, если не был создан до этого.

    Второй параметр функции OpenServer – номер порта, равный 0, означает, что сервер будет доступен только локальным клиентам, создаваемым с помощью server.OpenClient().

    Приведенный пример искусственный. В реальном приложении клиенты, скорее всего, будут открываться в отдельных потоках.

    И последний вариант – расширение предыдущего для случая удаленных клиентов.
    // создаем сервер
    IObjectServer server = Db4oFactory.OpenServer(filename, serverPort);
    server.GrantAccess(serverUser, serverPassword);

    try
    {
        IObjectContainer client = Db4oFactory.OpenClient("localhost", serverPort,
                                                         serverUser, serverPassword);
        // работаем с ООБД
        client.Close();
    }
    finally
    {
        server.Close();
    }


    * This source code was highlighted with Source Code Highlighter.

    Этот вариант отличается от предыдущего следующим.
    • Указывается реальное значение порта, который будет прослушивать сервер (используется TCP/IP) при вызове OpenServer.
    • Указываются авторизационные данные для доступа к БД.
    • Клиент создается с использованием Db4oFactory.OpenClient и, таким образом, это может происходить не только в другом потоке, но и совершенно в другом приложении, запущенном на удаленной машине.
    Итак, мы рассмотрели все три способа подключения к базе данных и научились получать объект типа IObjectContainer. Посмотрим теперь, как работать с данными, используя этот объект.

    Работа с данными


    Пусть где-то в нашем приложении объявлен класс User с полями Login, Password и Age, а db – это объект типа IObjectContainer (тот, что мы получили в прошлом разделе).

    Сохранение объекта (INSERT)


    User user1 = new User("Vasya", "123456", 25);
    db.Store(user1);


    * This source code was highlighted with Source Code Highlighter.

    Это всё! Не требуется заранее или вручную задавать, какие объекты мы можем сохранять в БД, структуру этих объектов или что-либо ещё. При сохранении первого объекта ООСУБД сделает всю работу за нас.

    Запросы к данным (SELECT)


    Существует несколько способов выполнить запрос к данным, сохраненным в базе данных.

    Применение естественных запросов (Native Queries, NQ) – гибкий, мощный и удобный метод выполнения запросов над данными в ООБД.
    IList<User> result = db.Query<User>(usr => usr.Age >= 18
                                            && usr.Login.StartsWith("V"));


    * This source code was highlighted with Source Code Highlighter.

    Здесь делается запрос к объектам класса User, причем всё, что только можно, в данном примере строго типизировано. Объекты фильтруются таким образом, чтобы удовлетворять условию: возраст пользователя больше или равен 18 и имя пользователя начинается с заглавной буквы «V». Вместо лямбда-выражения функции Query можно передавать делегаты или объекты типа Predicate<T>. Predicate<T> — интерфейс, содержащий единственную функцию Match, принимающую параметр типа T и возвращающую bool. Query вернет те объекты, для которых Match возвращает true.

    Концепция ООБД отлично ложиться на идею использования интегрированных в язык запросов (LINQ).
    Перепишем предыдущий запрос с использованием LINQ.
    IEnumerable<User> result = from User usr in db
                              where usr.Age >= 18 && usr.Login.StartsWith("V")
                              select usr;


    * This source code was highlighted with Source Code Highlighter.

    Запрос опять же строго типизирован и легко поддается рефакторингу.

    Существуют и другие методы выполнения запросов, кроме NQ и LINQ.
    • Запросы по образцу (query by example). Самый простой, но недостаточно мощный способ. Выборка данных осуществляется на основе сопоставления с заранее подготовленным экземпляром объекта — образцом. Результат-выборка не является строго типизированной. Сложно представить ситуации, когда этот метод может оказаться полезным.
    • SODA. Низкоуровневый язык запросов, с которым работает db4o. Запросы, использующие синтаксис SODA, не безопасны с точки зрения типов, не строго типизированы, занимают много места, но зато максимально гибки и позволяют отточить производительность приложения там, где это требуется.

    Обновление объектов (UPDATE)


    Перед тем как обновить объект, извлечем его из БД, затем изменим его и сохраним обратно.
    User usr = db.Query<User>(usr => usr.Login == "Vasya")[0];
    usr.SetPassword("111111");
    db.Store(usr);


    * This source code was highlighted with Source Code Highlighter.

    Удаление объектов (DELETE)


    Удаление объектов происходит аналогично:
    User usr = db.Query<User>(usr => usr.Login == "Vasya")[0];
    db.Delete(usr);


    * This source code was highlighted with Source Code Highlighter.

    Составные объекты


    До этого момента мы рассматривали, как работать с достаточно простыми объектами User, которые содержали только поля элементарных типов (string и int). Однако объекты могут быть составными и ссылаться на другие объекты. Например, в классе User может быть объявлено поле friends (друзья пользователя):
    public class User
    {
        // ...
        IList<User> friends = new List<User>();
    }


    * This source code was highlighted with Source Code Highlighter.

    Все операции с таким классом производятся также, как и раньше – составное поле корректно сохраняется в БД, однако есть некоторые особенности.

    Допустим, мы пытаемся загрузить из БД объект одного конкретного пользователя (User), как это делалось в прошлом разделе. Если загружен сам пользователь, то должны загрузиться и его друзья, дальше – друзья его друзей, и так далее. Это может закончиться тем, что придется загрузить в память все объекты User или даже, если у User есть ссылки на объекты других типов, всю базу данных целиком. Естественно, такой эффект нежелателен. Поэтому, по умолчанию загружаются только сами объекты выборки и объекты, на которые они ссылаются, до 5-го уровня вложенности включительно. Для некоторых ситуаций это много, для других – мало. Существует способ настроить этот параметр, называемый глубиной активации (activation depth).
    // глубина активации глобально для всех классов
    db.Ext().Configure().ActivationDepth(2);

    // глубина активации для класса User
    db.Ext().Configure().ObjectClass(typeof(User)).MinimumActivationDepth(3);
    db.Ext().Configure().ObjectClass(typeof(User)).MaximumActivationDepth(4);

    // каскадная активация для объектов User (нет ограничения на глубину)
    db.Ext().Configure().ObjectClass(typeof(User)).CascadeOnActivate(true);


    * This source code was highlighted with Source Code Highlighter.

    Здесь приведены примеры, устанавливающие глубину активации как для всех сразу, так и для отдельного класса. Функция Ext() возвращает расширенный объект IExtObjectContainer для доступа к продвинутым функциям вроде настроек конфигурации базы данных. Это сделано для удобства, чтобы не засорять основной интерфейс IObjectContainer.

    В случае, когда запрос уже отработал, но каких-либо данных не хватает, то есть не все нужные данные были активированы (загружены в память), можно использовать метод Activate, применительно к отдельному хранимому объекту:
    // первый параметр – активируемый объект, второй – глубина активации
    db.Activate(usr, 5);


    * This source code was highlighted with Source Code Highlighter.

    Во многом похожая проблема возникает при сохранении составных объектов. По умолчанию сохраняются только поля самого объекта, но не объектов, на которые он ссылается. То есть, глубина обновления (update depth) по умолчанию равна 1. Изменить её можно следующим образом:
    // глубина обновления глобально для всех классов
    db.Ext().Configure().UpdateDepth(2);

    // глубина обновления для класса User
    db.Ext().Configure().ObjectClass(typeof(User)).UpdateDepth(3);

    // каскадное обновление для объектов User (нет ограничений на вложенность)
    db.Ext().Configure().ObjectClass(typeof(User)).CascadeOnUpdate(true);


    * This source code was highlighted with Source Code Highlighter.

    В случае удаления объекта, по умолчанию также не происходит каскадного удаления: объекты, на которые ссылался удаленный объект, остаются. Настраивать поведение СУБД в случае удаления объектов можно следующим образом:
    // каскадное удаление (нет ограничений на вложенность)
    db.Ext().Configure().ObjectClass(typeof(User)).CascadeOnDelete(true);


    * This source code was highlighted with Source Code Highlighter.

    Понятия «глубины удаления» не предусмотрено.

    Транзакции


    Каждый раз, когда открывается контейнер (IObjectContainer), неявным образом создается контекст транзакции. При выполнении операции Close автоматически происходит commit текущей транзакции.

    Для более гибкого управления транзакциями в интерфейсе IObjectContainer присутствуют два метода:
    • Commit(). Явное завершение транзакции (commit) с записью всех изменений в БД.
    • Rollback(). Откат транзакции – изменения произошедшие с момента открытия транзакции (контейнера) не будут зафиксированы в БД.
    Уровень изоляции транзакций, принятый в db4o — read committed.

    Заключение


    Цель данной статьи — показать, что имеется очень мощная альтернатива существующим подходам к разработке с использованием реляционных СУБД. Сам по себе подход, использующий объектные базы данных, очень современен – это СУБД, которая не отстает от основных тенденций, наблюдаемых в развитии языков программирования, таких как Java и C#.

    В статье достаточно материала, чтобы начать работать с ООСУБД, создавая реальные приложения. Однако многие вопросы здесь затронуты не были, например, вопросы, связанные с производительностью и разработкой веб-приложений.

    В любом случае, если и не начать применять объектные СУБД на практике уже сегодня, то стоит хотя бы задуматься, не лучшее ли это решение для вашего проекта?

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 59

      –6
      цель не достигнута имхо
        +3
        Цель будет достигнута, если она будет достигнута в контексте хотя бы одного читателя ;)
        +6
        За статью спасибо, очень интересно взглянуть на проблему ORM с точки зрения ее отсутствия :)

        Однако ИМХО, объектные БД еще недостаточно зрелые, и в серьезный продакшн их пускать рано. Для примера можно взять хотя бы присутствие такого параметра, как «глубина активации ссылок» — хотя, по идее, этим должна заниматься БД, а не программист, предсказывая, как далеко по ссылкам ему придется ходить.
          0
          Как раз для решения этой проблемы в последних версиях db4o есть Transparent Activation. Данная тема в введение не влезла :)
            0
            Каюсь, давно не заглядывал в db4o :)

            В таком случае буду ждать продолжения

            0
            Очень интересно, и статья понравилась, db4o надо обязательно попробовать…

            Мне одному напрашивается решение проблемы «глубины активации» и т.д. с помощью атрибутов полей классов? :)
              0
              Думаю, что это неподходящее решение. Дело в том, что один и тот же класс может быть использован в различным ситуациях, когда объем графа(назовем так метрику, пропорциональную среднему диаметру графа, т.е. суммарной длине ссылок среднего «маршрута») может меняться достаточно сильно.

              Не перекомпилировать же приложение.
              +4
              Вообще то объектные базы давно используются в самых разных местах. db4o не самый удачный пример и далеко не самая зрелая технология.
              Из коммерческих мне приходилось работать с Matisse, давно доступна на рынке, на ней реализован был Craigslist, атомные станции управляются системами с Matisse во Франции, Los Alamos National Laboratory (сами знаете чем они там занимаются), ЦРУ и прочие ФБР.
              Объектные базы вообще и Matisse в частности используются для работы с очень сложными моделями, в которых из-за большого количества типов объектов и связей использовать реляционные базы невыгодно.
              Последний раз я работал с Matisse 6 лет назад и тогда это было очень круто — рисуешь все в Rational Rose в UML и собственно это и была схема базы. Из розы одним кликом в Matisse.
              Есть еще разумеется Caché, тоже уже очень давно на рынке.
                0
                Судя по документации (сам с ними не работал), обе упомянутые СУБД действительно очень мощные. Помимо поддержки объектного интерфейса к ним можно делать запросы на расширенном SQL. Последнего в db4o нет. Однако, что касается работы с БД на уровне объектов (без ORM) у db4o есть большие преимущества. Matisse и Caché требует для работы генерировать прокси-классы для хранимых классов и работать с БД через них. В db4o этого делать не надо, интерфейс более естественный — мы работаем с собственными классами.

                Для более подробной информации вот ссылки на доки (.NET): Matisse, Caché.
              +3
              Не нашел ответов в статье на следующие очевидные вопросы.

              Возможно ли сохранить граф объектов (с циклами)?
              Как разрешается identity проблема, то есть если два объекта ссылаются на третий, то при сохранении первого, а затем второго будет ли это связь учтена в DB?
              Как на счет скорости, какие ограничения на размер DB?
                0
                1) Можно.

                2) Да, связь учтена будет. Identity разрешается в точности, как в самом ЯП (по ссылке).

                3) Информации по вопросам производительности и масштабируемости очень мало. Собственного исследования на данной момент также не проводил. Все, что могу сейчас дать, это ссылка на benchmark на сайте db4o. Сам объективность приведенных данных не проверял и не знаком с методикой тестирования.
                0
                Есть что-нибудь подобное для ruby?
                  0
                    0
                    Некоторое подобие — Maglev. Они объектную БД для Руби завернули в прикольную обертку — там по сути нет явного процесса сохранения, все работает прозрачно для программиста. Вообщем, смотрите скринкаст :)
                      0
                      Maglev — это адаптированный GemStone/S, доступный для Smalltalk'a с 1992 года. Он упоминается еще в книге Фаулера, посвященной рефакторингу. Кстати на идею создания Maglev авторов натолкнула мысль отсутствия вменяемой VM для ruby и то, что Smalltalk почти полностью покрывает сам Ruby.
                        0
                        Да, вы правы. И?
                          +1
                          Кошерные OODBMS существуют достаточно давно. Просто необходимо заинтересоваться вопросом и начать копать, однако автор видит вершину айсберга (вытолкнутую из глубин силами маркетинга). Честно сказать вообще не понимаю таких Persistence решений, для которых требуется не меньше усилий, чем для RDBMS.
                            0
                            А вот с этим уже согласен на 100%.
                    0
                    Что Вы думаете о CouchDB?
                    P.S. Я знаю, что это не объектно-, а документ-ориентированная БД, но правильно ли я понимаю, что документ-ориентированная БД является расширением ООСУБД?
                      0
                      Не знаю, что скажет автор, но боюсь, что понимаете неправильно. CouchDB — это ближе к column-oriented и key-value-pair хранилищам. При этом, однако, CouchDB не является ни тем ни другим.
                        0
                        Первый раз слышу о CouchDB. Обязательно посмотрю, что это! Спасибо за наводку! :)
                          0
                          Могу предложить тогда «до кучи» еще SimpleDb и FeatherDb посмотреть и сравнить :)
                            +1
                            и ещё на Persevere можете глянуть.
                            Сразу можно начинать читать с Comparison with CouchDB and Others, там как раз небольшой обзорчик похожих технологий.
                          +2
                          Спасибо за статью! Несколько лет работаю программистом и работа с базами данных, как и у всех наверное, ежедневное занятие. Но обьектные никогда в глаза не видел. Супер!

                          Вопрос только такой: как делаются миграции в таких базах? когда нужно менять структуру? т.е. я меняю описание класса когда уже данные есть?
                            +1
                            В случае удаления/добавления полей и классов проблем нет. Когда надо переименовать поле или класс, следует использовать API db4o приблизительно так:

                            Db4oFactory.Configure().ObjectClass(typeof(User)).Rename(«NewClassName»);
                            Db4oFactory.Configure().ObjectClass(typeof(User)).ObjectField(«Login»).Rename(«NewFieldName»);

                            Как ни странно, в Object Manager Enterprise визуальных средств для этого нет.
                              0
                            • UFO just landed and posted this here
                                0
                                Ага… Если учесть что это C#, то Ваш комментарий очень полезен.
                                В java вместо IEnumerable Iterable.
                                И Linq там конечно есть, но немного другой.
                                  0
                                  жава живее всех живых.

                                  скороговорка какая-то, но суть ясна :)
                                    0
                                    забавно. один из популярнейших языков — и мертв? :)
                                    +2
                                    где самое главное — тесты производительности и масштабируемость?
                                      0
                                      Интересно, но технология еще не обкатана. Много деталей остаются неясными.
                                      1. Есть ли возможность индексирования поиска по полям?
                                      2. Кеш объектов и выборок.
                                      3. Интеграция с фреймворками высокого уровня, напр. EMF
                                      4. Система локов.
                                        0
                                        1. Да, конечно есть.

                                        2. Кеш существует и работает прозрачно. Благодаря ему во многих ситуациях ООСУБД оказывается быстрее РСУБД.

                                        3. С EMF не знаком. Затрудняюсь ответить.

                                        4. Все зависит от конкретного сценария.
                                        0
                                        Вот чуток тестов что я нашел(жаль не сравнительные)
                                        developer.db4o.com/forums/post/29460.aspx
                                          +2
                                          Мы для своей задачи тестили db4o и не возрадовались.

                                          Я даже очень-очень-приочень хотел, чтобы мы возрадовались, но не судьба…

                                          Возможно это пока.

                                          =Конфиг=
                                          Клиент-сервер. На сервере поднята служба, как в хелпе db4o. Работа с SQL`ем и OODB идут на одном сервере с одного и того же клиента.

                                          =Результаты=

                                          Sql-Server:
                                          — 0.18 секунды 5000 записей, с наполнением объекта-списка

                                          db4o:
                                          — 0.3 секунды 5000 объектов (все имеющиеся)
                                          — 5.5 секунд объект список состоящий из 5000 объектов
                                          — 10 секунд рандомная загрузка 50 объектов
                                            0
                                            как-то очень грустно, но мне кажется для чистоты эксперимента, надо было поднимать MSSQL и db4o отдельно, ибо кажется мне что sql server под себя ресурсов больше подминает,… хотя он все равно будет быстрее, но может хоть не настолько
                                              0
                                              Думаю, мало поможет.

                                              Мне кажется, что здесь либо:

                                              а) Сама db4o сыровата для продакшена

                                              б) Надо мегамозг и ряд реальных проектов, чтобы написать нормальный сервер для неё на её основе
                                            0
                                            попробуйте Zope, я там такое делал еще 5 лет назад. Этой python фреймворк; используя внутреннюю БД, можно делать необходимые объекты.
                                              0
                                              Интереснее было бы узнать, можно ли ZODB использовать отдельно от этого чудища. А то сам Zope как-то не очень нравится. А объектную базу погонять хочется.
                                                0
                                                Можно, только когда я занимался им (давно это было) ZODB подтормаживал не по детски.
                                                  0
                                                  можно; сейчас zope — это уже не цельный фреймворк, а скорее комплект независимых деталей
                                              • UFO just landed and posted this here
                                                  0
                                                  Мгм, а зачем?
                                                  • UFO just landed and posted this here
                                                      0
                                                      Как вариант пользуйтесь apc, memcache.

                                                      ООДБ — да, красиво, но…
                                                      Пока такие ООДБ проигрывают для PHP по соотношению Цена разработки/скорость работы.
                                                      Плюс, я, просто, не встречал на PHP серьезных разработок базирующихся на доменной архитектуре, где интересно хранить именно объекты. Поэтому возник вопрос, а зачем это надо? :)
                                                      • UFO just landed and posted this here
                                                      0
                                                      А в чем в данном случае отличие PHP от C#, что для шарпов это надо, а для пыха — нет?
                                                        0
                                                        Уровень абстракции и развитость платформы у Java, C# выше.

                                                        Это не плюс и не минус, просто это так есть.

                                                        К примеру, на PHP каждый второй, средней руки специалист пишет свой DB access layer или framework. На C#, Java — это редкое явление.
                                                          0
                                                          А что мешает взять хорошую реализацию.хорошего специалиста и подключать ее в качестве библиотеки? Жава настолько высоко развита, что у нее есть import, а у пыха — нет require_once?

                                                          А вообще, неправда ваша в данном случае. Тот же пропел под пых есть.
                                                            0
                                                            Сколько не бери специалистов, пока не будет инструментария и библиотек соответствующего уровня — ничего не изменится.

                                                            Propel и NHibernate сильно разные вещи.

                                                            Вы просто попробуйте написать средний проект (от 100к строк) на C#, Java, PHP и поймете разницу.

                                                            PHP более низкоуровневый — именно этим он и удобен для большинства веб-сайтов
                                                            (больший контроль над всем, меньший оверхед и т.д.)
                                                              0
                                                              «Сколько не бери специалистов, пока не будет инструментария и библиотек соответствующего уровня — ничего не изменится.»

                                                              Ну их писать-то кто-то должен? Вот написал я сайтик — почему бы не выложить его исходник на Google Code? Если он написан грамотно, то все использующиеся внутри классы/процедуры можно легко превратить в библиотеку, а сам сайтик — во фреймворк для создания сайтов такого типа. Немного документации — и вот уже готовая технология.

                                                              Где-то через месяц нужно будет писать сайт на PHP, у меня уже есть с прошлого года склонированный вплоть до названий классов каркас эмуляции сервлетов, а на нем — php-клон фреймворка Apache Turbine (версии 1). Конечно, всё это нужно доводить, и если таки придется писать на пыхе — доведу.

                                                              «Вы просто попробуйте написать средний проект (от 100к строк) на C#, Java, PHP и поймете разницу.»

                                                              Да я на каждой из этих технологий написал немало.
                                                              И на Жаве можно писать спокойненько вывод странички «вручную». Забабахал сервлет, и пиши в out что хочешь. Куда уж более низкоуровнево?

                                                              «больший контроль над всем»
                                                              и над чем же, интересно, контроль, над этим всем? Что там есть-то кроме HTML-кода, с чем может нативно работать PHP? Что такое может PHP-скрипт, чего не может сервлет + JDK?

                                                              «меньший оверхед»
                                                              ваще не к разработчику. проблемы провайдера.
                                                              а если покупать собсвтенный сервер для сайта — ну и на чем там экономить? На планке оперативки за две тысячи рублей?!
                                                                0
                                                                Извините, но для меня это разговор с глухим, тем более, если вы говорите — писали много на всех 3х языках. Разницу должны понимать.

                                                                На Java никому в голову не придет писать raw-html в out. Просто потому что это неудобно и вне рамок технологии. Есть стандартные компоненты, фреймворки их и используют.
                                                                Вы видели html сгенерированный на ASP.NET? Это же жесть.
                                                                Тем не менее писать его достаточно просто, пока работаешь с компонентами. А вот спустится до уровня чистого html — проще застрелиться и писать действительно весь вывод в out. Но для .NETчика это мартышкин труд.

                                                                На PHP просто нет соответствующих библиотек такого качества, зато я четко контролирую что у меня будет в html (впрочем и выхода особого нет :) ). ez, ZF, CI, Doctrine достаточно сыроваты. Они писались в определенных условиях, под определенные нужды.

                                                                Поэтому даже средние специалисты часто пишут свое. Хорошие специалисты уже написали и пользуются своим.

                                                                P.S. если вы не в курсе, я пишу на PHP в основном.

                                                                Лет через 5ть мы, возможно, увидим прогресс. Вопрос какой ценой. За легкость разработки и лишние абстракции всегда надо платить и производительностью и деньгами.
                                                                  0
                                                                  То есть типа под Java нельзя писать raw-html потому что есть фреймворки, а на PHP можно потому что нет другого выбора. Интересная логика.

                                                                  «На PHP просто нет соответствующих библиотек такого качества»
                                                                  Ага, библиотеки сами рождаются. Как кошки. А нам остается только ждать пока они появятся.

                                                                  «Хорошие специалисты уже написали и пользуются своим.»
                                                                  И конечно же выложить опенсорс их жаба задушит.

                                                                  Вывод: разговор слепого с глухим :) Глухой не желает слышать призыва «нет библиотек!!!», потому что знает, что их нужно писать самому и выкладывать в опенсорс, и никто кроме тебя этого не сделает. А слепой даже не рассматривает такой возможности, потому что привык довольствоваться текущим положением вещей.
                                                                    0
                                                                    Фффф. Жуть.

                                                                    Перечитайте мои слова и поймите разницу между нельзя и неудобно.

                                                                    И, да, я не вижу смысла бесплатно раздавать что-либо кроме знаний :) А библиотеки — это уже продукт труда и они должны покупаться.
                                                                    Так что пишите опенсорс библиотеки — на здоровье. Сейчас ОС плодит горы шлака, в котором сложно найти действительно нужные и качественные вещи.
                                                    –1
                                                    А еще есть GoogleAppEngine =)
                                                      0
                                                      orm sqlalchemy в питоне работает раза в 4 медленнее, чем native-запросы.
                                                      красиво, но медленно.
                                                        0
                                                        Интересная ссылка на отзыв об использовании db4o на практике: тут.
                                                          0
                                                          GLASS Из всего тулкита к данной теме относится только GemStone/S. Советую взглянуть, если не лениво. Яркий пример Persistence без какого либо кода.
                                                            0
                                                            client.Close(); тоже нужно вызывать в finally

                                                            Only users with full accounts can post comments. Log in, please.