db4o

from Wikipedia, the free encyclopedia
Db4o

Db4o logo
Basic data

developer Versant Corporation
Current  version 8.0
(February 1, 2011)
operating system Unix derivatives , Linux , Windows
programming language C # , Java
category Database system , server
License Dual license system ( proprietary and GPL )
German speaking No
www.db4o.com in the web archive

db4o ( database for objects ) is an object database for the Java and .NET platform, the further development of which was discontinued in 2011. The source code is still available on Github . It belongs to the NoSQL databases. The db4o program library is characterized by a comparatively low memory requirement of around 600 kB. This makes it particularly suitable for embedding in other programs and for environments with limited memory resources, such as PDAs . Db4o could be used either under the terms of the GPL or with commercial licenses.

db4o supported Java's JDK 1.1.x to 6.0 and ran natively on J2EE , J2SE and all J2ME configurations whose J2ME profile provides the Reflection API . In addition, db4o supports all languages ​​that are based on the CLR virtual machine of the .NET platform, such as C # or VB.NET . The C # source code of the db4o program library required for the .NET platform was largely generated from the Java source code and can also run on the Mono implementation of the .NET platform.

history

The db4o project began in 2000 under the leadership of Carl Rosenberger. Db4o was developed by db4objects, Inc., which was founded in 2004 with the help of investors such as Mark Leslie ( VERITAS Software ), Vinod Khosla ( Sun Microsystems ) and Jerry Fiddler ( Wind River ).

In December 2008 the database division was sold to Versant .

DB4O is currently no longer being developed. The website www.db4o.com is no longer accessible, and the last change at Sourceforge was in 2015, Versant has been part of Actian since December 2012.

License

Since 2004, db4o has been licensed either under the GPL as free software or under a commercial license that allows its use in non-GPL projects. There was also a Classpath-like license that allows db4o to be integrated into open source projects that are not db4o / GPL compliant.

System properties and object management

  • In addition to the small memory requirement for the program library, the RAM requirement is also low during runtime and normally does not exceed 1 MB.
  • Db4o cannot be administered externally. All settings must be made via the program code.
  • The database can be used in mixed environments: For example, two client applications programmed in C # or Java can jointly access a database that is operated by a server application programmed in Java or C #. With the help of the alias feature of db4o, class names can be renamed, which is necessary, for example, because of the different naming conventions.
  • One of the most important advantages of db4o: Objects can be saved without having to take any special precautions. It is not necessary to derive the classes to be saved from special superclasses , nor do special interfaces have to be implemented. Enrichment of the byte code , as used, for example, in aspect-oriented programming , is also not necessary. The objects can contain any type and can also be nested at any depth.
  • With this property it is possible to implement persistence with little effort.

Basic API

API ( application programming interface ) called the programming interface with which the database is programmed. It shows that the difference to other programs such as Hibernate or JPA / EJB is not too great.

A simple code example that should be run coherently:

   // Öffne eine Datenbank
   ObjectContainer db = Db4o.openFile("C:/beispiel.db");
   try {
      // Speichere zwei Personen
      db.store(new Person("John Doe","TOP INC",45));
      db.store(new Person("Clara Himmel","BB Radio",30));
      // Iteriere über alle Personen
      ObjectSet result = db.queryByExample(new Person());
      while (result.hasNext()) {
          System.out.println(result.next());
      }
      // Verändere eine Person
      result = db.queryByExample(new Person("Clara Himmel"));
      Person found = (Person) result.next();
      found.setAge(25);
      db.store(found);
      // Lösche eine Person
      db.delete(found);
      // Schreibe die Änderungen fest
      db.commit();
   }
   finally {
      // Schließe die Datenbank
      db.close();
   }
  • Similar to EJB / JPA (there EntityManager), an ObjectContainerobject manager is created first. This container can either refer to a file or, in a client-server architecture, to a database provided by a server. In the first case, all data is saved in a file.
    • Disadvantage: The data are therefore not completely independent of the programming language class. The format is proprietary and can no longer be read so easily by subsequent programming languages.
    • Advantage: This can be exchanged very easily between companies. Data access is very fast.

Then all CRUD operations ( C reate, R ead, U pdate and D elete) are carried out:

CREATE
With db.store(object)any object is stored. This is analogous to the JPA standard, which is em.persist(object)called. In the latter case, however, the domain object must at least have been @Entityannotated or registered in XML .
READ
This is followed by a simple search using the simplest query language, Query by Example . A person instance is created as a template and any fields are set. All objects in the database for which the fields match are returned. foundtherefore contains the complete object that was saved above.
UPDATE
This foundobject is now referenced internally and can therefore be changed .setAge(25)and saved again. Then it's updated. In the JPA standard, this corresponds to one em.merge(object), whereby the object must always be attached , i.e. referenced ( noted ) by the session .
DELETE
db.delete(object) deletes an object that must be known to the object manager.

Query languages

Db4o offers three query languages , none of which are too far removed from what Hibernate and JPA offer in EJB 3.0:

Query By Example (QBE)

Query by Example stands for a search based on examples. The foundations for this were laid by Moshé M. Zloof in several articles in the 1970s. Hibernate and db4o offer this mechanism in a slightly weakened version.

With db4o, as shown above, any object can be created. Then either:

  • No field is set, so all fields are zero, or a reference to the class is transferred directly (e.g. Person.class): In this case, all instances of the class stored in the database are returned.
  • Any number of fields can be set: Then all saved objects are returned in which the fields filled in the pattern match the value in the object.
  • It is nulltransferred: This returns all objects from the database.

Complex query criteria cannot be expressed using this type of query.

SODA / Criteria Queries

Internally, all queries at db4o are mapped to SODA. SODA is the programming interface of the SODA - Simple Object Database Access project hosted on SourceForge , which is partly supported by the developers of db4o, but is developed independently of db4o.

The SODA queries are very similar to those of Hibernate Criteria queries. An example:

  Query query=db.query();
  query.constrain(Person.class);
  query.descend("alter").constrain(50).greater();
  ObjectSet result=query.execute();

Here the query is initially restricted to the Person class, and then further to all persons older than 50.

This type of query is an example of Query by API , which creates trees of objects that are used to constrain queries. It is therefore more powerful than the other query mechanisms, but also more difficult to create because the code is more difficult to read. Using character strings as query parameters does not guarantee type safety at the time of compilation.

Native queries

Native Queries (Engl. Native queries ) are queries that in the programming of the client application are formulated so db4o for example, in Java or C #.

The code of native queries is normally not executed with db4o, but is analyzed at runtime. A SODA criteria query is created based on the result of the analysis . This has the advantage that the persistent objects do not have to be instantiated, which is time-consuming. Only if the analysis fails due to the complexity of the query is the object instance generated and the program code of the native query must be executed.

To compare native queries and JPQL or HQL, please refer to Microsoft's LINQ . Microsoft was able to change the language and thus embed powerful query constructs directly in C #.

advantages

  • The programmer does not need to use a special query language such as B. SQL , learn.
  • The queries use the elements of the programming language and are therefore type-safe.
  • The queries can be taken into account when the program is redesigned ( refactored ).

For these reasons, incorrect query commands are recognized earlier or avoided by avoiding common causes than is the case when using special query languages.

disadvantage

  • The creation of the query is completely in the hands of the developers and not under the control of administrators, who can, for example, take into account security aspects of the database when using stored procedures .
  • Native queries are not as powerful as corresponding constructs in special query languages ​​such as HQL or JPQL. In these languages, special query criteria, such as compression , can be expressed explicitly.

Examples

The decisive factor for comfortable use is whether and how the language used supports closures . Without closure support, you have to work with inner classes or unbound method pointers or delegates in order to pass the query as "free-floating code" to a method.

C # .NET 3.0 (Using a Lambda Expression );

  var persons = db.Query<Person>( s => s.Age > 50 );

C # .NET 2.0 (using an unbound method pointer):

  IList<Person> persons = db.Query<Person>( delegate(Person person){
    return person.Age > 50;
  });

Java JDK 5 (using a generic anonymous class):

  List<Person> personen = db.query(new Predicate<Person>() {
    public boolean match(Person person) {
      return person.getAge() > 50;
    }
  });

Java JDK 1.2 to 1.4 (using an anonymous class):

  List personen = db.query(new Predicate() {
    public boolean match(Object object) {
      Person person = (Person)object;
      return person.getAge() > 50;
    }
  });

Java JDK 1.1 (using an inner class):

  ObjectSet personen = db.query(new PersonFilter());

  public static class PersonFilter extends Predicate {
    public boolean match(Object object) {
      Person person = (Person)object;
      return person.getAge() > 50;
    }
  }

Transactions

Opening the container from the example above creates a transaction . This can be written or discarded with db.commit()or db.rollback()on the database at any time . Db4o guarantees ACID behavior. Everything within a transaction complies with ACID requirements. Internally, all access to the database is serialized within the transaction. This has major consequences for the database system:

  • Due to the proprietary data format, access for a thread is usually faster than other combinations of relational database and object-relational mapping.
  • However, “multithreaded” access does not yet scale with db4o, as is necessary, for example, for the construction of large web portals.

Experience has shown that up to a dozen accesses per second can normally be achieved, which can be sufficient for many applications. However, because of the above points, db4o is working on a server version that also scales with concurrent access.

Client / server modes

Db4o offers several working modes:

  1. Embedded Mode : An object container is opened in the application code, as shown in the example above. File-based access is the basis here.
  2. Client / Server Mode : Db4o can be started as a server and thus receive requests from clients.

Example for the server:

ObjectServer server = Db4oClientServer.openServer("c:/liveserver.db", 8732);
server.grantAccess("user1", "password");
server.grantAccess("user2", "password");

A thread is opened here that waits for client requests on port 8732. The server itself can wait via monitors and, for example, make status outputs. Access rights cannot be managed directly from the outside using a tool. These are either created in the code or read in via console, etc.

A client could initially be set up as follows:

aClient = Db4oClientServer.openClient("196.42.103.142", 8732, "user2", "password");

By means of a so-called “Out-Of-Band Signaling” communication protocol, any objects can be sent to the server with which a server can be administered. For example, the request to defragment the file can be sent.

Replication

Any number of servers can be replicated (clustered) with just a few lines. This is done with the db4odRS module.

The objects are given a unique UUID . This means that individual objects or the entire database can be distributed unidirectionally or bidirectionally, i. that is, every new object is sent to all other databases. This allows large and redundant architectures to be set up.

The option of replicating a db4o database in relational databases is also very interesting . This means a bridge / connection between two worlds that are often viewed as separate. db4o uses Hibernate for this . After the configuration of the dRS bridge, individual objects or entire databases can also be transferred in one or both directions via trigger. In many cases, the advantages of both worlds can be fully exploited in industry.

Charging behavior

At db4o there are three modes for loading objects:

IMMEDIATE
In this case, all searched objects are immediately determined when a query is made. If the result set is large, this can be time consuming and memory consuming.
LAZY
An is ObjectSetreturned immediately , but no object has yet been identified. A thread searches for all further results. This behavior is ideal when you want to get the first results quickly. With this loading mode it must be ensured that the query is not evaluated at a defined point in time. This can have side effects if changes are made to the database between the submission and the complete evaluation of the request.
SNAPSHOT
In this intermediate mode, all indexed components of the query are evaluated at a defined point in time. The status of the possible result set is then recorded in a snapshot . The further processing of the non-indexed query components takes place in a concurrent thread. This provides the advantages of the delayed evaluation while avoiding its side effects. However, working memory is used for the created snapshot, which can only be ObjectSetreleased when the is released.

Objects usually form deep reference structures. When objects are loaded, db4o can be used to specify the depth to which referenced objects should be implicitly loaded with the object. It is also possible to activate these referenced objects explicitly at a later point in time. More information on activating, deactivating, querying and updating referenced objects can be found in the db4o reference.

Callbacks

In db4o, there are internal and external callback functions ( callbacks ). These are similar in meaning to the database triggers of other databases. Recall mechanisms are available in many products for database connection and are a powerful tool for carrying out checks, setting standard values ​​or taking security aspects into account, for example.

Internal callbacks

Internal callbacks are added as methods to the classes of the objects to be saved. These are recognized and called up dynamically by db4o using reflection . For this it is not necessary to derive the classes from special interfaces. Similar to the join points of aspect-oriented programming, calls of internal callbacks are possible before and after database-related events. The time of the call is determined by the prefix of the method name: objectCan...–Methods are called before and objectOn...–Methods are called after the event. The return value of the objectCan...methods can be used to control whether the action associated with the event should take place. For internal callbacks following events are available: New, Update, Delete, Activateand Deactivate.

External callbacks

External callbacks are not assigned to any classes. Instead, they are ObjectContainerregistered with. In addition to the events possible with the internal callbacks, callbacks QueryStartedand QueryFinishedare available for these . The use of external callback enables event handling without changing the classes to be saved. This can have the advantage that aspects of persistence do not have to be mixed up with the business logic . If the source code of the classes to be saved is not available, external callbacks must be used.

literature

  • Jim Paterson, Stefan Edlich, Henrik Hörning, Reidar Hörning: The Definitive Guide to db4o Apress Inc., Berkeley CA 2006, ISBN 978-1-59059-656-2 .
  • Patrick Römer, Larysa Visengeriyeva: db4o. fast + compact . Developers.press, Frankfurt 2006, ISBN 978-3-939084-03-7 .
  • William Cook, Carl Rosenberger: Native Queries for Persistent Objects . In Dr. Dobb's Journal . February 2006 ( online ; English; 132 kB).
  • William Cook, Siddhartha Rai: Safe Query Objects . In Proceedings of the International Conference on Software Engineering (ICSE) . 2005. pp. 97-106 ( online ; English; PDF; 143 kB).

Web links

Individual evidence

  1. Lytico: db4o (database for objects). January 3, 2018, accessed February 14, 2018 .
  2. Alexander Neumann: db4objects sells its database business to Versant. In: Heise Newsticker. Heise Verlag, accessed on December 17, 2008 (German).
  3. Actian Corporation Completes Acquisition of Versant. Retrieved February 15, 2018 .