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 怎樣進行對象持久化呢?經過瀏覽目錄能夠發現,與傳統的 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 + "]"; } }
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(); } }
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(); } }
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(); } }
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 中文社區正在火熱成長!
學習
db4o 官方網站 。
面向對象數據庫 db4o 之旅系列:查看此係列文章完整列表。
ODMG 官方網站:瞭解 ODMG 技術。
得到產品和技術