OrientDB API高性能的文檔、圖數(shù)據(jù)庫
OrientDB 是一款高性能的文檔、圖數(shù)據(jù)庫,在關(guān)系查找、遍歷方面有很大的速度優(yōu)勢,特別是處理傳統(tǒng)關(guān)系型數(shù)據(jù)庫中的join操作,圖數(shù)據(jù)庫具有無法比擬的優(yōu)點。雖然OrientDB官方提供了Java的SDK,但是還是有一定的學(xué)習(xí)成本,需要手?jǐn)]操作腳本,本倉庫對OrientDB的Java SDK進(jìn)行了二次封裝,以更加自然的語言操作OrientDB,降低學(xué)習(xí)成本,使得項目能更快的集成OrientDB。
特性
更簡單的API :話不多說上例子感受,假如我們要保存一個People對象到圖數(shù)據(jù)庫,先看看原生的SDK例子:
public static void main(String[] args) { //使用原生JDK保存一個“人”頂點到圖數(shù)據(jù)庫 People people1 = new People("張三", "男", 18); try (ODatabaseSession session = OrientSessionFactory .getInstance() .getSession()) { //在圖數(shù)據(jù)庫創(chuàng)建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,并且創(chuàng)建對應(yīng)的頂點類,然后將實體相關(guān)的屬性需要調(diào)用setProperty方法存入進(jìn)去,并且保存,還要要留意關(guān)閉會話,對于屬性多、數(shù)量多的實體簡直是災(zāi)難,下面我們來看看使用OrientDB API:
public static void main(String[] args) { //創(chuàng)建實體對象 People people2 = new People("李四", "男", 21); //將實體對象包裝成ResourceNode對象,其提供了對頂點的操作,對邊的操作在ResourceRelation里 ResourceNode<People> li = new GraphResourceNode<>(people2); //直接調(diào)用save方法進(jìn)行保存 li.save(); } @Getter @Setter @ToString //實現(xiàn)Vertex語義接口,表明該實體是一個圖數(shù)據(jù)庫的頂點對象 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。
更優(yōu)雅的查詢 :原生SDK的查詢難免會跟OrientDB的SQL語句或者Match語句打交道,而且國內(nèi)的中文文檔很少和相關(guān)博客也很少,學(xué)習(xí)成本進(jìn)一步加大,因此OrientDB API對常用查詢操作進(jìn)行了封裝,做到完全透明化,下面我們來看一個示列:使用原生SDK進(jìn)行查詢:
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) { //創(chuàng)建資源圖對象,其提供了很多對圖的直接操作。使用OrientDB存儲庫(后續(xù)可以拓展Neo4j等存儲庫) ResourceGraph graph = new ResourceGraph(new OrientDBRepository()); //調(diào)用extractNode方法取出指定節(jié)點 ResourceNode<People> peopleResourceNode = graph.extractNode(QueryParamsBuilder .newInstance() .addParams("name", "李四") .getParams()); //獲取節(jié)點對應(yīng)的屬性實體 People people = peopleResourceNode.getSource(); }
更人性化的遍歷 : 單一的查詢肯定不能滿足實際的需要,OrientDB提供了圖的遍歷,支持更復(fù)雜的查詢,通過遍歷我們能找到與任意一個節(jié)點有某種關(guān)系的其他節(jié)點,使用原生SDK如下:
public static void main(String[] args) { try (ODatabaseSession session = OrientSessionFactory .getInstance() .getSession()) { //從頂點#74:0出發(fā),深度優(yōu)先遍歷7層以內(nèi)的同學(xué),并且進(jìn)行分頁 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) { //創(chuàng)建資源圖對象,其提供了很多對圖的直接操作。使用OrientDB存儲庫(后續(xù)可以拓展Neo4j等存儲庫) ResourceGraph graph = new ResourceGraph(new OrientDBRepository()); //直接調(diào)用traverse方法,參數(shù)分別是,出發(fā)節(jié)點、深度、遍歷策略、分頁配置、目標(biāo)實體類型 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())); }
無需語句,透明化,更人性化。
