虽然Containers(容器)是用于存储和管理XML文档的机制,但我们可以使用XmlManager对象来创建和打开XmlContainer对象。 因此,我们从XmlManager开始。
XmlManager是一个高级类,用于管理在BDB XML应用程序中使用的许多对象。
以下是我们可以使用XmlManager对象执行的一些操作:
因为XmlManager是构建重要BDB XML对象的唯一方法,所以它是BDB XML应用程序的核心。
在您实例化XmlManager对象之前,您必须对Berkeley DB环境做出一些决定。 BDB XML要求您使用数据库环境。您可以显式使用环境,也可以允许XmlManager构造函数为您管理环境。
如果明确创建环境,则可以打开BDB XML中的重要功能,例如日志记录,事务支持以及对多线程和多进程应用程序的支持。它还为您提供磁盘上的位置来存储您的所有应用程序的容器。
如果允许XmlManager构造函数为您隐式创建和/或打开环境,则仅将环境配置为允许多线程共享环境和基础数据库(使用DB_PRIVATE)。环境未启用所有其他功能。
接下来的几节将介绍为了明确创建和打开环境而需要了解的内容。我们首先从这个活动开始,因为除了最简单的BDB XML应用程序之外,它可能是你将要做的第一件事。
要使用环境,必须先打开它。 执行此操作时,您可以选择指定一系列配置属性。 这些具有启用重要子系统(例如事务支持)的效果。
有很多环境配置属性,这些属性在Berkeley DB文档中有所描述。 但是,您可能希望将其与BDB XML应用程序一起使用,因此我们在此处对其进行描述:
请记住,在BDB XML容器下使用Berkeley DB数据库,因此如果您希望容器可以被多个线程和/或多个进程访问,那么您应该启用此子系统。
我们讨论在Berkeley DB XML Getting Started with Transaction
Processing指南中编写事务应用程序。
只有在打开日志记录子系统时才能运行恢复。 此外,恢复只能由单个控制线程运行; 通常,在执行任何其他数据库操作之前,它由应用程序的主线程运行。
无论您决定在创建时设置哪些属性,在所有后续环境打开时使用相同的属性都很重要(例外情况是EnvironmentConfig.setAllowCreate(),只需创建环境)。 特别是,请避免使用属性来打开创建时未使用的环境。 这是因为不同的子系统在磁盘上需要不同的数据结构,因此尝试使用在首次创建环境时未初始化的子系统是非法的。
要使用环境,必须先打开它。 在打开时,您必须确定它所在的目录,并且该目录必须在打开尝试之前存在。 在开放时,您还可以指定要用于您的环境的open(如果有)。
完成环境后,必须确保它已关闭。 您可以显式执行此操作,也可以让XmlManager对象为您执行此操作。
如果要明确关闭环境,则必须确保在关闭环境之前已关闭环境中打开的所有容器。 此外,在这种情况下,为确保应用程序关闭您的环境,您应该在应用程序的顶级try块的finally块中执行此活动。
package dbxml.gettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.dbxml.XmlException;
import java.io.File;
class doDbXml {
public static void main(String args[]) throws Throwable {
Environment myEnv = null;
File envHome = new File("/export1/testEnv");
// Open an XmlManager
try {
//创建一个环境对象配置
EnvironmentConfig envConf = new EnvironmentConfig();
//添加环境对象配置属性
// 如果环境不存在就创建它
envConf.setAllowCreate(true);
//打开共享缓存
envConf.setInitializeCache(true);
//打开锁系统
envConf.setInitializeLocking(true);
//打开日志系统
envConf.setInitializeLogging(true);
//打开事务系统
envConf.setTransactional(true);
//设置自定义异常处理
MyErrorHandler meh = new MyErrorHandler();
envConf.setErrorHandler(meh);
//初始化环境
myEnv = new Environment(envHome, envConf);
} catch (XmlException e) {
// Error handling goes here
}finally {
//如果数据库环境不为空
if(myEnv!=null){
try {
//尝试关闭数据库环境
myEnv.close();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
}
}
我们可以通过调用其构造函数来创建XmlManager对象。 您通过调用其close()方法来销毁XmlManager对象。
请注意,关闭XmlManager并在关闭对象的最后一个打开句柄时释放其所有资源。
要构造XmlManager对象,您可能会也可能不会为构造函数提供打开的Environment对象。
如果使用打开的环境句柄实例化XmlManager,那么如果将XmlManagerConfig ::
setAdoptEnvironment()设置为true,XmlManager将关闭并销毁该Environment对象。
如果为构造函数提供Environment对象,则可以使用该对象来使用应用程序可能需要的任何子系统
如果您不提供环境对象,则XmlManager将隐式为您创建环境。
在这种情况下,环境将不会配置为使用任何子系统,并且只能由同一进程内的多个线程共享。此外,在这种情况下,您可以使用以下机制之一选择性地标识容器所在的磁盘位置:
在任何一种情况下,您都可以向XmlManager构造函数传递一个XmlManagerConfig对象,该对象控制该对象关于底层容器的行为(该属性不会直接传递给底层环境或数据库)。 配置方法是:
package dbxml.gettingStarted;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
class doDbXml {
public static void main(String args[]) throws Throwable {
XmlManager myManager = null;
try {
myManager = new XmlManager();
} catch (XmlException e) {
// Exception handling goes here
} finally {
try {
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}
package dbxml.gettingStarted;
import com.sleepycat.db.DatabaseException;
import com.sleepycat.db.Environment;
import com.sleepycat.db.EnvironmentConfig;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
import com.sleepycat.dbxml.XmlManagerConfig;
import java.io.File;
class doDbXml {
public static void main(String args[]) throws Throwable {
Environment myEnv = null;
File envHome = new File("/export1/testEnv");
// Open an XmlManager
XmlManager myManager=null;
try {
//创建一个环境对象配置
EnvironmentConfig envConf = new EnvironmentConfig();
//添加环境对象配置属性
// 如果环境不存在就创建它
envConf.setAllowCreate(true);
//打开共享缓存
envConf.setInitializeCache(true);
//打开锁系统
envConf.setInitializeLocking(true);
//打开日志系统
envConf.setInitializeLogging(true);
//打开事务系统
envConf.setTransactional(true);
//设置自定义异常处理
MyErrorHandler meh = new MyErrorHandler();
envConf.setErrorHandler(meh);
//初始化环境
myEnv = new Environment(envHome, envConf);
XmlManagerConfig managerConfig = new XmlManagerConfig();
managerConfig.setAdoptEnvironment(true);
myManager = new XmlManager(myEnv, managerConfig);
} catch (XmlException e) {
// Error handling goes here
}finally {
if(myManager!=null){
try {
myManager.close();
} catch (XmlException e) {
e.printStackTrace();
}
}
}
}
}
在BDB XML中,我们将XML文档存储在容器中。 容器是磁盘上的文件,其中包含与文档关联的所有数据,包括元数据和索引。
要创建和打开容器,请使用XmlManager.createContainer()
。 创建容器后,您不能再次使用createContainer()
相反,只需使用以下命令打开它:XmlManager.openContainer()
请注意,我们可以使用XmlManager.existsContainer()
方法测试容器是否存在。 此方法应在封闭容器上使用。 如果指定的文件不是BDB XML容器,则返回0。 否则,它返回基础数据库格式编号。
或者,我们可以通过调用openContainer()
来创建和打开容器,并将其传递给必要的属性以允许创建容器.
您可以多次打开容器。 每次打开容器时,都会收到该容器的引用计数句柄。
我们通过调用
XmlContainer.close()
关闭容器。 请注意,在关闭容器的最后一个句柄之前,容器实际上并未关闭。
package dbxml.gettingStarted;
import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
import java.io.FileNotFoundException;
public class doDbXml{
public static void main(String args[]){
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
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (myContainer != null) {
myContainer.close();
}
if (myContainer2 != null) {
myContainer2.close();
}
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}
创建或打开容器时,可以指定大量属性来控制容器行为的各个方面。 以下是BDB XML应用程序常用的属性。
XmlManager.createContainer()
时指定此属性。 此外,您需要为XmlManager.openContainer()
指定它。 仅当尚未创建容器时。XmlManager.createContainer()
时指定此属性。 请注意,除非同时使用XmlContainerConfig.setAllowCreate()
,否则此属性无意义。在创建时,每个容器都必须具有为其定义的类型。 此容器类型标识XML文档如何存储在容器中。 因此,容器类型只能在容器创建时确定; 您无法在后续容器打开时更改它。
容器可以为它们指定以下类型之一:
XmlContainerConfig.setNodeContainer()
设置为false。XmlContainerConfig.setNodeContainer()
设置为true。请注意,
NodeContainer
的查询速度通常比WholedocContainer
快。
另一方面,与NodeContainer
相比,WholedocContainer
为容器提供了更快的文档加载时间,因为BDB XML不必将文档解构为其各自的叶节点。 出于同样的原因,出于同样的原因,WholedocContainer更快地检索整个文档 -文档不必重新组装。
因此,除非满足下列条件之一,否则应使用NodeContainer
:
NodeContainer
提供的查询优势可以忽略不计或完全消失。 达到此阈值的大小当然取决于应用程序可用的物理资源(内存,CPU,磁盘速度等)。请注意,如果我们的文档大小超过兆字节,则应避免使用WholedocContainer
。 WholedocContainer
针对小型文档进行了调整,随着文档量的增大,您将承担越来越多的性能损失。
package dbxml.gettingStarted;
import com.sleepycat.dbxml.XmlContainer;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
import java.io.FileNotFoundException;
public class doDbXml {
public static void main(String args[]){
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
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (myContainer != null) {
myContainer.close();
}
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}
您可以使用XmlManager.removeContainer()删除容器。 尝试删除打开的容器是错误的。
您可以使用XmlManager.renameContainer()重命名容器。 尝试重命名打开的容器是错误的。
package dbxml.gettingStarted;
import com.sleepycat.dbxml.XmlException;
import com.sleepycat.dbxml.XmlManager;
import java.io.FileNotFoundException;
public class doDbXml2 {
public static void main(String args[]){
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
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (myManager != null) {
myManager.close();
}
} catch (XmlException ce) {
// Exception handling goes here
}
}
}
}