面向對象的數據庫db4o: 安裝並使用db4o

下載和安裝db4o

db4o 全部最新的版本均可以直接在官方網站上下載,進入 db4o 的下載頁面,咱們能夠看到最新的 for Java 穩定版本,包括 JAR、源代碼、入門文檔、API 等內容的完整的打包文件只有 6 MB,db4o 還有一個對象數據庫管理工具 ObjectManager,目前版本是 1.8。java

接着在 Eclipse 中新建 Java 項目,把 db4o 對象數據庫引擎包 db4o-8.0.249.16098-all-java5.jar 導入進項目。因爲 db4o 支持多種版本的 JDK,除了 for JDK 5.0 的 db4o-8.0.249.16098-all-java5.jar 外,還有 for JDK 1.一、1.2-1.4 的 JAR 包,以適應多種環境。與 Hibernate、iBATIS SQL Maps 相比,db4o 更加天然,無需過多地引用第三方支持庫。數據庫

db4o的包結構 

db4o 怎樣進行對象持久化呢?經過瀏覽目錄能夠發現,與傳統的 RDBMS 同樣,db4o 也有本身的數據庫文件, 在 db4o 中數據庫文件的後綴名是「*.yap」。讓咱們先來了解一下 db4o 對象數據庫引擎的主要包結構:服務器

  • com.db4o
    com.db4o 包含了使用 db4o 時最常常用到的功能。兩個最重要的接口是 com.db4o.Db4o 和 com.db4o.ObjectContainer。com.db4o.Db4o 工廠是運行 db4o 的起點,這個類中的靜態方法能夠開啓數據庫文件、啓動服務器或鏈接一個已經存在的服務器,還能夠在開啓數據庫以前進行 db4o 環境配置。com.db4o.ObjectContainer 接口很重要,開發過程當中 99% 的時間都會用到它,ObjectContainer 可在單用戶模式下做爲數據庫實例,也可做爲 db4o 服務器的客戶端。每一個 ObjectContainer 實例都有本身的事務。全部的操做都有事務保證。當打開 ObjectContainer,就已經進入事務了,commit() 或 rollback() 時,下一個事務當即啓動。每一個 ObjectContainer 實例維護它本身所管理的已存儲和已實例化對象,在須要 ObjectContainer 的時候,它會一直保持開啓狀態,一旦關閉,內存中數據庫所引用的對象將被丟棄。分佈式

  • com.db4o.ext
    你也許想知道爲何在 ObjectContainer 中只能看見不多的方法,緣由以下:db4o 接口提供了兩個途徑,分別在 com.db4o 和 com.db4o.ext 包中。這樣作首先是爲了讓開發者能快速上手;其次爲了讓其餘產品能更容易的複製基本的 db4o 接口;開發者從這一點上也能看出 db4o 是至關輕量級的。每一個 com.db4o.ObjectContainer 對象也是 com.db4o.ext.ExtObjectContainer 對象。能夠轉換成 ExtObjectContainer 得到更多高級特性。ide

  • com.db4o.config
    com.db4o.config 包含了全部配置 db4o 所需的類。工具

  • com.db4o.query
    com.db4o.query 包包含了構造「原生查詢, NQ(Native Queries)」所需的 Predicate 類。NQ 是 db4o 最主要的查詢接口。性能

初始化數據庫

db4o 提供兩種運行模式,分別是本地模式和服務器模式。本地模式是指直接在程序裏打開 db4o 數據庫文件進行操做:學習

Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), "auto.yap");

而服務器模式則是客戶端經過 IP 地址、端口以及受權口令來訪問服務器:網站

服務器端:this

ObjectServer server = Db4oClientServer.openServer("auto.yap", 1212);
server.grantAccess("admin", "1");

客戶端:

// ip爲服務器的ip地址
Db4oClientServer.openClient(ip, 1212, "admin", "1");

須要注意的是db4o會自動建立數據庫文件,可是並不會建立數據庫文件目錄,好比我想建立數據庫文件"/export/db4o/auto.yap",db4o並不會自動建立"/export/db4o"目錄 ,因此建立數據庫文件時最好初始化下數據庫目錄:

private void initDBFile(String dbName) {
    File file = new File(dbName);
    if (file.exists()) {
        return;
    }
    List<File> fList = new ArrayList<File>();
    File pFile = file.getParentFile();
    while (!pFile.exists()) {
        fList.add(pFile);
	pFile = pFile.getParentFile();
    }
    for (int i = fList.size() - 1; i >= 0; i--) {
	File f = fList.get(i);
	f.mkdir();
    }
}


使用數據庫

上面介紹的兩種方式均可以獲得 ObjectContainer 實例,就目前Java EE的分佈式的應用環境來看,服務器模式更有現實意義;而本地模式更適合於單服務器應用。由於分佈式模式比較經常使用,本文在下面的例子都將採用分佈式模式。

在下面的例子中,會使用一個UserVO對象,而後介紹db4o對該對象的CRUD。

  UserVO對象

public class UserVO implements Serializable {
    private static final long serialVersionUID = -9129148024922569814L;

    private String userName;
    private String password;

    public UserVO() {}

    public UserVO(String userName, String password) {
	this.userName = userName;
	this.password = password;
    }
	
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
	this.password = password;
    }

    public String getUserName() {
	return userName;
    }

    public void setUserName(String userName) {
	this.userName = userName;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
		return true;
	}
	if (!(obj instanceof UserVO)) {
		return false;
	}
	UserVO other = (UserVO) obj;
	if (!(userName == null ? other.userName == null : userName.equals(other.userName))){
		return false;
	}
	if (!(password == null ? other.password == null : password.equals(other.password))){
		return false;
	}
	return true;
    }
	
    @Override
    public int hashCode() {
	final int prime = 31;
	int result = 17;
	result = prime * result + ((userName == null) ? 0 : userName.hashCode());
	result = prime * result + ((password == null) ? 0 : password.hashCode());
	return result;
    }

    @Override
    public String toString() {
	return "UserVO [userName=" + userName + ", password=" + password + "]";
    }
}

增長(Create)

public static void main(String[] args) {
    UserVO vo = new UserVO("admin", "1");
    // 打開數據庫,ip爲服務器ip
    ObjectContainer db = Db4oClientServer.openClient(ip, 1212, "admin", "1");
    try {
        // 存儲數據
        db.store(vo);
	// 提交事務
	db.commit();
    } catch (Exception e) {
	// 出現異常則回滾
	db.rollback();
    } finally {
	// 關閉鏈接
	db.close();
    }
}

讀取(Retrieve)

public static void main(String[] args) {
    // 打開數據庫
    ObjectContainer db = Db4oClientServer.openClient(ip, 1212, "admin", "1");
    try {
	// 構造查詢對象
	Query query = db.query();
	// 設置被約束實例
	query.constrain(UserVO.class);
	// 設置被約束實例的字段和約束條件
	query.descend("userName").constrain("admin");
	// 查詢對象
	ObjectSet<UserVO> list = query.execute();
	// do something with list
    } finally {
	// 關閉鏈接
	db.close();
    }
}

更新(Update)

public static void main(String[] args) {
    // 打開數據庫
    ObjectContainer db = Db4oClientServer.openClient(ip, 1212, "admin", "1");
    try {
	ObjectSet<UserVO> result = db.query(new Predicate<UserVO>() {
	    private static final long serialVersionUID = 1554763863522546547L;
		
	    public boolean match(UserVO vo) {
		// 匹配userName爲admin的UserVO
		return vo.getUserName().equals("admin");
	    }
	});
	if (result.size() != 1) {
	    throw new RuntimeException("size does not matched.");
	}
	UserVO vo = result.next();
	// 修改passport
	vo.setPassword("0");
	db.store(vo);
	db.commit();
    } catch (Exception e) {
	db.rollback();
    } finally {
	// 關閉鏈接
	db.close();
    }
}

刪除(Delete)

public static void main(String[] args) {
    UserVO vo = new UserVO("admin", "1");
    // 打開數據庫
    ObjectContainer db = Db4oClientServer.openClient(ip, 1212, "admin", "1");
    try {
        ObjectSet<UserVO> result = db.query(new Predicate<UserVO>() {
	    private static final long serialVersionUID = -4397123083792023957L;
		
	    public boolean match(UserVO vo) {
		// 匹配userName爲admin的UserVO
		return vo.getUserName().equals("admin");
	    }
	});
	if (result.size() != 1) {
	    throw new RuntimeException("size does not matched.");
	}
	UserVO vo = result.next();
	db.delete(vo);
	db.commit();
    } catch (Exception e) {
	db.rollback();
    } finally {
	// 關閉鏈接
	db.close();
    }
}

結論

經過本系列文章,db4o 的優點已經體現得淋漓盡致,它的添加、更新、刪除是如此的簡單,正如 db4o 的口號那樣——「僅需一行代碼就能存儲複雜結構對象,極大的下降了開發時間和成本,提供高效的性能,無需 DBA 干預」。

如本文有不詳盡之處,你們能夠參考官方的《用戶指南》,db4o 中文社區正在火熱成長!

參考資料

學習

得到產品和技術

相關文章
相關標籤/搜索