It is really simple! All you have to do is to implement the empty interface net.sourceforge.floggy.persistence.Persistable or extend a class that implements it.
IMPORTANT: All concrete classes which implement this interface must have a public default constructor like any other POJO.
import net.sourceforge.floggy.persistence.Persistable; public class Person implements Persistable { // Static fields aren't persisted public static int SOME_STATIC_FIELD = 1; private String name; private Date birthday; private char gender; private Phone[] phones; // Transient fields aren't persisted private transient int age; // Each persistable class must have a public default constructor. public Person() { // Do something ... } ... } ... public class Phone implements Persistable { private String number; private String extension; private int type; // Mobile, Home, Work, etc public Phone() { // Do something ... } ... }
All operations, such as saving, loading, deleting and finding objects are made through a single class called net.sourceforge.floggy.persistence.PersistableManager.
The basic operations are explained in the following examples:
Person p = new Person(); p.setName(...); p.setBirthday(...); p.setGender(...); p.setPhones(...); try { PersistableManager pm = PersistableManager.getInstance(); // A new object ID is generated. // You can use it in future operations. int id = pm.save(p); } catch (FloggyException e) { ... }
Person person = new Person(); try { PersistableManager pm = PersistableManager.getInstance(); /* To load an object, use the object ID * generated previously by the save() operation. */ pm.load(person, id); } catch (FloggyException e) { ... }
try { PersistableManager pm = PersistableManager.getInstance(); /* Passing the lazy parameter with value true will avoid the * load of the Phone object associated to the Person instance. */ pm.load(person, id, true); } catch (FloggyException e) { ... }
public class Person implements Persistable, Nameable { ... public String getRecordStoreName() { return "NOSREP"; } }
Person person = ... try { PersistableManager pm = PersistableManager.getInstance(); // Delete the object. pm.delete(person); } catch (FloggyException e) { ... }
try { PersistableManager pm = PersistableManager.getInstance(); // Delete all objects based on its class. pm.deleteAll(Person.class); } catch (FloggyException e) { ... }
try { PersistableManager pm = PersistableManager.getInstance(); // Delete all objetcs. pm.deleteAll(); } catch (FloggyException e) { ... }
PersistableManager pm = PersistableManager.getInstance(); ObjectSet persons = pm.find(Person.class, null, null); for (int i = 0; i < persons.size(); i++) { Person p = (Person) persons.get(i); ... }
PersistableManager pm = PersistableManager.getInstance(); Person person = new Person(); ObjectSet persons = pm.find(Person.class, null, null); for (int i = 0; i < persons.size(); i++) { /* The same instance is used to load the data. This avoid * the creation of persons.size()-1 objects. */ persons.get(i, person); // Don't use the person reference outside the loop, only its data. //BAD list.add(person); //GOOD list.add(person.getName()); ... }
PersistableManager pm = PersistableManager.getInstance(); // Filtering persons by gender ObjectSet persons = pm.find(Person.class, new MaleFilter(), null); for (int i = 0; i < persons.size(); i++) { Person p = (Person) persons.get(i); ... } ... public class MaleFilter implements net.sourceforge.floggy.persistence.Filter { public boolean matches(Persistable persistable) { Person p = (Person) persistable; return p.getGender() == 'M'; } }
PersistableManager pm = PersistableManager.getInstance(); // Sorting persons by age (younger first) ObjectSet persons = pm.find(Person.class, null, new AgeCompator()); ... public class AgeComparator implements net.sourceforge.floggy.persistence.Comparator { public int compare(Persistable o1, Persistable o2) { Person p1 = (Person) o1; Person p2 = (Person) o2; if (p1.getBirthday().getTime() < p2.getBirthday().getTime()) { return PRECEDES; } if (p1.getBirthday().getTime() > p2.getBirthday().getTime()) { return FOLLOWS; } return EQUIVALENT; } }
Person person = new Person(); try { PersistableManager pm = PersistableManager.getInstance(); // Checks if the object is persisted. This will return false boolean persisted = pm.isPersisted(person); // To load an object, use the object ID // generated previously by a save() operation. pm.load(person, id); //This will return true persisted = pm.isPersisted(person); } catch (FloggyException e) { ... }
Person person = new Person(); try { PersistableManager pm = PersistableManager.getInstance(); // Gets the object id. This will return -1 int id = pm.getId(person); // saving the object pm.save(person); //This will return a value greater than 0 id = pm.getId(person); } catch (FloggyException e) { ... }
First of all, you must create a floggy.xml file containing the following definitions:
<?xml version="1.0" encoding="UTF-8"?> <floggy xmlns:tns="http://floggy.sourceforge.net/floggy-persistence-1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://floggy.sourceforge.net/floggy-persistence-1.4.0 http://floggy.sourceforge.net/schema/floggy-persistence-1.4.0.xsd" generate-source="true"> <persistables> <persistable class-name="net.sourceforge.floggy.persistence.Person" record-store-name="Person"> <indexes> <index name="byName"> <field>name</field> </index> </indexes> </persistable> </persistables> </floggy>
This XML instance refer to a class called "Person" that contains a field named "name" that is configured as an index to our Person persistable class. You have to add the parameter configurationFile pointing to the file above.
Person person = new Person(); person.setName("Floggy"); try { PersistableManager pm = PersistableManager.getInstance(); // saving the object pm.save(person); IndexFilter indexFilter = new IndexFilter("byName", "Floggy"); ObjectSet os = manager.find(Person.class, indexFilter, false); } catch (FloggyException e) { ... }
Person person = new Person(); person.setName("Floggy"); PersistableManager pm = PersistableManager.getInstance(); try { // turn on the store of indexes after a save operations pm.setProperty(PersistableManager.STORE_INDEX_AFTER_SAVE_OPERATION, Boolean.TRUE); // saving the objects pm.save(person); } catch (FloggyException e) { ... }
The release 1.4.0 brought a new feature that enable the devoloper to change the persistence strategy for objects hierarchy. There are three types supported:
import net.sourceforge.floggy.persistence.Persistable; import net.sourceforge.floggy.persistence.strategy.PerClassStrategy; public class Person implements Persistable, PerClassStrategy { private String name; private Date birthday; ... } ... import net.sourceforge.floggy.persistence.Persistable; public class Employee extends Person { protected long employeeId; ... } ... import net.sourceforge.floggy.persistence.Persistable; public class Customer extends Person { protected long favoriteProductId; ... }
For the usecase above Floggy will end up with two RecordStores one called Employee and another Customer. Employee will contain the data for name, birthday and employeeId. Customer will contain the data for name, birthday and favoriteProductId.
import net.sourceforge.floggy.persistence.Persistable; import net.sourceforge.floggy.persistence.strategy.SingleStrategy; public class Person implements Persistable, SingleStrategy { private String name; private Date birthday; ... } ... import net.sourceforge.floggy.persistence.Persistable; public class Employee extends Person { protected long employeeId; ... } ... import net.sourceforge.floggy.persistence.Persistable; public class Customer extends Person { protected long favoriteProductId; ... }
For the usecase above Floggy will end up with only one RecordStore called Person. All the object for Employee and Customer will be save on the same RecordStore.
import net.sourceforge.floggy.persistence.Persistable; import net.sourceforge.floggy.persistence.strategy.SingleStrategy; public class Person implements Persistable, JoinedStrategy { private String name; private Date birthday; ... } ... import net.sourceforge.floggy.persistence.Persistable; public class Employee extends Person { protected long employeeId; ... } ... import net.sourceforge.floggy.persistence.Persistable; public class Customer extends Person { protected long favoriteProductId; ... }
For the usecase above Floggy will end up with three RecordStores, called Person, Employee and Customer. Person will contain the data for name and birthday. Employee will contain the data for an entry on Person RecordStore and for employeeId. Customer will contain the data for an entry on Person RecordStore and for favoriteProductId.
If you need to open a shared Record Store you can configure the floggy.xml file with the information about it. Keep in mind that both application must use the exactly same Persistable classes
<?xml version="1.0" encoding="UTF-8"?> <floggy xmlns:tns="http://floggy.sourceforge.net/floggy-persistence-1.4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://floggy.sourceforge.net/floggy-persistence-1.4.0 http://floggy.sourceforge.net/schema/floggy-persistence-1.4.0.xsd" generate-source="true"> <persistables> <persistable class-name="net.sourceforge.floggy.persistence.Person" record-store-name="Person" suite-name="BarbecueCalculator" vendor-name="Floggy" /> </persistables> </floggy>
PersistableManager pm = PersistableManager.getInstance(); try { // turn on the batch operation pm.setProperty(PersistableManager.BATCH_MODE, Boolean.TRUE); // Run the heavy load/save operation myLoadSaveHeavyOperation(); } catch (FloggyException e) { ... } finally { // turn off the batch operation pm.setProperty(PersistableManager.BATCH_MODE, Boolean.FALSE); }