MapDB 中的 DB 类是提供命名映射和其他集合便捷访问的核心数据库类,它继承了 Closeable 和ConcurrencyAware 接口,是操作 MapDB 数据库的核心入口,负责管理数据库的各类集合、原子变量、事务以及资源生命周期等核心能力。
一个 DB 实例代表一个已打开的数据库(或单个事务会话)。它可用于创建和打开集合存储,还能通过诸如 commit()、rollback() 和 close() 等方法来处理数据库的生命周期。
DB 类包含大量嵌套类型,主要为各类 Maker 实现类(用于创建对应集合 / 原子变量)和辅助类,整体可分为三类,所有 Maker 均继承自抽象类 Maker<E>(核心创建器基类):
用于创建各类原子类型变量,支持原子性操作,适用于并发场景的计数、状态标识等:
AtomicBooleanMaker 创建布尔型原子变量
AtomicIntegerMaker 创建整型原子变量
AtomicLongMaker 创建长整型原子变量
AtomicStringMaker 创建字符串型原子变量
AtomicVarMaker<E> 创建泛型原子变量(Var<E>)
示例:
public static class AtomicBooleanExample {
public static void main(String[] args) {
// 使用 try-with-resources 语法创建并自动关闭数据库连接
try (DB memoryDB = DBMaker.fileDB("file.db").make()) {
// 从数据库中获取/创建一个名为 "myBool" 的原子布尔类型对象
// createOrOpen()方法:如果该键存在则打开,不存在则创建
Atomic.Boolean maker = memoryDB.atomicBoolean("myBool").createOrOpen();
// 设置原子布尔值为 true(原子操作,线程安全)
maker.set(true);
// 打印当前原子布尔值,验证设置结果
System.out.println("value=" + maker.get());
}
}
}用于创建 MapDB 支持的各类持久化 / 内存集合,是 DB 类的核心能力之一:
HashMapMaker<K, V> 创建哈希映射(HTreeMap)
HashSetMaker<E> 创建哈希集合(KeySet)
IndexTreeListMaker<E> 创建索引树列表
IndexTreeLongLongMapMaker 创建长键长值的索引树映射
TreeMapMaker<K, V> 创建树映射(BTreeMap)
TreeSetMaker<E> 创建可导航树集合(NavigableSet)
示例:
public static class HashMapExample {
public static void main(String[] args) {
try (DB memoryDB = DBMaker.fileDB("file.db").make()) {
// 构建并获取名为 "myBool" 的哈希映射(HTreeMap)对象
HTreeMap<String,String> maker = memoryDB.hashMap("myTreeMap")
// 配置键的序列化器为字符串序列化器,确保键以字符串格式存储/读取
.keySerializer(Serializer.STRING)
// 配置值的序列化器为字符串序列化器,确保值以字符串格式存储/读取
.valueSerializer(Serializer.STRING)
// 创建或打开映射:存在则打开,不存在则创建
.createOrOpen();
// 向哈希映射中存入键值对:键为"name",值为"MapDB"
maker.put("name", "MapDB");
// 根据键"name"从哈希映射中获取对应的值
String value = maker.get("name");
System.out.println("value=" + value);
}
}
}注意,构建器可以以三种不同的方法结束:
create() 将创建新集合,如果该集合已存在,则抛出异常。
open() 打开现有的集合,如果该集合不存在,则抛出异常。
createOrOpen() 如果集合存在则打开它,否则创建该集合。
事务(Transaction)是数据库操作的最小不可分割的执行单元,它将一组数据库操作(比如增删改查)打包成一个整体,要么全部成功执行,要么全部失败回滚,以此保证数据的一致性和完整性。
事务的 ACID 原则:
原子性(Atomicity):事务中的所有操作要么全做,要么全不做,不存在 “部分执行” 的情况。
一致性(Consistency):事务执行前后,数据库的完整性约束(比如账户余额不能为负)始终保持有效。
隔离性(Isolation):多个并发事务之间相互隔离,一个事务的执行不会被其他事务干扰。
持久性(Durability):事务一旦提交成功,修改的数据会永久保存到数据库,即使系统崩溃也不会丢失。
在 MapDB 中,DB 具有处理事务生命周期的方法:commit()、rollback() 和 close()。
一个 DB 对象代表一个单独的事务。
示例:
public static class TransactionExample {
public static void main(String[] args) {
// transactionEnable() 用于开启事务
try (DB db = DBMaker.fileDB("file.db").transactionEnable().make()) {
ConcurrentNavigableMap<Integer,String> map = db
.treeMap("collectionName", Serializer.INTEGER, Serializer.STRING)
.createOrOpen();
map.put(1,"one");
map.put(2,"two");
//map.keySet() 现在是 [1,2],甚至在提交之前
System.out.println(map.keySet());
db.commit(); // 将更改持久化到磁盘中
map.put(3,"three");
//map.keySet() 现在是 [1,2,3]
System.out.println(map.keySet());
db.rollback(); // 撤销最近的更改
//map.keySet() 现在是 [1,2]
System.out.println(map.keySet());
// 省略 db.close(),DB 将在 try 块结束后自动关闭
//db.close();
}
}
}用于数据库的关闭、状态检查和并发安全校验:
close(): 实现 Closeable 接口,关闭数据库并释放所有关联资源(如线程池、存储、锁);
isClosed(): 判断数据库是否已关闭;
checkNotClosed(): 校验数据库未关闭,若已关闭则抛出异常;
checkThreadSafe(): 校验所有子组件的线程安全性,若非线程安全则抛出异常;
示例:
public static class ResourceManagementExample {
public static void main(String[] args) {
// 创建 MapDB 数据库实例(启用线程安全)
DB db = DBMaker.fileDB("file.db")
.transactionEnable() // 启用事务
// 设置并发级别(线程安全)
// 值必须是 2 的幂,否则会自动向上取整
.concurrencyScale(8)
.make();
try {
// 判断数据库状态
boolean isClosed = db.isClosed();
System.out.println("数据库当前是否关闭:" + isClosed); // 输出 false
// 调用原生 checkThreadSafe() 校验线程安全性
System.out.println("开始校验线程安全性...");
db.checkThreadSafe(); // 如果是非线程安全会抛异常
System.out.println("线程安全性校验通过 ✔");
// 执行数据库操作(验证方法调用后状态正常)
HTreeMap<String, String> map = db.hashMap("rmHashMap")
.keySerializer(Serializer.STRING)
.valueSerializer(Serializer.STRING)
.createOrOpen();
map.put("key1", "value1");
System.out.println("数据库操作正常:key1 = " + map.get("key1"));
} catch (Exception e) {
e.printStackTrace();
} finally {
// 调用 close() 关闭数据库
System.out.println("关闭数据库...");
if (!db.isClosed()) {
db.close(); // 释放所有资源
System.out.println("数据库已关闭 ✔");
}
// 验证关闭后的状态
System.out.println("关闭后数据库状态:" + db.isClosed()); // 输出 true
}
}
}运行示例,输出日志:
数据库当前是否关闭:false
开始校验线程安全性...
线程安全性校验通过 ✔
数据库操作正常:key1 = value1
关闭数据库...
数据库已关闭 ✔
关闭后数据库状态:true更多关于 MapDB 的知识,请继续学习后续教程🚀