In BDB XML you store your XML Documents in containers. A container is a file on disk that contains all the data associated with your documents, including metadata and indices.
To create and open a container, you use
XmlManager.createContainer()
.
Once a container has been created, you can not use
createContainer()
on it again. Instead,
simply open it using:
XmlManager.openContainer()
.
Note that you can test for the existence of a container using the
XmlManager.existsContainer()
method. This method should be used on closed containers. It
returns 0
if the named file is not a BDB XML
container. Otherwise, it returns the underlying database format
number.
Alternatively, you can cause a container to be created and
opened by calling openContainer()
and
pass it the necessary properties to allow the container to be
created (see the following section for information on container
open properties).
You can open a container multiple times. Each time you open a container, you receive a reference-counted handle for that container.
You close a container by calling XmlContainer.close()
.
Note that the container is not actually closed until the last
handle for the container has been closed.
For example:
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlContainer; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; ... XmlManager myManager = null; XmlContainer myContainer = null; XmlContainer myContainer2 = null; try { myManager = new XmlManager(); // Open the container. If it does not currently exist, // then create it. myContainer = myManager.createContainer("/export/xml/myContainer.bdbxml"); // Obtain a second handle to the container. This container is closed // when its last handle is closed. myContainer2 = myManager.openContainer("/export/xml/myContainer.bdbxml"); } catch (XmlException e) { // Exception handling goes here } finally { try { if (myContainer != null) { myContainer.close(); } if (myContainer2 != null) { myContainer2.close(); } if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here } }
When you create or open a container, there are a large number of properties that you can specify which control various aspects of the container's behavior. The following are the properties commonly used by BDB XML applications. For a complete listing of the properties available for use, see the Javadoc.
XmlContainerConfig.setAllowCreate()
Causes the container and all underlying databases to be
created. It is not necessary to specify this
property on the call to
XmlManager.createContainer()
.
In addition, you need to specify it for
XmlManager.openContainer()
.
only if the container has not already been created.
XmlContainer.setExclusiveCreate()
Causes the container creation to fail if the container
already exists. It is not necessary to specify this
property on the call to
XmlManager.createContainer()
.
Note that this property is meaningless unless
XmlContainerConfig.setAllowCreate()
is also used.
XmlContainerConfig.setReadOnly()
The container is opened for read-access only.
XmlContainerConfig.setAllowValidation()
Causes documents to be validated when they are loaded into the container. The default behavior is to not validate documents.
XmlContainerConfig.setIndexNodes()
Determines whether indexes for the container will
return nodes (if this property is set to
On
)
or documents (if this property is set to
Off
).
Note that the default index type is determined by
the type of container you are creating. If you are
creating a container of type
NodeContainer
, then this
property is set to
On
by default. For containers of type WholedocContainer
,
this property is set to
Off
by default.
If you want to change this property on an existing container, you must re-index the container in order for the new index type to take effect.
For more information on index nodes, see Specifying Index Nodes.
XmlContainerConfig.setTransactional()
The container supports transactions. For more information, see the Berkeley DB XML Getting Started with Transaction Processing guide.
At creation time, every container must have a type defined for it. This container type identifies how XML documents are stored in the container. As such, the container type can only be determined at container creation time; you cannot change it on subsequent container opens.
Containers can have one of the following types specified for them:
Wholedoc Containers
The container contains entire documents; the documents are
stored "as is" without any manipulation of line breaks or
whitespace.
To cause the container to hold whole documents, set
XmlContainerConfig.setNodeContainer()
to false.
Node containers
XmlDocument
s are stored as individual nodes in the
container. That is, each record in the underlying database
contains a single leaf node, its attributes and attribute
values if any, and its text nodes, if any. BDB XML also
keeps the information it needs to reassemble the document
from the individual nodes stored in the underlying
databases.
This is the default, and preferred, container type.
To cause the documents to be stored as individual nodes, set
XmlContainerConfig.setNodeContainer()
to true.
Default container type.
The default container type is used. You can set the default
container type using
XmlManager.setDefaultContainerType()
.
If you never set a default container type, then the
container will use node-level storage.
Note that NodeContainer
is generally faster to
query than is WholedocContainer
.
On the other hand, WholedocContainer
provides
faster document loading times into the container than does NodeContainer
because BDB XML does not have to deconstruct the document into its
individual leaf nodes. For the same reason,
WholedocContainer
is faster at retrieving whole
documents for the same reason
— the document does not have to be reassembled.
Because of this, you should use NodeContainer
unless one of the following conditions are true:
Load performance is more important to you than is query performance.
You want to frequently retrieve the entire XML document (as opposed to just a portion of the document).
Your documents are so small in size that the query advantage
offered by NodeContainer
is negligible or
vanishes entirely. The size at which this threshold is
reached is of course dependent on the physical resources
available to your application (memory, CPU, disk speeds, and
so forth).
Note that you should avoid using WholedocContainer
if your documents tend to be greater than a megabyte in size.
WholedocContainer
is tuned for small
documents and you will pay increasingly heavy performance penalties
as your documents grow larger.
For example:
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlContainer; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; ... XmlManager myManager = null; XmlContainer myContainer = null; try { myManager = new XmlManager(); myManager.setDefaultContainerType(XmlContainer.WholedocContainer); // Create and open the container. myContainer = myManager.createContainer("/export/xml/myContainer.bdbxml"); } catch (XmlException e) { // Exception handling goes here } finally { try { if (myContainer != null) { myContainer.close(); } if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here } }
You can delete a container using
XmlManager.removeContainer()
.
It is an error to attempt to remove an open container.
You can rename a container using
XmlManager.renameContainer()
.
It is an error to attempt to rename an open container.
For example:
package dbxml.gettingStarted; import com.sleepycat.dbxml.XmlException; import com.sleepycat.dbxml.XmlManager; ... XmlManager myManager = null; try { myManager = new XmlManager(); String currentName = "/export/xml/myContainer.bdbxml"; String newName = "/export2/xml/myContainer.bdbxml"; myManager.renameContainer(currentName, newName); myManager.removeContainer(newName); } catch (XmlException e) { // Exception handling goes here } finally { try { if (myManager != null) { myManager.close(); } } catch (XmlException ce) { // Exception handling goes here } }