快速开始
第一步:数据库定义
使用 SmartEDB Java 本地接口(JNI)的第一步是定义您希望在 SmartEDB 数据库中管理的类。JNI 使用带有注释的 Java 类语法。在运行时,使用 Java 反射来发现带有注释的类,并构建 SmartEDB 数据库字典。一旦创建,该字典随后将由 SmartEDB 运行时使用。因此,Java 反射在首次创建或打开数据库时仅发生一次。
SDK 示例 samples/java/open/Open 展示了如何打开一个简单的内存数据库。该数据库类使用 @Persistent 注解,表明此类将由 SmartEDB 运行时进行管理。例如:
@Persistent // Class will be stored in SmartEDB database
class OpenObj
{
int i4;
};
第二步:打开数据库
SDK 示例 samples/java/open/Open 展示了如何打开一个简单的内存数据库。该示例还演示了如何通过调用 Database 方法 getRunTimeInfo() 来显示运行时信息。请构建并运行示例应用程序并查看源代码。请注意,整型变量 config 是根据命令行参数设置的:
int config;
// Get config parameters from the command line
for (String s : args)
{
if ("disk".equals(s)) config |= Database.MCO_CFG_DISK_SUPPORT;
if ("shm".equals(s)) config |= Database.MCO_CFG_SHARED_MEMORY;
if ("debug".equals(s)) config |= Database.MCO_CFG_DEBUG_LIBRARY;
if ("mvcc".equals(s)) config |= Database.MCO_CFG_MVCC_TRANSACTION_MANAGER;
if (s.startsWith("license:")) params.license_key = s.substring(8);
}
然后在“数据库”类的构造函数中使用此模式。这会动态加载适当的运行时库。实例化后,调用 GetRunTimeInfo() 方法以获取有关当前加载的运行时库的信息:
Database db;
db = new Database(config);
Database.RuntimeInfo ri = db.getRunTimeInfo();
数据库内存设备和参数被初始化,并传递给数据库的 open() 方法:
Database.Device devs[];
Database.Parameters params = new Database.Parameters();
...
params.memPageSize = PAGE_SIZE; // Memory page size
params.classes = new Class[] { OpenObj.class }; // List of classes which will be stored in SmartEDB database.
params.maxConnections = 10;
...
devs = new Database.Device[1];
...
devs[0] = new Database.PrivateMemoryDevice(Database.Device.Kind.Data, DATABASE_SIZE);
...
db.open("opendb", params, devs);
对于持久数据库,必须定义至少四个存储设备,并且在调用 Database 构造函数时必须启用 DiskSupport。有关更多详细信息,请参阅“打开持久数据库”页面。
使用 Java API 打开持久数据库
正如针对内存数据库所解释的那样,在执行数据存储和检索操作之前,我们必须打开并连接到数据库。Java 应用程序通过调用 Database 类的 open() 方法来打开数据库,该方法可以接受多个参数,包括 Database.Parameters 对象和 Database.Device 对象数组。这在 SDK 示例 samples/java/open/Open 中有演示。
若要指定数据库类存储在持久性介质上,则使用注解 @Persistent(disk=true) 声明该类,并且必须在启用 DiskSupport 的情况下调用 Database 构造函数。例如:
@Persistent(disk=true)
class Employee
{
...
}
...
Database.Mode mode = Database.MCO_CFG_DISK_SUPPORT;
Database db = new Database(mode);
定义存储设备
SmartEDB 使用逻辑设备的概念来描述存储位置。对于全内存数据库,可以使用单个设备来描述数据库的常规(也称为本地或进程内)或共享内存,但对于持久数据库或混合数据库(其中包含瞬态类和持久类),必须定义至少四个设备。例如:
static final int DATABASE_SIZE = (600 * 1024 * 10);
static final int DISK_CACHE_SIZE = (300 * 1024 * 10);
Database.Device devs[] = new Database.Device[4];
/* Configure first memory device as a plain conventional memory region */
devs[0] = new Database.PrivateMemoryDevice(Database.Device.Kind.Data, DATABASE_SIZE);
/* Configure conventional memory region for cache */
devs[1] = new Database.PrivateMemoryDevice(Database.Device.Kind.DiskCache, DISK_CACHE_SIZE);
/* Configure FILE memory device for main database storage */
devs[2] = new Database.FileDevice(Database.Device.Kind.Data, "opendb.dbs");
/* Configure FILE memory device for transaction log */
devs[3] = new Database.FileDevice(Database.Device.Kind.TransactionLog, "opendb.log");
数据库参数
数据库打开参数在类 Database.Parameters 中定义。这些参数在构造函数中初始化为默认值,然后分配以下特定于应用程序的参数:
#define MEMORY_PAGE_SIZE 128
#define PSTORAGE_PAGE_SIZE 4096
Database.Parameters params = new Database.Parameters();
/* Initialize and customize the database parameters */
params.memPageSize = MEMORY_PAGE_SIZE;
params.classes = new Class[] { OpenObj.class }; // List of classes which will be stored in SmartEDB database.
params.maxConnections = 10;
params.diskPageSize = PSTORAGE_PAGE_SIZE;
params.diskClassesByDefault = true; // Mark @Persistent classes as on-disk classes by default
数据库操作
一旦指定了持久化数据库设备和参数,数据库打开方法 open()、Connection 类以及执行数据库操作的所有其他 API 都与内存数据库的相同。有关更多实现细节,请参阅 SDK 示例 samples/java/open/Open。
第三步:数据访问操作
SDK 示例 samples/java/operations/Operations 展示了如何使用 Connection 和 Cursor 类执行基本的数据库 CRUD 操作。请构建并运行示例应用程序并查看源代码。请注意,Connection 对象 con 是在打开数据库之后实例化的:
Database db = new Database();
...
db.open("operations-db", params, DATABASE_SIZE);
Connection con = new Connection(db);
然后,使用 Connection 方法 insert() 实例化持久化的 Record 对象并将其插入数据库。请注意,所有数据库操作都在 Connection 方法 startTransaction() 和 commitTransaction() 之间执行:
con.startTransaction(Database.TransactionType.ReadWrite); // start RW transaction
rec = new Record(); // create Java object
// fill data
rec.id = i;
rec.str = "String " + i;
con.insert(rec); // Insert object into SmartEDB database
con.commitTransaction(); // Commit changes
要更新记录,需实例化一个游标对象,并使用其 update() 方法来修改对象内容:
con.startTransaction(Database.TransactionType.ReadWrite);
// Perform simple index search: locate Record by id
cursor = new Cursor<Record>(con, Record.class, "id");
// Find record to update
rec = cursor.find(2);
// Update object
rec.str = "Updated string";
cursor.update(); // Update current object (pointed by the cursor) in SmartEDB database
cursor.close(); // Release cursor
con.commitTransaction(); // commit changes