258 lines
8.3 KiB
Java
258 lines
8.3 KiB
Java
/*-
|
||
* Copyright (C) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
|
||
*
|
||
* This file was distributed by Oracle as part of a version of Oracle Berkeley
|
||
* DB Java Edition made available at:
|
||
*
|
||
* http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html
|
||
*
|
||
* Please see the LICENSE file included in the top-level directory of the
|
||
* appropriate version of Oracle Berkeley DB Java Edition for a copy of the
|
||
* license and additional information.
|
||
*/
|
||
|
||
package persist;
|
||
|
||
import java.io.File;
|
||
import java.util.HashSet;
|
||
import java.util.Set;
|
||
|
||
import com.sleepycat.je.DatabaseException;
|
||
import com.sleepycat.je.Environment;
|
||
import com.sleepycat.je.EnvironmentConfig;
|
||
import com.sleepycat.persist.EntityCursor;
|
||
import com.sleepycat.persist.EntityIndex;
|
||
import com.sleepycat.persist.EntityStore;
|
||
import com.sleepycat.persist.PrimaryIndex;
|
||
import com.sleepycat.persist.SecondaryIndex;
|
||
import com.sleepycat.persist.StoreConfig;
|
||
import com.sleepycat.persist.model.Entity;
|
||
import com.sleepycat.persist.model.Persistent;
|
||
import com.sleepycat.persist.model.PrimaryKey;
|
||
import com.sleepycat.persist.model.SecondaryKey;
|
||
import static com.sleepycat.persist.model.DeleteAction.NULLIFY;
|
||
import static com.sleepycat.persist.model.Relationship.ONE_TO_ONE;
|
||
import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY;
|
||
import static com.sleepycat.persist.model.Relationship.MANY_TO_ONE;
|
||
import static com.sleepycat.persist.model.Relationship.MANY_TO_MANY;
|
||
|
||
public class PersonExample {
|
||
|
||
/* An entity class. */
|
||
@Entity
|
||
static class Person {
|
||
|
||
@PrimaryKey
|
||
String ssn;
|
||
|
||
String name;
|
||
Address address;
|
||
|
||
@SecondaryKey(relate=MANY_TO_ONE, relatedEntity=Person.class)
|
||
String parentSsn;
|
||
|
||
@SecondaryKey(relate=ONE_TO_MANY)
|
||
Set<String> emailAddresses = new HashSet<String>();
|
||
|
||
@SecondaryKey(relate=MANY_TO_MANY,
|
||
relatedEntity=Employer.class,
|
||
onRelatedEntityDelete=NULLIFY)
|
||
Set<Long> employerIds = new HashSet<Long>();
|
||
|
||
Person(String name, String ssn, String parentSsn) {
|
||
this.name = name;
|
||
this.ssn = ssn;
|
||
this.parentSsn = parentSsn;
|
||
}
|
||
|
||
private Person() {} // For deserialization
|
||
}
|
||
|
||
/* Another entity class. */
|
||
@Entity
|
||
static class Employer {
|
||
|
||
@PrimaryKey(sequence="ID")
|
||
long id;
|
||
|
||
@SecondaryKey(relate=ONE_TO_ONE)
|
||
String name;
|
||
|
||
Address address;
|
||
|
||
Employer(String name) {
|
||
this.name = name;
|
||
}
|
||
|
||
private Employer() {} // For deserialization
|
||
}
|
||
|
||
/* A persistent class used in other classes. */
|
||
@Persistent
|
||
static class Address {
|
||
String street;
|
||
String city;
|
||
String state;
|
||
int zipCode;
|
||
private Address() {} // For deserialization
|
||
}
|
||
|
||
/* The data accessor class for the entity model. */
|
||
static class PersonAccessor {
|
||
|
||
/* Person accessors */
|
||
PrimaryIndex<String,Person> personBySsn;
|
||
SecondaryIndex<String,String,Person> personByParentSsn;
|
||
SecondaryIndex<String,String,Person> personByEmailAddresses;
|
||
SecondaryIndex<Long,String,Person> personByEmployerIds;
|
||
|
||
/* Employer accessors */
|
||
PrimaryIndex<Long,Employer> employerById;
|
||
SecondaryIndex<String,Long,Employer> employerByName;
|
||
|
||
/* Opens all primary and secondary indices. */
|
||
public PersonAccessor(EntityStore store)
|
||
throws DatabaseException {
|
||
|
||
personBySsn = store.getPrimaryIndex(
|
||
String.class, Person.class);
|
||
|
||
personByParentSsn = store.getSecondaryIndex(
|
||
personBySsn, String.class, "parentSsn");
|
||
|
||
personByEmailAddresses = store.getSecondaryIndex(
|
||
personBySsn, String.class, "emailAddresses");
|
||
|
||
personByEmployerIds = store.getSecondaryIndex(
|
||
personBySsn, Long.class, "employerIds");
|
||
|
||
employerById = store.getPrimaryIndex(
|
||
Long.class, Employer.class);
|
||
|
||
employerByName = store.getSecondaryIndex(
|
||
employerById, String.class, "name");
|
||
}
|
||
}
|
||
|
||
public static void main(String[] args)
|
||
throws DatabaseException {
|
||
|
||
if (args.length != 2 || !"-h".equals(args[0])) {
|
||
System.err.println
|
||
("Usage: java " + PersonExample.class.getName() +
|
||
" -h <envHome>");
|
||
System.exit(2);
|
||
}
|
||
PersonExample example = new PersonExample(new File(args[1]));
|
||
example.run();
|
||
example.close();
|
||
}
|
||
|
||
private Environment env;
|
||
private EntityStore store;
|
||
private PersonAccessor dao;
|
||
|
||
private PersonExample(File envHome)
|
||
throws DatabaseException {
|
||
|
||
/* Open a transactional Berkeley DB engine environment. */
|
||
EnvironmentConfig envConfig = new EnvironmentConfig();
|
||
envConfig.setAllowCreate(true);
|
||
envConfig.setTransactional(true);
|
||
env = new Environment(envHome, envConfig);
|
||
|
||
/* Open a transactional entity store. */
|
||
StoreConfig storeConfig = new StoreConfig();
|
||
storeConfig.setAllowCreate(true);
|
||
storeConfig.setTransactional(true);
|
||
store = new EntityStore(env, "PersonStore", storeConfig);
|
||
|
||
/* Initialize the data access object. */
|
||
dao = new PersonAccessor(store);
|
||
}
|
||
|
||
private void run()
|
||
throws DatabaseException {
|
||
|
||
/*
|
||
* Add a parent and two children using the Person primary index.
|
||
* Specifying a non-null parentSsn adds the child Person to the
|
||
* sub-index of children for that parent key.
|
||
*/
|
||
dao.personBySsn.put
|
||
(new Person("Bob Smith", "111-11-1111", null));
|
||
dao.personBySsn.put
|
||
(new Person("Mary Smith", "333-33-3333", "111-11-1111"));
|
||
dao.personBySsn.put
|
||
(new Person("Jack Smith", "222-22-2222", "111-11-1111"));
|
||
|
||
/* Print the children of a parent using a sub-index and a cursor. */
|
||
EntityCursor<Person> children =
|
||
dao.personByParentSsn.subIndex("111-11-1111").entities();
|
||
try {
|
||
for (Person child : children) {
|
||
System.out.println(child.ssn + ' ' + child.name);
|
||
}
|
||
} finally {
|
||
children.close();
|
||
}
|
||
|
||
/* Get Bob by primary key using the primary index. */
|
||
Person bob = dao.personBySsn.get("111-11-1111");
|
||
assert bob != null;
|
||
|
||
/*
|
||
* Create two employers if they do not already exist. Their primary
|
||
* keys are assigned from a sequence.
|
||
*/
|
||
Employer gizmoInc = dao.employerByName.get("Gizmo Inc");
|
||
if (gizmoInc == null) {
|
||
gizmoInc = new Employer("Gizmo Inc");
|
||
dao.employerById.put(gizmoInc);
|
||
}
|
||
Employer gadgetInc = dao.employerByName.get("Gadget Inc");
|
||
if (gadgetInc == null) {
|
||
gadgetInc = new Employer("Gadget Inc");
|
||
dao.employerById.put(gadgetInc);
|
||
}
|
||
|
||
/* Bob has two jobs and two email addresses. */
|
||
bob.employerIds.add(gizmoInc.id);
|
||
bob.employerIds.add(gadgetInc.id);
|
||
bob.emailAddresses.add("bob@bob.com");
|
||
bob.emailAddresses.add("bob@gmail.com");
|
||
|
||
/* Update Bob's record. */
|
||
dao.personBySsn.put(bob);
|
||
|
||
/* Bob can now be found by both email addresses. */
|
||
bob = dao.personByEmailAddresses.get("bob@bob.com");
|
||
assert bob != null;
|
||
bob = dao.personByEmailAddresses.get("bob@gmail.com");
|
||
assert bob != null;
|
||
|
||
/* Bob can also be found as an employee of both employers. */
|
||
EntityIndex<String,Person> employees;
|
||
employees = dao.personByEmployerIds.subIndex(gizmoInc.id);
|
||
assert employees.contains("111-11-1111");
|
||
employees = dao.personByEmployerIds.subIndex(gadgetInc.id);
|
||
assert employees.contains("111-11-1111");
|
||
|
||
/*
|
||
* When an employer is deleted, the onRelatedEntityDelete=NULLIFY for
|
||
* the employerIds key causes the deleted ID to be removed from Bob's
|
||
* employerIds.
|
||
*/
|
||
dao.employerById.delete(gizmoInc.id);
|
||
bob = dao.personBySsn.get("111-11-1111");
|
||
assert bob != null;
|
||
assert !bob.employerIds.contains(gizmoInc.id);
|
||
}
|
||
|
||
private void close()
|
||
throws DatabaseException {
|
||
|
||
store.close();
|
||
env.close();
|
||
}
|
||
}
|