Berkeley DB Java Edition初步

0.概述
Berkeley DB是历史悠久的嵌入式数据库系统,主要应用在UNIX/LINUX操作系统上,其设计思想是简单、小巧、可靠、高性能。

1. 下载
可去[url=http://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html]官网[/url]下载,本文写作时的Java Edition(简称JE)最新版是Berkeley DB Java Edition 6.1.5。
另外,也可以用maven pom的方式来指定,这样就不用下载了(可参考上面这个地址上的链接)。
下载以后,解压后在lib目录下有个je-6.1.5.jar,加入到classpath就可以用了。Berkeley DB不需要像oracle,mysql那样先要启动数据库。因为他是嵌入式的,所以直接指定一个目录写文件就可以了。数据库文件的格式是00000000.jdb,00000001.jdb......

2. Base API
Berkeley DB读写数据库有2种API(Base API和DPL)。
先介绍第一种,Base API。
没啥好说的,看了代码就懂的。
[code="java"]
public class BaseApiTest {

public static void main(String[] args) throws Exception {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File("D:/bdbtest/"), envConfig);
DatabaseConfig dbconf = new DatabaseConfig();
dbconf.setAllowCreate(true);
dbconf.setSortedDuplicates(false);//allow update
Database db = dbEnv.openDatabase(null, "SampleDB", dbconf);
DatabaseEntry searchEntry = new DatabaseEntry();
DatabaseEntry dataValue = new DatabaseEntry("data content".getBytes("UTF-8"));
DatabaseEntry keyValue = new DatabaseEntry("key content".getBytes("UTF-8"));
db.put(null, keyValue, dataValue);//inserting an entry }
db.get(null, keyValue, searchEntry, LockMode.DEFAULT);//retrieving record
String foundData = new String(searchEntry.getData(), "UTF-8");
System.out.println(foundData);
dataValue = new DatabaseEntry("updated data content".getBytes("UTF-8"));
db.put(null, keyValue, dataValue);//updating an entry
db.delete(null, keyValue);//delete operation
db.close();
dbEnv.close();
}
}

这段代码先是创建了一个Environment,也就是数据库,指定数据写入目录为D:/bdbtest/。
然后插入一条key/value数据,key="key content", value="data content"

3.DPL
DPL(Direct Persistence Layer ),则相对Base API提供了更多的高级功能。有点类似hibernate/JPA这种了,可以直接将java bean保存到数据库。

首先定义2个java bean,Employee 和Project

@Entity(version=1)
public class Employee {
@PrimaryKey
public String empID;
public String lastname;
@SecondaryKey(relate = Relationship.MANY_TO_ONE)
public int age;
@SecondaryKey(relate = Relationship.MANY_TO_ONE)
public int sex;
@SecondaryKey(relate = Relationship.MANY_TO_MANY, relatedEntity = Project.class, onRelatedEntityDelete = DeleteAction.NULLIFY)
public Set<Long> projects;

public Employee() {
}

public Employee(String empID, String lastname, int age, int sex, Set<Long> projects) {
this.empID = empID;
this.lastname = lastname;
this.age = age;
this.sex = sex;
this.projects = projects;
}
}



@Entity(version=1)
public class Project {
public String projName;
@PrimaryKey(sequence = "ID")
public long projID;

public Project() {
}

public Project(String projName) {
this.projName = projName;
}
}


首先,@Entity类似于JPA,表示这是一个实体,或者表。
然后@PrimaryKey表示这张表的主键
@SecondaryKey先不要管。
我们通过下面这个程序测试一下。

public class DplTest {

public static void main(String[] args) throws Exception {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File("D:/bdbtest/"), envConfig);
StoreConfig stConf = new StoreConfig();
stConf.setAllowCreate(true);
EntityStore store = new EntityStore(dbEnv, "DPLSample", stConf);
PrimaryIndex<String, Employee> userIndex;
userIndex = store.getPrimaryIndex(String.class, Employee.class);
userIndex.putNoReturn(new Employee("u180", "Doe", 20, 1, null));// insert
Employee user = userIndex.get("u180");// retrieve
System.out.println("empID=" + user.empID + ",lastname="
+ user.lastname);
userIndex.putNoReturn(new Employee("u180", "Locke", 30, 2, null));// Update
userIndex.delete("u180");// delete
store.close();
dbEnv.close();
}
}

putNoReturn方法就是insert/update数据了,可以看到插入了一条u180的用户,很简单。

4. DPL高级
接下来讲一下@SecondaryKey,表示第二主键。有些字段如果需要查询的,则需要加上@SecondaryKey。
例子中Employee有一个age和sex,relate = Relationship.MANY_TO_ONE表示多个Employee的age和sex允许重复。如果改用Relationship.ONE_TO_ONE的话每个人的年龄就不能重复了,显然是不行的。
下面这句表示Employee和Project表有关联了,是多对多关系。

@SecondaryKey(relate = Relationship.MANY_TO_MANY, relatedEntity = Project.class, onRelatedEntityDelete = DeleteAction.NULLIFY)
public Set<Long> projects;


好了,测试吧。

public class DplTest2 {

public static void main(String[] args) throws Exception {
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
Environment dbEnv = new Environment(new File("D:/bdbtest/"), envConfig);
StoreConfig stConf = new StoreConfig();
stConf.setAllowCreate(true);
EntityStore store = new EntityStore(dbEnv, "DPLSample", stConf);

PrimaryIndex<String, Employee> empByID;
PrimaryIndex<Long, Project> projByID;
empByID = store.getPrimaryIndex(String.class, Employee.class);
projByID = store.getPrimaryIndex(Long.class, Project.class);
SecondaryIndex<Long, String, Employee> empsByProject;
empsByProject = store.getSecondaryIndex(empByID, Long.class, "projects");
Set<Long> projects = new HashSet<Long>();
Project proj = null;
proj = new Project("Project 1");
projByID.putNoReturn(proj);
projects.add(proj.projID);
proj = new Project("Project 2");
projByID.putNoReturn(proj);
projects.add(proj.projID);
empByID.putNoReturn(new Employee("u150", "铃木五十郎", 20, 2, projects));//insert
empByID.putNoReturn(new Employee("u144", "田中四郎", 20, 1, projects));//insert
empByID.putNoReturn(new Employee("u146", "田中六郎", 30, 2, projects));//insert
empByID.putNoReturn(new Employee("u147", "田中七郎", 20, 2, projects));//insert
empByID.putNoReturn(new Employee("u148", "田中八郎", 30, 1, projects));//insert
empByID.putNoReturn(new Employee("u149", "田中九郎", 20, 2, projects));//insert

EntityIndex<String, Employee> projs = empsByProject.subIndex(proj.projID);
EntityCursor<Employee> pcur = projs.entities();
System.out.println("----Employees----");
for (Employee user : pcur) {
System.out.println("empID=" + user.empID + ",lastname="
+ user.lastname);
}
pcur.close();
EntityCursor<Employee> emplRange = empByID.entities("e143", true, "u146", true);
System.out.println("----Employees2----");
for (Employee user : emplRange) {
System.out.println("empID=" + user.empID + ",lastname="
+ user.lastname);
}
emplRange.close();

EntityJoin<String, Employee> join = new EntityJoin<String, Employee>(empByID);

// For SecondaryIndex, the params are
// 1st - type of the secondary index
// 2nd - type of the primary key
// 3rd - type of the stored object
SecondaryIndex<Integer, String, Employee> employeeByAge = store.getSecondaryIndex(empByID, Integer.class, "age");
SecondaryIndex<Integer, String, Employee> employeeBySex = store.getSecondaryIndex(empByID, Integer.class, "sex");
//查找20岁,性别女的所有人
join.addCondition(employeeByAge, 20);
join.addCondition(employeeBySex, 2);

System.out.println("----Employees3----");
ForwardCursor<Employee> joinCursor = join.entities();
for (Employee user : joinCursor) {
System.out.println("empID=" + user.empID + ",lastname="
+ user.lastname);
}
joinCursor.close();

store.close();
dbEnv.close();
}
}


我们的测试数据是u144~u150,年龄不是20就是30,然后性别不是1就是2(代表男女),每个人做的项目都是一样的,Project 1和Project 2。

测试结果

----Employees----
empID=u144,lastname=田中四郎
empID=u146,lastname=田中六郎
empID=u147,lastname=田中七郎
empID=u148,lastname=田中八郎
empID=u149,lastname=田中九郎
empID=u150,lastname=铃木五十郎
----Employees2----
empID=u144,lastname=田中四郎
empID=u146,lastname=田中六郎
----Employees3----
empID=u147,lastname=田中七郎
empID=u149,lastname=田中九郎
empID=u150,lastname=铃木五十郎

一共3个测试用例。
第一个,empsByProject.subIndex取得了做Project 1和Project 2的所有人,没问题。
第二个,empByID.entities("e143", true, "u146", true)表示取一个范围,id在e143到u146之间的,所以结果是2条记录(u144,u146)
第三个,通过EntityJoin.addCondition()这个方法查找20岁,性别女的所有人所以结果是3条记录(u147,u149,u150)

可以看到功能还是蛮丰富的,可以范围查找,还可以多条件过滤。
附件是本文提到的源代码。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值