IntroductionThe Orient Object DB works on top of the Document Database and it's able to treat Java objects. It uses Java Reflection to register the class structure and Javassist Proxy to manage Object2Document handling. Please consider that the Java reflection in modern Java Virtual Machines is really fast and the discovering of Java meta data is made at first time. Future implementation could use also the byte-code enhancement techniques in addition. If you want use the Orient Object Database you need to link the orient-object.jar in your classpath. The proxied objects has a ODocument bounded to it and trasparently replicate object modifications. It also allows lazy loading of the fields: they won't be loaded from the document until the first access. To do so the object MUST implement getters and setters since the Javassist Proxy is bounded to them. In case of object load, edit an update all non loaded fields won't be lost. The database instance has an API to generate new objects already proxied, in case a non-proxied instance is passed it will be serialized, wrapped around a proxied instance and returned. Read more about the Binding between Java Objects and Records. Quick example of usage: // OPEN THE DATABASE
OObjectDatabaseTx db = new OObjectDatabaseTx ("remote:localhost/petshop").open("admin", "admin");
db.getEntityManager().registerEntityClasses("foo.domain");
// CREATE A NEW PROXIED OBJECT AND FILL IT
Account account = db.newInstance(Account.class);
account.setName( "Luke" );
account.setSurname( "Skywalker" );
City rome = db.newInstance(City.class,"Rome", db.newInstance(Country.class,"Italy"));
account.getAddresses().add(new Address("Residence", rome, "Piazza Navona, 1"));
db.save( account );
// CREATE A NEW OBJECT AND FILL IT
Account account = new Account();
account.setName( "Luke" );
account.setSurname( "Skywalker" );
City rome = new City("Rome", new Country("Italy"));
account.getAddresses().add(new Address("Residence", rome, "Piazza Navona, 1"));
// SAVE THE ACCOUNT: THE DATABASE WILL SERIALIZE THE OBJECT AND GIVE THE PROXIED INSTANCE
account = db.save( account );Connection PoolOne of most common use case is to reuse the database avoiding to create it every time. It's also the typical scenario of the Web applications. // OPEN THE DATABASE
OObjectDatabaseTx db= OObjectDatabasePool.global().acquire("remote:localhost/petshop", "admin", "admin");
try {
...
} finally {
db.close();
}The close() method doesn't close the database but release it to the owner pool. It could be reused in the future. Database URLIn the example above a database of type Database Object Transactional has been created using the storage: remote:localhost/petshop. This address is a URL. To know more about database and storage types go to Database URL. In this case the storage resides in the same computer of the client, but we're using the remote storage type. For this reason we need a Orient Server instance up and running. If we would open the database directly bypassing the server we had to use the local storage type such as "local:/usr/local/database/petshop/petshop" where, in this case, the storage was located in the /usr/local/database/petshop folder on the local file system. Multi-threadingThe OObjectDatabaseTx class is non thread-safe. For this reason use different OObjectDatabaseTx instances by multiple threads. They will share local cache once transactions are committed. InheritanceStarting from the release 0.9.19 OrientDB supports the Inheritance. Using the ObjectDatabase the inheritance of Documents fully matches the Java inheritance. When registering a new class Orient will also generate the correct inheritance schema if not already generated. Example: public class Account {
private String name;
// getters and setters
}
public class Company extends Account {
private int employees;
// getters and setters
}When you save a Company object, OrientDB will save the object as unique Document in the cluster specified for Company class. When you search between all the Account instances with: SELECT FROM account The search will find all the Account and Company documents that satisfy the query. Use the databaseIf you want to connect to a remote database using a OrientDB Server instance, you need to link the orient-client.jar in your classpath and to register the Remote Engine in your client application by calling: Orient.instance().registerEngine(new OEngineRemote()); Before to use a database you need to open it: OObjectDatabase db = new OObjectDatabaseTx("remote:localhost/petshop").open("admin", "admin");The database instance will share the connection versus the storage. if it's a local storage, then all the database instances will be synchronized on it. If it's a remote storage then the network connection will be shared among all the database instances. To get the reference to the current user use: OUser user = db.getUser(); Once finished remember to close the database to free precious resources. db.close(); Working with POJOPlease read the POJO binding guide containing all the information about the management of POJO. Work in schema-less modeThe Object Database can be used totally in schema-less mode as long as the POJO binding guide requirements are followed. Take a look to this example: OObjectDatabase db = new OObjectDatabaseTx("remote:localhost/petshop").open("admin", "admin");
Person p = db.newInstance(Person.class);
p.setName( "Luca" );
p.setSurname( "Garulli" );
p.setCity( new City( "Rome", "Italy" ) );
db.save( p );
db.close();This is the very first example. While the code it's pretty clear and easy to understand please note that we didn't declared "Person" structure before now. However Orient has been able to recognize the new object and save it in persistent way. Work in schema-full modeIn the schema-full mode you need to declare the classes you're using. Each class contains one or multiple properties. This mode is similar to the classic Relational DBMS approach where you need to create tables before to store records. To work in schema-full mode take a look to the Schema APIs page. Create a new objectThe best practice to create a Java object is to use the OObjectDatabase.newInstance() API: public class Person {
private String name;
private String surname;
public Person(){
}
public Person(String name){
this.name = name;
}
public Person(String name, String surname){
this.name = name;
this.surname = surname;
}
// getters and setters
}
OObjectDatabase db = new OObjectDatabaseTx("remote:localhost/petshop").open("admin", "admin");
// CREATES A NEW PERSON FROM THE EMPTY CONSTRUCTOR
Person person = db.newInstance(Person.class);
animal.setName( "Antoni" );
animal.setSurname( "Gaudi" );
db.save( person );
// CREATES A NEW PERSON FROM A PARAMETRIZED CONSTRUCTOR
Person person = db.newInstance(Person.class, "Antoni");
animal.setSurname( "Gaudi" );
db.save( person );
// CREATES A NEW PERSON FROM A PARAMETRIZED CONSTRUCTOR
Person person = db.newInstance(Person.class,"Antoni","Gaudi");
db.save( person );However any Java object can be saved by calling the db.save() method, if not created with the database API will be serialized and saved. In this case the user have to assign the result of the db.save() method in order to get the proxied instance, if not the database will always treat the object as a new one. Example: Animal animal = new Animal(); animal.setName( "Gaudi" ); animal.setLocation( "Madrid" ); animal = db.save( animal ); Note that the behaviour depends by the transaction begun if any. See Transactions Browse all the records in a clusterfor (Object o : database.browseCluster("CityCars")) {
System.out.println( ((Car) o).getModel() );Browse all the records of a classfor (Animal animal : database.browseClass(Animal.class)) {
System.out.println( animal.getName() );Count records of a classlong cars = database.countClass("Car");Count records of a clusterlong cityCars = database.countCluster("CityCar");Update an objectAny proxied object can be updated using the Java language and then calling the db.save() method to synchronize the changes to the repository. Behaviour depends by the transaction begun if any. See Transactions. animal.setLocation( "Nairobi" ); db.save( animal ); Orient will update only the fields really changed. Example of how to update the price of all the animals by 5% more: for (Animal animal : database.browseClass(Animal.class)) {
animal.setPrice(animal.getPrice() * 105 / 100);
database.save(animal);
}If the db.save() method is called with a non-proxied object the database will create a new document, even if said object were already saved Delete an objectTo delete an object call the db.delete() method on a proxied object. If called on a non-proxied object the database won't do anything. Behaviour also depends by the transaction begun if any. See Transactions. db.delete( animal ); Example of deletion of all the objects of class "Animal". for (Animal animal : database.browseClass(Animal.class)) database.delete(animal); Execute a queryOrient supports two kinds of queries:
Native queryNative queries are written in Java code. They are pretty fast since the JVM compiles it as for the rest of application. Example: List<ODocument> result = db.getUnderlying().command(
new ONativeSynchQuery<ODocument, OQueryContextNativeSchema<ODocument>>("Person",
new OQueryContextNativeSchema<ODocument>()) {
@Override
public boolean filter(OQueryContextNativeSchema<ODocument> iRecord) {
return iRecord.field("city").field("name").eq("Rome").and().field("name").like("G%").go();
};
}).execute();SQL queryAlthough OrientDB is part of NoSQL databases, supports the SQL engine, or at least a subset of it with such extensions to work with objects and graphs. To know more about the SQL syntax supported go to: SQL Query. Example: List<Animal> result = db.query(
new OSQLSynchQuery<Animal>("select * from Animal where ID = 10 and name like 'G%'"));SQL CommandsTo execute SQL commands use the command() method passing a OCommandSQL object: int recordsUpdated = db.command(
new OCommandSQL("update Animal set sold = false")).execute();See all the SQL Commands. Get the ODocument from a POJOThe OObjectDatabase implementation has APIs to get a document from its referencing object: ODocument doc = db.getRecordByUserObject( animal ); In case of non-proxied objects the document will be a new generated one with all object field serialized in it. Get the POJO from a RecordThe Object Database can also create an Object from a record. Object pojo = db.getUserObjectByRecord(record); Old Implementationuntil 1.0rc9 IntroductionThis implementation and documentation refers to all ODatabaseObjectXXX deprecated classes. The Orient Object DB works on top of the Document Database and it's able to treat Java objects without the use of pre-processor, byte enhancer or Proxy classes. It uses the simpler way: the Java Reflection. Please consider that the Java reflection in modern Java Virtual Machines is really fast and the discovering of Java meta data is made at first time. Future implementation could use the byte-code enhancement techniques in addition. Read more about the Binding between Java Objects and Records. Quick example of usage: // OPEN THE DATABASE
ODatabaseObjectTx db = new ODatabaseObjectTx ("remote:localhost/petshop").open("admin", "admin");
db.getEntityManager().registerEntityClasses("foo.domain");
// CREATE A NEW ACCOUNT OBJECT AND FILL IT
Account account = new Account()
account.setName( "Luke" );
account.setSurname( "Skywalker" );
City rome = new City("Rome", new Country("Italy"));
account.getAddresses().add(new Address("Residence", rome, "Piazza Navona, 1"));
db.save( account );Connection PoolOne of most common use case is to reuse the database avoiding to create it every time. It's also the typical scenario of the Web applications. // OPEN THE DATABASE
ODatabaseObjectTx db= ODatabaseObjectPool.global().acquire("remote:localhost/petshop", "admin", "admin");
...
db.close();The close() method doesn't close the database but release it to the owner pool. It could be reused in the future. InheritanceStarting from the release 0.9.19 OrientDB supports the Inheritance. Using the ObjectDatabase the inheritance of Documents fully matches the Java inheritance. Example: public class Account {
private String name;
}
public class Company extends Account {
private int employees;
}When you save a Company object, OrientDB will save the object as unique Document in the cluster specified for Company class. When you search between all the Account instances with: SELECT FROM account The search will find all the Account and Company documents that satisfy the query. |