It is recommended to use the Releases on Maven Central here
Used IDE: Intellij IDEA Only use this method if there is some issue to grab it from the maven central repository or if you want to use development builds.
- Clone or download the project
- Open project folder with the IDE
- Right-Click the pom.xml and hit add as maven project
- Import changes if required
- After the dependencies are loaded, open up the maven tab on the right side and click install under lifecycle The latest version should than be installed to your local repository. Continue with Include into project
Add the following dependency to your pom.xml
<dependency>
<groupId>net.endrealm</groupId>
<artifactId>realm-drive</artifactId>
<version>1.1.2-RELEASE</version>
<scope>compile</scope>
</dependency>
Choose any version you like. To always use the newest version use LATEST
(Though this might lead to unwanted updates). On top of that you will probably want to depend on the driver of the backend you want to use. To keep the RealmDrive Lightweighted the drivers are not shaded along. Check here to find supported drivers.
To get started using RealmDrive you will probably want to know how it works. Here is a simple explanation:
You can comunicate with the backend through the reader and writer held in a driver service. You additionally have direct access to the backend implementation, but do keep in mind that direct interactions might require backend specific code and will prevent switching the backend later on. Java classes can directly be converted into database entities and saved into the database. For this to work classes must be registered into the conversion handler of the used service. Fields to save must be annotated with @SaveVar
. Retrieving data out of the backend is simple as well. Just build a query with the QueryBuilder, do note that some complex query setups might be incompatible with some backends. Retrieved values can be automatically converted into Java classes. Either by handing over a mapped class or by letting the conversion service try to automatically find the right class. Unmapped objects can be interacted with as DriveObject instances.
To get started we will first need a DriveService. The DriveServiceFactory will help out here. First thing we need is a DriveSettings object. The following code shows an example on how the settings for a MongoDB database is setup.
DriveSettings settings = DriveSettings.builder()
.type(DriveSettings.BackendType.MONGO_DB)
.hostURL("mongodb://localhost:27017")
.database("yourDatabase")
.table("defaultTable")
.build()
The table and database defined here are used as a default/fallback, if no other is specified in the used query.
Now there is little left to get a simple DriveService implementation
DriveService service = new DriveServiceFactory().getDriveService(settings);
Realm Drive can automatically find a constructor matching the type/super type of the parent object and will inject this to a constructor.
To enable this behaviour put @InjectParent
above the class. If no suitable constructor is found it will fallback to the no args constructor.
Examples can be found here
**Find out how powerful sub classes can be with RealmDrive here
Read more about it here
Now we will want to go ahead and tell the conversion handler that this class can be saved. This is required to automatically transform database entries to classes. While you will not be able to store them directly into the database you can define serializers that will allow you using them as fields.
//service is the implementation of DriveService
ConversionHandler conversion = service.getConversionHandler();
conversion.registerClasses(GreatEntity.class);
At some point you will probably want to store some of java's various classes (e.g. UUID, Date,...), those of other libraries or just want to change how a specific class is saved in general. The classes Date and UUID are supported by default. Serializers are used according to LIFO so it is possible to overwrite them, by just adding serializers supporting those classes.
First of all you have to implement Custom Serializer
public class DateSerializer implements CustomSerializer<Date> {
@Override
public DriveElement toDriveEndpoint(Date element) {
try {
return new SimplePrimitiveDriveElement(element.getTime());
} catch (NotAPrimitiveTypeException e) {
e.printStackTrace();
}
return null;
}
@Override
public Date fromEndpoint(DriveElement endpoint) {
try {
return new Date(endpoint.getAsLong());
} catch (NotAPrimitiveTypeException e) {
e.printStackTrace();
}
return null;
}
@Override
public boolean supportsClass(Class clazz) {
return Date.class.equals(clazz);
}
}
To register it you do almost the same, as you would when registering new classes.
//service is the implementation of DriveService
ConversionHandler conversion = service.getConversionHandler();
conversion.registerSerializers(new DateSerializer());
Classes supported by default (current version):
- UUID
- Date
Now we are going to write objects to our database. We are going to keep using our example class GreatEntity
, our DriveService instance service
and the retrieved instance of the ConversionHandler named conversion
. From here it is pretty straight forward.
This will add an entry to the database. It will try to add the entry, this can cause duplicate entries.
service.getWriter().write(new GreatEntity("Josh", 19, new String[] {"nowhere lol"}, 3));
When choosing overwrite all entities matching the query will be removed and the data will be added to the database.
Query query = new Query().addEq().setField("entityName").setValue("Josh").close().build();
service.getWriter().write(new GreatEntity("Josh", 19, new String[] {"nowhere lol"}, 3), true, query);
Delete will delete values matching the query. It will delete the specified amount of entities.
Query query = new Query().addEq().setField("entityName").setValue("Josh").close().build();
service.getWriter().delete(query, 12); //Deletes twelve entities where entityname == Josh
Now we are going to read objects from our database. We are going to keep using our example class GreatEntity
, our DriveService instance service
and the retrieved instance of the ConversionHandler named conversion
. From here it is pretty straight forward as well.
Query query = new Query().addEq().setField("entityName").setValue("Josh").close().build();
DriveObject object = service.getReader().readObject(query); //Reads an object as a DriveObject. This can later be converted into a class object via a DriveObject method
GreatEntity entity = service.getReader().readObject(query, GreatEntity.class);
Query query = new Query().addEq().setField("entityName").setValue("Josh").close().build();
Iterable<DriveObject> objects = service.getReader().readAllObjects(query);
Iterable<GreatEntity> entities = service.getReader().readAllObjects(query, GreatEntity.class);
When interacting with the reader and writer you will have to hand over Query objects. Some operations are database specific e.g. MongoDB features embedded documents that can be easily be searched for with setField("child1.name")
, while other databases e.g. MySQL don't. Those issues will have to be resolved manually when switching backend.
Writing queries is pretty easy. Just create a new Query object and append requirements e.g. addAnd(). Each requirement has to be closed with .close(). Although right now not required, be sure to call .build() at the end later versions might require this.
Example Query:
Query query = new Query()
.addAnd()
.addEq()
.setField("name")
.setValue("James")
.close()
.addIn()
.setField("age")
.addValue(1)
.addValue(2)
.addValue(40)
.close()
.close()
.addOr()
.addGt()
.setField("height")
.setValue(10)
.close()
.close()
.build();