當時設計mq(消息服務中間件)時,我們要確保每條消息能夠可靠的發送到消費端,不管是網絡掉線,還是mq服務器掛了。如果出現這些情況,我們會把未發出去的消息存放到數據庫中,當網絡通的時候,在把爲發送的消息通過線程發送出去,確保每條消息能可靠的發送出去。特別針對走秀的促銷系統,這個是非常重要,所以我們當時選擇了je。
一、 簡介
Berkeley DB Java Edition (JE)是一個完全用JAVA寫的,它適合於管理海量的,簡單的數據。
它是是一個高性能的,嵌入數據庫編程庫,和C語言,C++,Java,Perl,Python,PHP,Tcl以及其他很多語言都有綁定。Berkeley DB可以保存任意類型的鍵/值對,而且可以爲一個鍵保存多個數據。Berkeley DB可以支持數千的併發線程同時操作數據庫,支持最大256TB的數據,廣泛
用於各種操作系統包括大多數Unix類操作系統和Windows操作系統以及實時操作系統
l 能夠高效率的處理1到1百萬條記錄,制約JE數據庫的往往是硬件系統,而不是JE本身。
l 多線程支持,JE使用超時的方式來處理線程間的死瑣問題。
l Database都採用簡單的key/value對應的形式。
l 事務支持。
l 允許創建二級庫。這樣我們就可以方便的使用一級key,二級key來訪問我們的數據。
l 支持RAM緩衝,這樣就能減少頻繁的IO操作。
l 支持日誌。
l 數據備份和恢復。
l 遊標支持
二、 獲取JE
JE下載地址:
選擇java版的,http://download.oracle.com/otn/berkeley-db/je-5.0.34.zip
相關幫助文檔可以參考 JE_HOME/docs/index.html
源代碼見JE_HOME/src/*.*
增加對象到數據庫中,代碼如下
package com.xiu.je;
import java.io.File;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.ClassCatalog;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.OperationStatus;
import com.xiu.je.bean.User;
/**
*
* JE數據庫的一般步驟 1.創建數據庫環境environment 2.打開數據庫 3.操作數據庫
4.關閉數據庫及環境。
* JE 數據庫的crud
* @author user
*
*/
public class JEaddObject {
// Environment對象,由EnvironmentConfig對象創建
private Environment env;
// 打開數據庫,由env打開
private Database db,classDB;
private ClassCatalog classCatalog;
public JEaddObject() {
}
/**
* 創建環境對象
*
* @param path
* @param cacheSize
*/
public void setUp(String path, longcacheSize) {
// 創建一個EnvironmentConfig配置對象
EnvironmentConfig envConfig = newEnvironmentConfig();
envConfig.setAllowCreate(true); // 允許創建一個數據庫環境
envConfig.setCacheSize(cacheSize);// 設置數據庫緩存大小
// 使用一個指定路徑和一個EnvironmentConfig配置對象創建Environment環境
env = new Environment(newFile(path), envConfig);
}
/**
* 打開數據庫
*
* @param dbName
*/
public void open(String dbName) {
// 創建數據庫配置
DatabaseConfig dbConfig = newDatabaseConfig();
dbConfig.setAllowCreate(true);// 允許創建數據庫
db = env.openDatabase(null, dbName,dbConfig); // 打開數據庫dbName
classCatalog = newStoredClassCatalog(env.openDatabase(null, "classDB",
dbConfig));
}
/**
* 關閉鏈接
*/
public void close() {
if (db != null) {
db.close();
}
if (env != null) {
env.close();
}
}
/**
* 存數據(參數爲object類型)
*
* @param key
* @param value
* @return
* @throws Exception
*/
public boolean put(String key, Objectvalue) throws Exception {
DatabaseEntry theKey = newDatabaseEntry(key.getBytes("utf-8"));
User user = newUser("je...");
EntryBinding dataBinding = newSerialBinding(classCatalog, User.class);
DatabaseEntry dataEntry = newDatabaseEntry();
dataBinding.objectToEntry(user,dataEntry);
OperationStatus status =db.put(null, theKey, dataEntry);
if (status ==OperationStatus.SUCCESS) {
return true;
}
return false;
}
public static void main(String[] args)throws Exception {
JEaddObject je = new JEaddObject();
je.setUp("c://je",1000000);
je.open("myDB");
System.out.println("開始向Berkeley DB中讀取數據.....");
}
}
簡單類型的CRUD
package com.xiu.je;
import java.io.File;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
/**
*
* JE數據庫的一般步驟
* 1.創建數據庫環境environment
* 2.打開數據庫
* 3.操作數據庫
* 4.關閉數據庫及環境。
*
* JE 數據庫的crud
*
* @author user
*
*/
public class TestJECRUD {
// Environment對象,由EnvironmentConfig對象創建
private Environment env;
// 打開數據庫,由env打開
private Database db;
public TestJECRUD() {
}
/**
* 創建環境對象
*
* @param path
* @param cacheSize
*/
public void setUp(String path, longcacheSize) {
// 創建一個EnvironmentConfig配置對象
EnvironmentConfig envConfig = newEnvironmentConfig();
envConfig.setAllowCreate(true); // 允許創建一個數據庫環境
envConfig.setCacheSize(cacheSize);// 設置數據庫緩存大小
// 使用一個指定路徑和一個EnvironmentConfig配置對象創建Environment環境
env = new Environment(newFile(path), envConfig);
}
/**
* 打開數據庫
*
* @param dbName
*/
public void open(String dbName) {
// 創建數據庫配置
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);// 允許創建數據庫
db = env.openDatabase(null, dbName,dbConfig); // 打開數據庫dbName
}
/**
* 關閉鏈接
*/
public void close() {
if (db != null) {
db.close();
}
if (env != null) {
env.close();
}
}
/**
* 根據key取數據
*
* @param key
* @return
* @throws Exception
*/
public String get(String key) throwsException {
DatabaseEntry queryKey = newDatabaseEntry(); // 查詢的key
DatabaseEntry value = newDatabaseEntry(); // value
queryKey.setData(key.getBytes("utf-8"));
OperationStatus status = db
.get(null, queryKey, value,LockMode.DEFAULT);
if (status ==OperationStatus.SUCCESS) {
return newString(value.getData());
}
return null;
}
/**
* 存數據
*
* @param key
* @param value
* @return
* @throws Exception
*/
public boolean put(String key, Stringvalue) throws Exception {
byte[] theKey =key.getBytes("utf-8");
byte[] theValue =value.getBytes("utf-8");
OperationStatus status =db.put(null, new DatabaseEntry(theKey),
new DatabaseEntry(theValue));
if (status == status.SUCCESS) {
return true;
}
return false;
}
/**
* 刪除數據
* @param key
* @return
* @throws Exception
*/
public boolean delete(String key)throws Exception{
byte[] theKey = key.getBytes("utf-8");
OperationStatus status =db.delete(null, new DatabaseEntry(theKey));
if(status==OperationStatus.SUCCESS){
return true;
}
return false;
}
/**
* 修改數據
* @param key
* @param value
* @return
* @throws Exception
*/
public boolean update(String key,String value) throws Exception {
byte[] updateKey =key.getBytes("utf-8");
byte[] updateValue =value.getBytes("utf-8");
OperationStatus status =db.put(null, new DatabaseEntry(updateKey),
new DatabaseEntry(updateValue));
if (status == status.SUCCESS) {
return true;
}
return false;
}
}
測試類:
package com.xiu.je;
import junit.framework.TestCase;
public class TestJECRUDTest extends TestCase {
TestJECRUD je = null;
// 實例化對象
@Override
protected void setUp() throws Exception{
je = new TestJECRUD();
je.setUp("c://je",1000000);
je.open("myDB");
}
// 打開鏈接
public void testOpen() {
je.setUp("c://je",1000000);
je.open("myDB");
}
// 關閉鏈接
public void testClose() {
je.close();
}
// 取得數據
public void testGet() {
for (int i = 0; i < 30; i++) {
String key = "myKey" + 2* i;
String value = "myValue"+ 2 * i;
try {
String v = je.get(key);
System.out.println("["+ key + ":" + v + "]");
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 插入
public void testPut() {
for (int i = 0; i < 30; i++) {
String key = "myKey" +i;
String value = "myValue"+ i;
System.out.println("[" +key + ":" + value + "]");
try {
je.put(key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 刪除
public void testDelete() {
for (int i = 0; i < 30; i++) {
String key = "myKey" + 2* i;
String value = "myValue"+ 2 * i;
try {
je.delete(key);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 更新
public void testUpdate() {
for (int i = 0; i < 30; i++) {
String key = "myKey" + 2* i;
String value ="myValue"+2*i;
try {
je.update(key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override
protected void tearDown() throwsException {
je.close();
}
}