feedback / send your comments
mail to luc peuvrier
chat channel
joafip users mailing list
forums

BACK

In English

Database versus JOAFIP

Cette page est pour vous donner une idée de comment il est siple de créer une "base de données" avec JOAFIP.

Nous allong apprendre comment ouvrir, stocker, retrouver et effacer des instance de d'enregistrement dans une table persistance d'enregistrement. Dans notre exemple l'enregistrement sera de la classe Item qui a code et price comme attributs.

En fait c'est l'instance d'un modèle de données qui sera persisté.

Diagramme de classe UML pour notre modèle de données (exemple simple)

 item table
La relation de composition entre ItemTable et Item est réalisée en utilisant PTreeMap
autres collections utilisables pour les relations à cardinalités multiples

La classe Item

Une simple classe avec deux champs: code and price.

/**
 * item entity<br>
 * comparable compare item code ( the main key )
 */
public class Item implements Comparable<Item> {

    /** item code is immutable : it is the main key */
    private final String code;

    /** the item price */
    private BigDecimal price;

    public Item(final String code) {
        super();
        this.code = code;
    }

    public Item(final String code, final BigDecimal price) {
        super();
        this.code = code;
        this.price = price;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(final BigDecimal price) {
        this.price = price;
    }

    public String getCode() {
        return code;
    }

    @Override
    public int compareTo(final Item otherItem) {
        // /!\ JOAFIP persistable object rule
        // do not use code.compareTo(otherItem.code)
        // see joafip persistent pojo
    // or use joafip 3.0.0 java agent
        return code.compareTo(otherItem.getCode());
    }

    @Override
    public String toString() {
        return code + ";" + price + ";";
    }
}

La classe ItemTable

La table d'Item sera persistée.

public class ItemTable {

    /** map of {@link Item} by item code */
    private final Map<String, Item> itemByCodeMap =
    /**/new PTreeMap<String, Item>();

    /** map of {@link Item} by item price, can have multiple item for same price
     */

    private final NavigableMap<BigDecimal, Set<Item>> itemByPrice =
    /**/new PTreeMap<BigDecimal, Set<Item>>();

    public Item addItem(final Item item) {
        final Item previousItem = itemByCodeMap.put(item.getCode(), item);
        if (previousItem != item) {// NOPMD must compare object instance
            removeOfPriceMap(previousItem);
            addToPriceMap(item);
        }
        return previousItem;
    }

    public Item getItemByCode(final String itemCode) {
        return itemByCodeMap.get(itemCode);
    }

    public Collection<Item> getAllItem() {
        return itemByCodeMap.values();
    }

    public List<Item> getItemByPrice(final BigDecimal fromPrice, final BigDecimal toPrice) {
        final NavigableMap<BigDecimal, Set<Item>> subMap = itemByPrice
                .subMap(fromPrice, true/* fromInclusive */,
                        toPrice, true/* toInclusive */);

        final List<Item> list = new PLinkedList<Item>();
        for (Set<Item> set : subMap.values()) {
            list.addAll(set);
        }
        return list;
    }

    public Item removeItem(final String itemCode) {
        final Item removed = itemByCodeMap.remove(itemCode);
        removeOfPriceMap(removed);
        return removed;
    }

    private void addToPriceMap(final Item toAdd) {
        final BigDecimal price = toAdd.getPrice();
        Set<Item> set = itemByPrice.get(price);
        if (set == null) {
            set = new PTreeSet<Item>();
            itemByPrice.put(price, set);
        }
        set.add(toAdd);
    }

    private void removeOfPriceMap(final Item toRemove) {
        if (toRemove != null) {
            final BigDecimal price = toRemove.getPrice();
            final Set<Item> set = itemByPrice.get(price);
            if (set != null) {
                set.remove(toRemove);
            }
        }
    }
}

Opening the "database"

Pour accéder au fichier de stockage ou créer un nouveau gestionnaire de persistance en donnat le chemin du répertoire de stockage. La "data access session" est la façade pour gérer les objets dans le fichier de stockage.

depuis 4.0.0

/* open file persistence */
final FilePersistenceBuilder builder = new FilePersistenceBuilder();
builder.setPathName(STORAGE_DIRECTORY);
builder.setProxyMode(true);
builder.setRemoveFiles(false);
builder.setGarbageManagement(false);
builder.setCrashSafeMode(false);
final IFilePersistence filePersistence = builder.build();
    ............
/* close file persistence */
filePersistence.close();

avant 4.0.0

/* open file persistence */
final FilePersistence filePersistence =
    new FilePersistence(STORAGE_DIRECTORY, false, false);
final IDataAccessSession session = filePersistence.createDataAccessSession();
    ............
/* close file persistence */
filePersistence.close();

Ouvrir une session d'accés aux données

ouvrir une session pour des opération CRUD ( Create Read Update Delete ).

session.open();

fermeture de la session avec sauvegarde pour répliquer les changements en mémoire dans le fichier de stockage.

session.close(EnumFilePersistenceCloseAction.SAVE);

En cas d'accés en lecture seule, fermer la session sans suavegarder, cela peut être une sorte de rollback.

session.close(EnumFilePersistenceCloseAction.DO_NOT_SAVE);

Stocker un objet

stocker une instance de ItemTable

/* store new item table (empty) */
session.open();
ItemTable itemTable = new ItemTable();
session.setObject("itemTable", itemTable);
session.close(EnumFilePersistenceCloseAction.SAVE);

ajouter des instance de Item dans l'instance de ItemTable fera persister ces item

/* populate item table */
session.open();
itemTable = (ItemTable) session.getObject("itemTable");
Item item = new Item("123", 10);
itemTable.addItem(item);
item = new Item("456", 10);
itemTable.addItem(item);
item = new Item("789", 11);
itemTable.addItem(item);
session.close(EnumFilePersistenceCloseAction.SAVE);

Retrouver un objet

Joafip n'a pas de système de requête, mais ItemTable implemente ce qui est nécessaire pour retrouver un objet, tout se passe au travers des méthodes d'accès.

/* retrieve by code */
session.open();
itemTable = (ItemTable) session.getObject("itemTable");
item = itemTable.getItemByCode("456");
// _log.info("retrieved by code 456: " + item);
item = (Item) filePersistence.copy(item);// create accessible out of session deprecated in 3.0.0
item = (Item) filePersistence.deepCopy(item);// create accessible out of session
session.close(EnumFilePersistenceCloseAction.DO_NOT_SAVE);
// item is accessible out of data access session
_log.info("retrieved by code 456:" + item);

Mise à jour d'un objet

Mettre à jour consiste à retrouver l'objet, appeler une méthode de modification, et ensuite fermer la session en sauvegardant.

/* update */
session.open();
itemTable = (ItemTable) session.getObject("itemTable");
item = itemTable.getItemByCode("123");
item.setPrice(9);
session.close(EnumFilePersistenceCloseAction.SAVE);

Effacement d'un objet

Effacer est tout aussi facile que mettre à jour.

/* delete */
session.open();
itemTable = (ItemTable) session.getObject("itemTable");
item = itemTable.removeItem("456");
_log.info("deleted " + item);
session.close(EnumFilePersistenceCloseAction.SAVE);

Conclusion

Des requêtes plus complexes peuvent être ajoutées en implemantant des méthodes d'accées et modification à la classe ItemTable class.

Il est possible de créer une classe base de données composée de multiples tables. Cette classe DataBase class peut jouer le rôle de façade d'accès aux donners pour stocker, retrouver, mettre à jour, et effacer des instances. Cette façade peut implémenter un ensemble de méthodes pour des requêtes complexes, tout cela en java via navigation dans le graphe d'objet constitué des tables d'entités.

toutes les sources


feedback / send your comments
mail to luc peuvrier
chat channel
joafip users mailing list
forums

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License.
© 2007-2012, joafip