Pull to refresh

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

Reading time 3 min
Views 16K
Читая ежедневную порцию постов из своей подборки 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(...));


Ссылки:
Tags:
Hubs:
+30
Comments 51
Comments Comments 51

Articles