Morphia — легкий ORM для MongoDB, управляемый аннотациями

    Читая ежедневную порцию постов из своей подборки Google Reader наткнулся на пост про ORM для MongoDB с манящим названием «Morphia». Ниже вы найдете компоновку материалов из его документации, претендующую на звание «очень краткий обзор».

    1. Morphia очень просто использовать. Это легкий и быстрый фреймворк
    2. Поддерживает как аннотированные POJO объекты, так и DAO подход
    3. Вся конфигурация задается аннотациями, XML файлы не используются
    4. Поддерживается интерфейс расширений (в настоящий момент во фреймворк встроены валидация (jsr330) и поддержка SLF4J для протоколирования
    5. Отлично работает с Google Guice, Spring и другими DI фреймворками
    6. Содержит большое количество точек расширения
    7. Поддерживает GWT



    Сущность в Morphia описывается так:

    @Entity("employees")
    class Employee {
      @Id ObjectId id; // генерируется автоматически, если не задан вручную
      String firstName, lastName; // Типы, передаваемые по значению сохраняются автоматически
      Long salary = null; // Хранятся только не-null Значения
    
      Address address; // По умолчанию поля ссылочных типов считаются @Embedded (встраиваются внутрь объекта целиком, без создания новых сущностей)
    
      Key<Employee> manager; //Ссылки могут сохраняться как без автоматической загрузки...
      @Reference List<Employee> underlings = new ArrayList<Employee>(); //... так и с ней
    
      @Serialized EncryptedReviews; // Хранится в одном бинарном поле данных
     
      @Property("started") Date startDate; //Поля можно переименовывать...
      @Property("left") Date endDate;
    
      @Indexed boolean active = false; //... и индексировать
      @NotSaved String readButNotStored; //Поля можно загружать, но не сохранять...
      @Transient int notStored; //... а также вообще игнорировать
      transient boolean stored = true; //Поля с пометкой transient игнорируются автоматически
    
      //Поддерживаются события, вызываемые в различных местах жизненного цикла объекта
      @PostLoad void postLoad(DBObject dbObj) { ... }
    }
    


    Работать с базой можно так:

    Morphia morphia = new Morphia();
    db = new Mongo();
    Datastore ds = morphia.createDatastore(db, appname, user, pass.toCharArray());
    
    morphia.map(Employee.class);
    ds.save(new Employee("Mister", "GOD", null, 0));
    // Получаем работника, у которого нет менеджера
    Employee boss = ds.find(Employee.class).field("manager").equal(null).get(); 
    
    //Создаем сотрудника Скотт
    Key<Employee> scottsKey = ds.save(new Employee("Scott", "Hernandez", ds.getKey(boss), 150*1000));
    
    //Добавляем Скотта как работника этого менеджера
    ds.update(boss, ds.createUpdateOperations(Employee.class).add("underlings", scottsKey)); 
    
    // Получаем босса Скотта
    Employee scottsBoss = ds.find(Employee.class).filter("underlings", scottsKey).get(); 
    
    for (Employee e : ds.find(Employee.class, "manager", boss))
       print(e);
    


    Пример запросов, построенных с использованием Fluent API:

    Query q = ds.createQuery(MyEntity.class).filter("foo >", 12).filter("foo <", 30).order("dateAdded").offset(1000).retrievedFields(true, "foo"); //Создаем запрос для поиска
    
    MyEntity e = ds.find(MyEntity.class).field("name").equal("someName").get(); //Получаем первый элемент с полем name = "someName";
    
    List<Hotel> hotels = ds.find(Hotel.class, "stars >", 3).sort("-stars").asList();
    


    Пример работы в стиле DAO:

    public class HotelDAO extends BasicDAO<Hotel, String> {
        public HotelDAO(Morphia morphia, Mongo mongo ) {
            super(mongo, morphia, "myDB");
        }
    public List<Hotel> findByTitle( String title ) {
        Pattern regExp = Pattern.compile(name + ".*", Pattern.CASE_INSENSITIVE);
        return ds.find(Hotel.class).filter("title", regExp).sort("title").asList();
    }
    }
    
    HotelDAO hDAO = new HotelDAO(...);
    List<Hotel> hotels = hDAO.findByTitle("Luxury");
    hDAO.save(new Hotel(...));
    


    Ссылки:
    Поделиться публикацией

    Похожие публикации

    Комментарии 51

      0
      Всмысле оно заточено чисто под mongoDB?
        0
        Да, именно так.
        0
        Спасибо.
        Как раз искал что-то подобное.
          +2
          Только не ORM, т.к. монго — не реляционный сторедж.
            +2
            Ну я бы сказал, что на уровне объектов реляционность все же присутствует. Mongo поддерживает поиск по структуре документа, поэтому на документы можно мапить довольно сложные структуры. То есть в терминах Mongo документ один, а программист-клиент работает с набором связанных объектов.

            Вообще можно очень условно рассматривать каждый монговский документ как олап кубик. Такую структуру можно описать даже стандартным набором JPA аннотаций. Может, замутить стартапчик?
              0
              не перевирайте термин
              0
              «Реляционный» — не синоним «поддерживающий связи». «Реляционный» значит «табличный».
                0
                Не путайте отношение (relation) и таблицу. Да, это одно и то же с точки зрения реляционной СУБД. Но ORM — это механизм, позволяющий создавать виртуальную реляционную структуру на уровне объектов, и ему вовсе необязательно иметь нечто реляционное в качестве хранилища данных. Это просто на один уровень абстракции выше.
                  0
                  ORM — это механизм позволяющий создавать виртуальную объектную базу данных по верх физической реляционной базы данных. Если ваше хранилище поддерживает прямую ссылочность, то и ORM не нужен, нужно более простое решение.
                    0
                    Да почему же поверх физической реляционной базы данных? ))) Бэкэнд может быть любым. Я понимаю, что мои слова для Вас не авторитетны, может быть эта ссылка Вас переубедит?
                      0
                      Я исхожу из того, что название технологии отображает реальную суть. Если кто-то использует это название не по назначению — это их проблемы. Итак, Object Relational Mapping. Собственно имеем два перевода — отображение объектов на таблицы (отношения) и отображение объектов на связи. Второй перевод абсолютно бредовый. И да, по ссылке ничего про «виртуальную реляционную структуру на уровне объектов» нет и быть не может ибо это выражение лишено смысла — объекты подразумевают связи между собой, если вы под «реляционным» имели ввиду «связочный», получается масло масленое.
                        0
                        Я ни в одном своем комментарии не употреблял термин «реляционный» в смысле «связочный». Мне надоел этот спор ни о чем с подменами тезисов. Я сдаюсь.
                          0
                          Я не знаю, из чего вы исходите, но вы явно противоречите определению WikiPedia. Там ясно написано
                          Object-relational mapping (ORM, O/RM, and O/R mapping) in computer software is a programming technique for converting data between incompatible type systems in object-oriented programming languages.

                          Нет здесь ничего про «реляционный». Я надеюсь, у вас нет монополии на разъяснение смысла IT терминов? И вообще, зачем цепляться к словам? Употребили термин и употребили. Все поняли в каком значении.
                            0
                            Давайте все таки вернемся к обсуждению термина. В википедии полнным-полно неточностей и возможно статья нуждается в правке.

                            >Все поняли в каком значении.

                            Давайте все же разберемся :) Я термин Object Relational Mapping трактую так: отражение объектов на отношения, где под отношениями подразумеваются таблицы РСУБД. Под отношением можно понимать и более общее, математическое понятие, однако получается слишком общее, ничего толком не значущее определение. Практически всегда под отношениями в контексте баз данных подразумевают таблицы РСУБД. В той же статье с вики дальше идет обяснение в контексте РСУБД.

                              0
                              Уже писал Денису в личку. частично продублирую сюда:

                              Перечитал свой первый комментарий. Пожалуй да, он допускает и такую трактовку. Попробую переформулировать то, что я имел в виду в первом и втором комментариях: Отношение это не всегда таблица РСУБД. Это логическая сущность. И в Монго отношения представляются в виде документа или его части. Поэтому я и приводил олап кубы как наиболее, как мне кажется, наглядный пример того, как отношения из обычной РСУБД разворачиваются в структуры подобные документам монго. Но логические отношения-то из них при этом не исчезают! А ORM мапит именно объекты именно на отношения. Все верно.
                                +1
                                Я понял вашу трактовку. Однако «давайте разберемся» и "я трактую" у меня как-то плохо согласуются. Вы можете чем-то подкрепить свое мнение? Скажем, я слово Relational в аббревиатуре ORM перевожу как производное от «связь», а не «реляционный». Да и слово «реляционный», в общем-то говоря, суть «выражающий отношение».

                                В реляционной теории слово «таблица» — неформальное. Ключевое слово в реляционной модели данных — «отношение». В оригинальной работе Кодда, с которой, собственно, все начиналось, слово таблица (table) вообще встречается всего дважды в самом начале.

                                Я термин Object Relational Mapping трактую так: отражение объектов на отношения, где под отношениями подразумеваются таблицы РСУБД

                                В самом термине про РСУБД нет ни слова. И под отношениями вообще-то должны пониматься именно отношения. А вовсе не таблицы, которые эти отношения вообще говоря реализуют.
                                  0
                                  >Вы можете чем-то подкрепить свое мнение? Скажем, я слово Relational в аббревиатуре ORM перевожу как производное от «связь», а не «реляционный»

                                  Я это могу подкрепить тем, что выражение «отображение объектов на связи» не имеет никакого смысла. А вот «отображение объектов на таблицы» имеет вполне конкретный смысл.

                                  >Да и слово «реляционный», в общем-то говоря, суть «выражающий отношение».

                                  Мы же про базы данных говорим? Реляционный в теории баз данных означает «основаный на реляционной модели данных». На википедии есть утверждение, которому я охотно верю:

                                  «In relational model:
                                  A relation is a data structure which consists of a heading and an unordered set of tuples which share the same type.»

                                  Это таблицы, товарищи!

                                  Вот спорить корректно ли называть моного реляционным хранилищем не берусь, на этом с товарищем dxb мы спор и закончили.

                                    0
                                    Я это могу подкрепить тем, что выражение «отображение объектов на связи» не имеет никакого смысла

                                    Откуда вообще взялось это выражение? Ваш дословный перевод с английского термина «Object/Relational Mapping»? На мой взгляд, перевод неграмотный. Я бы сказал, что это переводится как «отображение объектов и связей [между ними]». Кстати, вообще это интересный аргумент в споре — перевести термин с английского дословно, получить ахинею и утверждать, что термин не имеет смысла.

                                    Мы же про базы данных говорим?

                                    Кто говорит? Я говорю про информацию и ее хранение. Но даже если бы мы говорили о базах данных, они бывают не только реляционными.

                                    In relational model:
                                    A relation is a data structure which consists of a heading and an unordered set of tuples which share the same type.

                                    Ткните пальцем, пожалуйста, где тут конкретно сказано про таблицы.
                                      0
                                      >Кстати, вообще это интересный аргумент в споре — перевести термин с английского дословно,

                                      Хорошо, докажите, что я перевел не правильно, и я соглашусь. Ваша трактовка странная и я ее впервые слышу.

                                      >Но даже если бы мы говорили о базах данных, они бывают не только реляционными.

                                      Да. В теории баз даных есть сетевые модели, к примеру. И что это меняет?

                                      >Ткните пальцем, пожалуйста, где тут конкретно сказано про таблицы.

                                      «unordered set of tuples which share the same type.»

                                      Вполне понятно, что это синоним таблиц.
                                        0
                                        Хорошо, докажите, что я перевел не правильно, и я соглашусь. Ваша трактовка странная и я ее впервые слышу.

                                        Это сделать довольно легко. Вы сказали
                                        Я это могу подкрепить тем, что выражение «отображение объектов на связи» не имеет никакого смысла.

                                        То есть, вы сами признали, что ваш перевод не имеет никакого смысла. Но сам термин смысл имеет, раз он используется во всем мире. То есть, вы перевели его некорректно. Полагаю… ЧТиД?

                                        Да. В теории баз даных есть сетевые модели, к примеру. И что это меняет?

                                        Мы говорили не о теории баз данных, а о самих базах данных, которые бывают разными. В том числе и «объектные, объектно-ориентированные, объектно-реляционные».

                                        «unordered set of tuples which share the same type.»Вполне понятно, что это синоним таблиц.

                                        Из чего именно это становится понятно? Коллекция MongoDb, каждый документ которой имеет один и тот же формат вполне является «unordered set of tuples which share the same type».
                                          0
                                          Нет, докажите, что перевод «отображение объектов на таблицы» не верен, а верен какой-то другой.

                                          >Коллекция MongoDb, каждый документ которой имеет один и тот же формат

                                          Такую структуру данных вполне можно назвать таблицей или отношением.

                                          Но дело в том, что такая коллекция документов одного формата не является основной структурой для монго. Основная рабочая единица в монго — это документ, поэтому монго не реляционное хранилище. Что бы можно было прозрачно работать с монго как с реляционным хранилищем нужна либа.
                                            0
                                            Нет, докажите, что перевод «отображение объектов на таблицы» не верен, а верен какой-то другой.

                                            Не понимаю, почему я должен что-то доказывать, а не вы. Это ведь вы ратуете за исключительно однобокое толкование термина ORM, а не я. Я считаю, что термин ORM можно применять как к реляционным базам данных, так и к любым другим, которые могут хранить отношения между сущностями. Поэтому справедливы оба толкования этого термина.

                                            Но дело в том, что такая коллекция документов одного формата не является основной структурой для монго.

                                            Причем тут является основной структурой или нет?
                                            Коллекция MongoDb, каждый документ которой имеет один и тот же формат вполне является «unordered set of tuples which share the same type».

                                            Вы можете оспорить мои слова или нет? Зачем увиливать?
                                              0
                                              > Не понимаю, почему я должен что-то доказывать, а не вы.

                                              У меня есть аргументы против вашего трактования. Вот они:

                                              Отображение объектов и связей — объекты подразумевают связи, инче это не объекты.

                                              Я не нашел примеров ORM, которые меппят не на таблицы.

                                              На сайте Morphia нет упоминания, что это ORM

                                              Для Redis есть похожее решение, и оно там именуется Object Hash Mapping

                                              А у вас против моего нету :) Только «Я считаю, что термин ORM можно применять как к реляционным базам данных»

                                              Ну коль вы дошли до такой аргументции, то удачи.

                                              >Вы можете оспорить мои слова или нет? Зачем увиливать?

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

                                                Полностью с вами согласен. Только вот связи можно хранить не только в реляционных базах данных.

                                                Я не нашел примеров ORM, которые меппят не на таблицы.

                                                Ну вот Morphia например :)

                                                Ну коль вы дошли до такой аргументции, то удачи.

                                                Так ведь это ваша аргументация :) «Я считаю, что термин ORM можно применять только к реляционным базам данных» — ваша? Или нет?

                                                На сайте Morphia нет упоминания, что это ORM

                                                Читайте тред внимательно. Вы слишком увлеклись нашим маленьким спором.
                                                  0
                                                  www.hibernate.org/about/orm

                                                  «RDBMSs represent data in a tabular format (a spreadsheet is a good visualization for those not familiar with RDBMSs), whereas object-oriented languages, such as Java, represent it as an interconnected graph of objects.»

                                                  Здесь вполне ясно написано, что orm — это штуковина, позволяющяя сблизить 2 мира: объектный и реляционных баз.
                                                    0
                                                    Вы куда смотрите-то? На той странице вообще слово ORM не встречается. Термин «Object/Relational Mapping» там вообще никак не толкуется, практически. Только ссылка на Wikipedia справа. Там сказано
                                                    Specifically, Hibernate is concerned with data persistence as it applies to relational databases (RDBMS)


                                                    И все. А далее

                                                    In the world of Object-Oriented applications, there is often a discussion about using an object database (ODBMS) as opposed to a RDBMS. We are not going to explore that discussion here. Suffice it to say that RDBMS remain a very popular persistence mechanism and will so for the foreseeable future.

                                                    То есть спорить попусту, как это делаете вы, они не намерены :)

                                                    Кстати, если вы подозреваете в большом количестве ошибок Wikipedia, почему бы не предположить тоже самое в отношении Hibernate? Тем более, что у них ссылка на Wikipedia справа поставлена. Значит, они доверяют мнению Wikipedia, раз на нее ссылаются?
                                                      0
                                                      >Термин «Object/Relational Mapping» там вообще никак не толкуется, практически.

                                                      Весь топик целиком, т.к. он озоглавлен там как «What is Object/Relational Mapping?»

                                                      Введите в гугле object relational mapping и в каждой статье с описанием вы увидете, что под relational имеется ввиду relational модель реляционной базы.

                                                      Аргументы «ну и где это написано» не принимаются, если вы этого не видите, я вам этого не докажу.
                                                        0
                                                        И да, зачем вы привели вот это:

                                                        «In the world of Object-Oriented applications, there is often a discussion about using an object database (ODBMS) as opposed to a RDBMS. We are not going to explore that discussion here. Suffice it to say that RDBMS remain a very popular persistence mechanism and will so for the foreseeable future.»

                                                        ?

                                                        Тут они пишут, что вместо rdbms + orm можно юзать odbms, но вот что лучше они спорить не будут, все правильно.
                                                          0
                                                          Открываю Google и ищу «object relational mapping mongodb». Нахожу, например:

                                                          Grails Object Relational Mapping for MongoDB

                                                          В общем, с вами все ясно :)
                                                            0
                                                            И что? Значит GORM теперь не только ORM, но и ODM. Короче это с вами все ясно. Вы хотите мне доказать, что черное — это белое.
                                                              0
                                                              Гы, и интересно как это вы нагугли этот горм? Ввели «orm mongodb»? )))

                                                              Вот вам из первых нескольких ссылок, которые выдает мне гугл на «object relational mapping»:

                                                              «Object-relational mapping is used to map object-oriented programming objects to relational databases managed by Oracle, DB2, Sybase, and other relational database managers (RDBMSs). „

                                                              “A PersistenceLayer connecting objects in an object-oriented system to data stored in a relational database.»

                                                              «Mapping Objects to Relational Databases: O/R Mapping In Detail»

                                                              И так далее, что вполне логично и закономерно в плане интерпретации слова relational
                                            0
                                            >отображение объектов и связей [между ними

                                            И еще я заметил вот что: объекты подразумевают связи. Так бы никто не сказал.
                                              0
                                              Поясните, пожалуйста, я не совсем вас понял.
                        0
                        Да, правильно называть ODM
                          +1
                          Надо автора проинформировать, а то он, бедный не в курсе: blog.mongodb.org/post/5217011262/improving-scalable-java-application-development-with-mon
                          0
                          Поддержка GWT — это УГ которое не работает и не собирается к сожалению.
                            0
                            ну у кого как
                              0
                              Пробовали и в проекте работало? entity с ObjectId нормально собирались?
                            0
                            извиняюсь за оффтоп, я из другого мира, мимо проходил.

                            аннотации — это конструкции вида @foo decl?
                            чтоли в жаве есть рефлексивность?
                              0
                              Конечно. И аннотации, и рефлексия.
                                0
                                Правильно ли я понял, что аннотации — это типа програмно-читабельных комментариев, а рефлексия ограничена интроспекцией?
                                  +1
                                  первое — с небольшой натяжкой да, а второе — нет. Есть и манипулирование данными, и динамическая компиляция, и подмена байткода, и многое другое.
                              0
                              А есть где-нибудь сравнение Morphia и Spring Data?
                              0
                              Лично мне кажется что очень не хватает JPA имплементации. Это же хорошо когда есть стандарт и люди его придерживаются (даже если не полностью).
                                0
                                Как я понял Morphia без сессии (Unit Of Work), а это сильно проще в реализации, чем сессия JPA. Да и потом я что-то не верю, что приложение написаное на JPA с РСУБД бекендом заведется на MongoDB — все равно переписывать придется приложение, толку от однинаковости API в таком случае не будет.
                                0
                                "@Serialized EncryptedReviews;"

                                Имя поля класса забыли.
                                  0
                                  Скажите, а Вы эту штуку в деле пробовали. На сколько она работоспособна. Есть ил какие трудности?
                                    0
                                    Нет, сам не пробовал, к сожалению.
                                    0
                                    Мне сначала очень понравилась возможность работать с mongoDB с помощью аннотированных классов. Но фишка mangoDB — в динамичности структуры entity. При использовании же заранее определенных классов с аннотациями, мы пытаемся работать с noSQL как с обычной реляционной базой, что нивелирует преимущества подхода. Как по мне, нужно либо динамически строить объекты у которых нет заранее заданной структуры и сохранять их в монге, либо уж по старинке использовать SQL+Hibernate+Spring и не заморачиваться.

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

                                    Самое читаемое