OrientDB API v1.0.0(OrientDB 3.x) Gitee OrientDB介紹 OrientDB是一個開源的NoSQL資料庫管理系統,同時也是一款高性能的圖資料庫,支持ACID事務以及原子操作。 官網 圖資料庫介紹 圖資料庫是以點、邊為基礎存儲單元,以高效存儲、查詢圖數據為設計 ...
OrientDB API v1.0.0(OrientDB 3.x)
OrientDB介紹
OrientDB是一個開源的NoSQL資料庫管理系統,同時也是一款高性能的圖資料庫,支持ACID事務以及原子操作。
圖資料庫介紹
圖資料庫是以點、邊為基礎存儲單元,以高效存儲、查詢圖數據為設計原理的數據管理系統。
圖概念對於圖資料庫的理解至關重要。圖是一組點和邊的集合,“點”表示實體,“邊”表示實體間的關係。在圖資料庫中,數據間的關係和數據本身同樣重要 ,它們被作為數據的一部分存儲起來。這樣的架構使圖[資料庫]能夠快速響應複雜關聯查詢,因為實體間的關係已經提前存儲到了資料庫中。圖資料庫可以直觀地可視化關係,是[存儲]、查詢、分析高度[互聯數據]的最優辦法。
圖資料庫屬於非關係型資料庫(NoSQL)。圖資料庫對數據的存儲、查詢以及數據結構都和關係型資料庫有很大的不同。圖數據結構直接存儲了節點之間的依賴關係,而關係型資料庫和其他類型的非關係型資料庫則以非直接的方式來表示數據之間的關係。圖資料庫把數據間的關聯作為數據的一部分進行存儲,關聯上可添加標簽、方向以及屬性,而其他資料庫針對關係的查詢必須在運行時進行具體化操作,這也是圖資料庫在關係查詢上相比其他類型資料庫有巨大性能優勢的原因。
最簡單的說,圖資料庫對於關係型資料庫中的join操作具有十分高的效率,每個節點存儲了所有邊的引用。
下麵我們來看一個示列,加入圓代表一個學校教學樓,圓角矩形代表教學樓下麵的教室,三角形代表教室的每一張桌椅,當我們需要獲取一個樓宇下麵的所有桌椅,在關係型資料庫如MySQL中,就需要把教學樓表、教室表以及桌椅表join起來查詢,雖然有索引,但當量上去後依然是一個昂貴的操作。而在圖資料庫如OrientDB中,就可以直接從教學樓出發通過廣度優先或者深度優先直接找到桌椅,而且相比關係型資料庫具有極高的效率。
OrientDB API
OrientDB是一款高性能的文檔、圖資料庫,在關係查找、遍歷方面有很大的速度優勢,特別是處理傳統關係型資料庫中的join操作,圖資料庫具有無法比擬的優點。雖然OrientDB官方提供了Java的SDK,但是還是有一定的學習成本,需要手擼操作腳本,本倉庫對OrientDB的Java SDK進行了二次封裝,以更加自然的語言操作OrientDB,降低學習成本,使得項目能更快的集成OrientDB。
一、特性
更簡單的API :話不多說上例子感受,假如我們要保存一個People
對象到圖資料庫,先看看原生的SDK例子:
public static void main(String[] args) {
//使用原生JDK保存一個“人”頂點到圖資料庫
People people1 = new People("張三", "男", 18);
try (ODatabaseSession session = OrientSessionFactory
.getInstance()
.getSession()) {
//在圖資料庫創建Class:People
if (session.getClass("People") == null) {
session.createVertexClass("People");
}
OVertex vertex = session.newInstance();
vertex.setProperty("name", people1.getName());
vertex.setProperty("age", people1.getAge());
vertex.save();
}
}
原生的SDK將頂點封裝成了Overtex
對象,首先需要先獲取會話ODatabaseSession
,並且創建對應的頂點類,然後將實體相關的屬性需要調用setProperty
方法存入進去,並且保存,還要要留意關閉會話,對於屬性多、數量多的實體簡直是災難,下麵我們來看看使用OrientDB API:
public static void main(String[] args) {
//創建實體對象
People people2 = new People("李四", "男", 21);
//將實體對象包裝成ResourceNode對象,其提供了對頂點的操作,對邊的操作在ResourceRelation里
ResourceNode<People> li = new GraphResourceNode<>(people2);
//直接調用save方法進行保存
li.save();
}
@Getter
@Setter
@ToString
//實現Vertex語義介面,表明該實體是一個圖資料庫的頂點對象
public class People implements Vertex {
private String name;
private String sex;
private Integer age;
public People(String name, String sex, Integer age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public People() {
}
}
如上圖,通過上面的語句就將實體對象People1
存入了OrientDB。
更優雅的查詢 :原生SDK的查詢難免會跟OrientDB的SQL
語句或者Match
語句打交道,而且國內的中文文檔很少和相關博客也很少,學習成本進一步加大,因此OrientDB API對常用查詢操作進行了封裝,做到完全透明化,下麵我們來看一個示列:使用原生SDK進行查詢:
public static void main(String[] args) {
try (ODatabaseSession session = OrientSessionFactory
.getInstance()
.getSession()) {
OResultSet resultSet = session.query("select * from People where name = ?", "李四");
People people=new People();
while(resultSet.hasNext()){
OResult result= resultSet.next();
people.setName(result.getProperty("name"));
people.setAge(result.getProperty("age"));
}
resultSet.close();
}
}
原生JDK使用起來跟JDBC差不多,體驗差,下麵看看OrientDB API查詢:
public static void main(String[] args) {
//創建資源圖對象,其提供了很多對圖的直接操作。使用OrientDB存儲庫(後續可以拓展Neo4j等存儲庫)
ResourceGraph graph = new ResourceGraph(new OrientDBRepository());
//調用extractNode方法取出指定節點
ResourceNode<People> peopleResourceNode = graph.extractNode(QueryParamsBuilder
.newInstance()
.addParams("name", "李四")
.getParams());
//獲取節點對應的屬性實體
People people = peopleResourceNode.getSource();
}
更人性化的遍歷 : 單一的查詢肯定不能滿足實際的需要,OrientDB提供了圖的遍歷,支持更複雜的查詢,通過遍歷我們能找到與任意一個節點有某種關係的其他節點,使用原生SDK如下:
public static void main(String[] args) {
try (ODatabaseSession session = OrientSessionFactory
.getInstance()
.getSession()) {
//從頂點#74:0出發,深度優先遍歷7層以內的同學,並且進行分頁
OResultSet resultSet = session.query("select * from (traverse * from #74:0 MAXDEPTH 7 STRATEGY DEPTH_FIRST) where (@class = \"Classmate\") skip 0 limit 10");
List<ClassMates> classMates=new ArrayList<>();
while(resultSet.hasNext()){
ClassMates classMate=new ClassMates(null);
OResult result= resultSet.next();
classMate.setDate(result.getProperty("date"));
//...
classMates.add(classMate);
}
resultSet.close();
}
}
使用OrientDB API
public static void main(String[] args) {
//創建資源圖對象,其提供了很多對圖的直接操作。使用OrientDB存儲庫(後續可以拓展Neo4j等存儲庫)
ResourceGraph graph = new ResourceGraph(new OrientDBRepository());
//直接調用traverse方法,參數分別是,出發節點、深度、遍歷策略、分頁配置、目標實體類型
PagedResult<ResourceNode<? extends Vertex>> result = graph.traverse(graph.extractNode("#74:0"),
QueryParamsBuilder
.newInstance()
.getParams(), 7, TraverseStrategy.DEPTH_FIRST, new PageConfig(1, 10, true), ClassMates.class);
result
.getSources()
.forEach(item -> System.out.println(item.getSource()));
}
無需語句,透明化,更人性化。
二、詳細用法
圖的元素分為頂點和邊兩類,在使用圖資料庫時我們一定要想好以前在關係型資料庫中存的數據如何在建立模型,如介紹中的教學樓-教室-桌椅模型。創建好模型後就需要定義頂點實體類,如特性中的People
類,以及關係類頂點實體類需要實現Vertex介面,關係類需要實現Edge介面。
圖資料庫的相關配置在orientdb-config.yml
中下麵是一個配置示列:
orientDB:
# 圖資料庫IP地址
url: "localhost"
# 圖資料庫庫名
database: "testDB"
# 訪問用戶名
username: "root"
# 訪問密碼
password: "0000"
# 連接池配置
pool:
min: 5
max: 30
acquireTimeout: 30
2.1 創建頂點
public static void main(String[] args) {
//創建實體對象
People people2 = new People("李四", "男", 21);
//將實體對象包裝成ResourceNode對象,其提供了對頂點的操作,對邊的操作在ResourceRelation里
ResourceNode<People> li = new GraphResourceNode<>(people2);
//直接調用save方法進行保存
li.save();
}
2.2 創建邊
public static void main(String[] args) {
//創建實體對象
People people1 = new People("張三", "男", 18);
People people2 = new People("李四", "男", 21);
//創建關係對象
FriendOf friendOf = new FriendOf();
//封裝成ResourceNode對象
ResourceNode<People> zhang = new GraphResourceNode<>(people1);
ResourceNode<People> li = new GraphResourceNode<>(people2);
//封裝成ResourceRelation對象
ResourceRelation<FriendOf> friend = new GraphResourceRelation<>(friendOf);
//直接調用ResourceRelation的link方法創建有向邊,如果頂點還未創建會先創建頂點
friend.link(zhang, li);
//或者調用linkUndirected創建無向邊,即會創建兩條互相指向的邊
friend.linkUndirected(zhang,li)
}
2.3 分頁查詢
public static void main(String[] args){
//通過指定PageCofig來實現分頁查詢,構造函數參數列表分別代表:頁號、頁大小、是否查詢總數
PagedResult<ResourceNode<? extends Vertex>> pagedResult = graph.extractNodes(QueryParamsBuilder
.newInstance()
.addParams("sex", "男")
.getParams(), new PageConfig(1, 5, true));
System.out.println("分頁結果:"+pagedResult.getSources());
System.out.println("總條數:"+pagedResult.getTotal());
}
2.4 關係查找
public static void main(String[] args){
//創建資源圖對象,其提供了很多對圖的直接操作。使用OrientDB存儲庫(後續可以拓展Neo4j等存儲庫)
ResourceGraph graph = new ResourceGraph(new OrientDBRepository());
//查找張三的朋友的朋友
graph
//獲取關係匹配器
.getGraphResourceNodeMatcher()
//張三作為起始節點
.asStart(zhang)
//查找張三的朋友
.findUndirected(FriendOf.class)
//查找張三的朋友的朋友
.findUndirected(FriendOf.class)
//將結果收集成People對象
.collect(People.class)
//遍歷列印
.forEach(item -> System.out.println(item.getSource()));
}
2.5 最短路徑搜索
public static void main(String[] args){
//查詢張到李的最短路徑,參數列表分別是:起始頂點、終止頂點、關係方向,無向邊任意方向都可、路徑最大深度、路徑要經過的邊類型
List<ResourceNode<? extends Vertex>> find4 = graph.shortestPath(zhang, li, RelationDirection.OUT, 3, FriendOf.class);
find4.forEach(item -> System.out.println(item.getSource()));
}
2.6 屬性修改
public static void main(String[] args){
//修改張的年齡為15歲
zhang.update(QueryParamsBuilder
.newInstance()
.addParams("age", 15)
.getParams())
}
2.7 元素刪除
public static void main(String[] args){
//移除張
zhang.remove();
}
2.8 關係重定向
關係重定向意思是將原來的A->B的關係變更成A->C。
public static void main(String[] args){
ResourceRelation<FriendOf> friend = graph.extractRelation(QueryParamsBuilder
.newInstance()
.addParams("date", new Date())
.getParams());
//參數列表分別是:要重定向的關係,重定向到的目標
graph.relink(friend, li);
}
2.9 批量創建關係和頂點
public static void main(String[] args){
//構建參數key是連接的關係,value是目標頂點
Map<FriendOf, ResourceNode<People>> toMap = new HashMap<>();
toMap.put(new FriendOf(), li);
toMap.put(new FriendOf(), wang);
toMap.put(new FriendOf(), huang);
toMap.put(new FriendOf(), hu);
//調用linksUndirected方法,返回所有的關係
List<ResourceRelation<? extends Edge>> relations = zhang.linksUndirected(toMap);
relations.forEach(item -> System.out.println(item.getInEdgeId() + "," + item.getOutEdgeId()));
}
其他更多API正在更新中......