Neo4j圖數據庫管理系統開發筆記之一:Neo4j Java 工具包

1 應用開發概述

      基於數據傳輸效率以及接口自定義等特殊性需求,咱們暫時放棄使用Neo4j服務器版本,而是在Neo4j嵌入式版本的基礎上進行一些封裝性的開發。封裝的重點,是解決Neo4j嵌入式版本EmbeddedGraphDatabase中不能同時建立多個實例指向同一個數據庫的問題。若是開發人員使用Neo4j嵌入式版本做爲數據庫,要想實現多個程序共享一個數據庫,這將是一個不可迴避的問題。本手冊給出的解決方案是「構建一箇中間服務層,提供各類接口方法,指向同一個數據庫實例;其餘客戶端程序經過中間服務層與Neo4j嵌入式數據庫進行通訊」。由於咱們已經從Neo4j官方聲明中得知:Neo4j嵌入式實例能夠在多個線程中共享。java

      系統框架以下圖所示:node

系統架構圖

  • Neo4j Java 工具包

      Neo4j Java 工具包是對Neo4j嵌入式版本Java API的二次封裝,根據業務類型劃分爲Node(Relationship)、Index、Path和Cypher等四種工具集。mysql

  • 管理工具Server端

      之因此稱其爲Server端,是由於其中包含了對RMI Server的管理。此管理工具的主要功能包括圖數據庫信息管理(包括新建、刪除、統計圖數據庫等)、圖數據庫數據管理(包括Node數據管理、Relationship數據管理等)、數據導入導出(包括Neo4j與oracle、mysql和excel等之間的數據轉換)、RMI Server監控管理等。sql

管理工具Server端只能部署在Neo4j數據庫服務器上,而且只能部署一套程序,不然將違背Neo4j圖數據庫單例的原則。數據庫

  • RMI Service(服務)

      RMI Server(服務),是在Neo4j Java 工具包的基礎上,設計的一套接口服務,分爲Server端和Client端。Server端用於接口方法的實現和監控管理,Client端用於接口方法的定義和分發(供其餘外部系統使用)。整體設計思路,是將Neo4j中的關鍵對象(Node、Relationship、Path、Direction等)進行可序列化的封裝,經過遠程調用服務返回給客戶端使用。apache

  • 管理工具Client端

      管理工具Client端,是基於RMI Client設計的Neo4j數據管理工具,主要功能包括圖數據庫信息查看功能、圖數據庫數據管理功能、數據導入導出功能等。管理工具Client端能夠部署多套。服務器

 

2 Neo4j Java 工具包

      以上全部功能(工具包、RMI Service以及管理工具)都包含在兩個Java項目中,項目結構以下圖所示:架構

      hnepri-neo4j-common爲工具包項目,包括Neo4j Java 工具包、RMI Server端和管理工具Server端;hnepri-neo4j-client爲客戶端項目,包括RMI Client端和管理工具Client端。oracle

      下面主要介紹Neo4j Java 工具包的幾個封裝關鍵點,其中,下圖爲各個工具類之間的關聯效果圖。框架

 

2.1 Node操做工具類(GraphNodeUtil)

      Node操做工具類的主要功能包括Node節點和Relationship關係的建立、編輯、刪除、查詢,以及Label和Property的管理等。對於其中的部分接口方法,根據實際狀況和須要則進行了事務處理。相關接口方法截圖以下所示:

 

2.2 Index操做工具類(GraphIndexUtil)

      Index操做工具類的主要功能包括Node和Relationship相關索引信息的建立、編輯、刪除、查詢,以及基於索引查詢Node節點和Relationship關係等。對於其中的部分接口方法,根據實際狀況和須要則進行了事務處理。相關接口方法截圖以下所示:

 

2.3 Path操做工具類(GraphPathUtil)

      Path操做工具類的主要功能包括針對Path的檢索操做,包括路徑深度遍歷、兩點之間路徑尋址等接口方法。對於其中的部分接口方法,根據實際狀況和須要則進行了事務處理。相關接口方法截圖以下所示:

 

2.4 Cypher操做工具類(GraphCypherUtil)

      Cypher操做工具類是對Cypher查詢語言的封裝,主要包括針對Node、Relationship和Path的自定義查詢操做。另外,也包括了多種方式的分頁查詢。對於其中的部分接口方法,根據實際狀況和須要則進行了事務處理。

       其中,最基本的接口方法是executeQuery方法,執行Cypher查詢語句,將查詢結果以Properties的形式存在在List中,而後再由其餘接口方法顯式地轉換爲Node、Relationship、Path或者其餘基本類型使用。

 

 1        /**
 2      * 執行Cypher查詢語句,將檢索結果封裝進Properties列表中。
 3      * @param query cypher查詢語句
 4      * @param params cypher查詢語句參數集合
 5      * @return
 6      */
 7     public List<Properties> executeQuery(String query, Map<String,Object> params) {
 8         GraphTimerModel timer = GraphTimerModel.create();
 9         List<Properties> propertiesList = new ArrayList<Properties>();
10         if(StringUtils.isBlank(query)) {
11             return propertiesList;
12         }
13         ExecutionResult result = null;
14         if(params == null || params.size() == 0) {
15             result = this.getExecutionEngine().execute(query);
16         } else {
17             result = this.getExecutionEngine().execute(query, params);
18         }
19         LogInfoUtil.printLog(query);
20         
21         for (Map<String, Object> row : result ) {
22             Properties properties = new Properties();
23             for ( Entry<String, Object> column : row.entrySet()){
24                 properties.put(column.getKey(), column.getValue());
25             }
26             propertiesList.add(properties);
27         }
28         timer.initEndTime();
29         timer.printTimeInfo();
30         return propertiesList;
31     }
32     舉例以下所示:
33     String query = "START n=node(*) WHERE n.name=’tom’ RETURN n AS NODE_ENTRY";
34     List<Properties> list = this.executeQuery(query);
35     for(Properties properties : list) {
36         nodeList.add((Node)properties.get("NODE_ENTRY"));
37     }

 

      相關接口方法截圖以下所示:

 

2.5 動態生成RelationshipType(GraphRelTypeUtil)

      動態生成RelationshipType是構建RMI服務必須首先要解決的一個關鍵點,由於RMI要求Server端與Client端之間的傳輸對象必須是可序列化的對象,而Neo4j API中的接口類和枚舉是沒法真正序列化的,這也是咱們在RMI Service中對相關實體進行封裝的根本緣由。

      所謂動態生成RelationshipType,就是可根據字符串類型的關係類型,生成符合Neo4j Java API要求的枚舉類型RelationshipType。關鍵代碼以下表所示:

 

  1 package com.hnepri.neo4j.common.util;
  2 
  3 import java.lang.reflect.AccessibleObject;
  4 import java.lang.reflect.Array;
  5 import java.lang.reflect.Field;
  6 import java.lang.reflect.Modifier;
  7 import java.util.ArrayList;
  8 import java.util.Arrays;
  9 import java.util.HashMap;
 10 import java.util.Iterator;
 11 import java.util.List;
 12 import java.util.Map;
 13 
 14 import org.apache.commons.lang3.StringUtils;
 15 import org.neo4j.graphdb.GraphDatabaseService;
 16 import org.neo4j.graphdb.RelationshipType;
 17 import org.neo4j.graphdb.Transaction;
 18 
 19 import sun.reflect.ConstructorAccessor;
 20 import sun.reflect.FieldAccessor;
 21 import sun.reflect.ReflectionFactory;
 22 
 23 /**
 24  * Description: 圖數據庫關係類型工具類。<br>
 25  * 一、可根據關係類型名稱字符串動態生成關係類型枚舉。<br>
 26  * 二、可管理動態生成的關係類型枚舉列表。
 27  * Copyright: Copyright (c) 2015<br>
 28  * Company: 河南電力科學研究院智能電網所<br>
 29  * @author shangbingbing 2015-11-01編寫
 30  * @version 1.0
 31  */
 32 public class GraphRelTypeUtil {
 33 
 34     /**
 35      * 構造函數。<br>
 36      * 初始化對應的圖數據庫服務對象實例。
 37      * @param graphDBService
 38      */
 39     public GraphRelTypeUtil(GraphDatabaseService graphDBService) {
 40         this.graphDBService = graphDBService;
 41     }
 42     
 43     private GraphDatabaseService graphDBService = null;
 44     /**
 45      * 獲取對應的圖數據庫服務對象實例。
 46      * @return
 47      */
 48     public GraphDatabaseService getGraphDBService() {
 49         return this.graphDBService;
 50     }
 51     
 52     /**
 53      * 構建事務。
 54      * @return
 55      */
 56     public Transaction createTransaction() {
 57         return this.getGraphDBService().beginTx();
 58     }
 59     
 60     private GraphIndexUtil indexManager = null;
 61     /**
 62      * 獲取圖數據庫索引信息管理器。
 63      * @return
 64      */
 65     public GraphIndexUtil getIndexManager() {
 66         if(this.indexManager == null) {
 67             this.indexManager = new GraphIndexUtil(this.getGraphDBService());
 68         }
 69         return this.indexManager;
 70     }
 71     
 72     private Map<String,RelationshipType> relationshipTypeList = null;
 73     /**
 74      * 獲取已動態生成的關係枚舉類型列表。
 75      * @return
 76      */
 77     @SuppressWarnings("deprecation")
 78     public Map<String, RelationshipType> getRelationshipTypeList() {
 79         if(this.relationshipTypeList == null) {
 80             this.relationshipTypeList = new HashMap<String, RelationshipType>();
 81             
 82             Iterator<RelationshipType> iterator = this.getGraphDBService().getRelationshipTypes().iterator();
 83             while(iterator.hasNext()) {
 84                 RelationshipType relType = iterator.next();
 85                 String relTypeName = relType.name();
 86                 this.relationshipTypeList.put(relTypeName, relType);
 87             }
 88         }
 89         return this.relationshipTypeList;
 90     }
 91 
 92     /**
 93      * 根據關係類型名稱動態生成圖數據庫關係枚舉類型。
 94      * @param relTypeName
 95      * @return
 96      */
 97     public RelationshipType create(String relTypeName) {
 98         if(StringUtils.isBlank(relTypeName)) {
 99             return null;
100         }
101         if(this.getRelationshipTypeList().containsKey(relTypeName) == false) {
102             addEnum(relTypeName);
103             RelationshipType relType = RelationshipTypeEnum.valueOf(relTypeName);
104             this.getRelationshipTypeList().put(relTypeName, relType);
105             return relType;
106         } else {
107             return this.getRelationshipTypeList().get(relTypeName);
108         }
109     }
110     
111     /**
112      * 根據關係類型名稱,獲取對應的關係枚舉類型。
113      * @param relTypeName
114      * @return
115      */
116     public RelationshipType get(String relTypeName) {
117         if(StringUtils.isBlank(relTypeName)) {
118             return null;
119         }
120         return this.create(relTypeName);
121     }
122     
123     /**
124      * 根據關係類型名稱,刪除對應的關係枚舉類型。
125      * @param relTypeName
126      * @return
127      */
128     public void remove(String relTypeName) {
129         if(this.getRelationshipTypeList().containsKey(relTypeName)) {
130             this.getRelationshipTypeList().remove(relTypeName);
131         }
132     }
133     
134     /**
135      * 根據關係類型名稱列表,初始化關係類型枚舉列表。
136      * @param relTypeNameList
137      */
138     public void init(List<String> relTypeNameList) {
139         if(relTypeNameList == null || relTypeNameList.size() == 0) {
140             return;
141         }
142         for(String relTypeName : relTypeNameList) {
143             create(relTypeName);
144         }
145     }
146     
147     private static ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
148     
149     private static void setFailsafeFieldValue(Field field, Object target, Object value) throws NoSuchFieldException,IllegalAccessException {
150         field.setAccessible(true);
151         Field modifiersField = Field.class.getDeclaredField("modifiers");
152         modifiersField.setAccessible(true);
153         int modifiers = modifiersField.getInt(field);
154         
155         modifiers &= ~Modifier.FINAL;
156         modifiersField.setInt(field, modifiers);
157         
158         FieldAccessor fa = reflectionFactory.newFieldAccessor(field, false);
159         fa.set(target, value);
160     }
161     
162      private static void blankField(Class<?> enumClass, String fieldName) throws NoSuchFieldException, IllegalAccessException {
163          for (Field field : Class.class.getDeclaredFields()) {
164              if (field.getName().contains(fieldName)) {
165                  AccessibleObject.setAccessible(new Field[] { field }, true);
166                  setFailsafeFieldValue(field, enumClass, null);
167                  break;
168              }
169         }
170     }
171 
172     private static void cleanEnumCache(Class<?> enumClass) throws NoSuchFieldException, IllegalAccessException {
173         blankField(enumClass, "enumConstantDirectory");
174         blankField(enumClass, "enumConstants");
175     }
176 
177     private static ConstructorAccessor getConstructorAccessor(Class<?> enumClass, Class<?>[] additionalParameterTypes) throws NoSuchMethodException {
178         Class<?>[] parameterTypes = new Class[additionalParameterTypes.length + 2];
179         parameterTypes[0] = String.class;
180         parameterTypes[1] = int.class;
181         System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length);
182         return reflectionFactory.newConstructorAccessor(enumClass.getDeclaredConstructor(parameterTypes));
183     }
184 
185     private static Object makeEnum(Class<?> enumClass, String value, int ordinal, Class<?>[] additionalTypes, Object[] additionalValues) throws Exception {
186         Object[] parms = new Object[additionalValues.length + 2];
187         parms[0] = value;
188         parms[1] = Integer.valueOf(ordinal);
189         System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length);
190         return enumClass.cast(getConstructorAccessor(enumClass, additionalTypes).newInstance(parms));
191     }
192 
193     @SuppressWarnings("unchecked")
194     private static <T extends Enum<?>> void addEnum(String enumName) {
195          if (!Enum.class.isAssignableFrom(RelationshipTypeEnum.class)) {
196              throw new RuntimeException("class " + RelationshipTypeEnum.class + " is not an instance of Enum");
197          }
198         
199          Field valuesField = null;
200          Field[] fields = RelationshipTypeEnum.class.getDeclaredFields();
201          for (Field field : fields) {
202              if (field.getName().contains("$VALUES")) {
203                  valuesField = field;
204                  break;
205              }
206          }
207          AccessibleObject.setAccessible(new Field[] { valuesField }, true);
208         
209          try {
210         
211              T[] previousValues = (T[]) valuesField.get(RelationshipTypeEnum.class);
212              List<T> values = new ArrayList<T>(Arrays.asList(previousValues));
213         
214              T newValue = (T) makeEnum(RelationshipTypeEnum.class, enumName, values.size(), new Class<?>[] {}, new Object[] {});
215              values.add(newValue);
216              setFailsafeFieldValue(valuesField, null, values.toArray((T[]) Array.newInstance(RelationshipTypeEnum.class, 0)));
217              cleanEnumCache(RelationshipTypeEnum.class);
218          } catch (Exception e) {
219              e.printStackTrace();
220              throw new RuntimeException(e.getMessage(), e);
221          }
222     }
223 }
224 
225 /**
226  * Description: 圖數據庫關係類型枚舉。
227  * Copyright: Copyright (c) 2015<br>
228  * Company: 河南電力科學研究院智能電網所<br>
229  * @author shangbingbing 2015-11-01編寫
230  * @version 1.0
231  */
232 enum RelationshipTypeEnum implements RelationshipType {
233     NONE
234 }

 

2.6 圖數據庫操做模板工具類(GraphTemplateUtil)

      圖數據庫操做模板工具類,主要負責對以上工具集的組織和調用管理,以保證開發人員在調用習慣上遵循Neo4j嵌入式圖數據庫單例服務的原則。關鍵代碼以下表所示:

  1 package com.hnepri.neo4j.common.util;
  2 
  3 import java.io.File;
  4 import java.util.HashMap;
  5 import java.util.Map;
  6 
  7 import org.apache.commons.lang3.StringUtils;
  8 import org.neo4j.graphdb.GraphDatabaseService;
  9 import org.neo4j.graphdb.Transaction;
 10 import org.neo4j.graphdb.factory.GraphDatabaseFactory;
 11 import org.neo4j.io.fs.FileUtils;
 12 
 13 import com.hnepri.neo4j.client.form.graph.bean.GraphConfigOption;
 14 import com.hnepri.neo4j.form.graph.util.GraphManageUtil;
 15 
 16 /**
 17  * Description: Neo4j圖數據庫操做模板類。<br>
 18  * Copyright: Copyright (c) 2015<br>
 19  * Company: 河南電力科學研究院智能電網所<br>
 20  * @author shangbingbing 2015-11-01 編寫
 21  * @version 1.0
 22  */
 23 public class GraphTemplate {
 24 
 25     private String graphDBPath = "";
 26     /**
 27      * 獲取圖數據庫路徑。
 28      * @return
 29      */
 30     public String getGraphDBPath() {
 31         return graphDBPath;
 32     }
 33     private GraphDatabaseService graphDBService = null;
 34     /**
 35      * 獲取圖數據庫服務實例對象。
 36      * @return
 37      */
 38     public GraphDatabaseService getGraphDBService() {
 39         if(StringUtils.isBlank(this.getGraphDBPath())) {
 40             try {
 41                 throw new Exception("警告:沒有配置圖數據庫路徑信息!");
 42             } catch (Exception e) {
 43                 e.printStackTrace();
 44             }
 45         }
 46         if(this.graphDBService == null) {
 47             this.graphDBService = new GraphDatabaseFactory().newEmbeddedDatabase(this.getGraphDBPath());
 48             registerShutdownHook();
 49         }
 50         return this.graphDBService;
 51     }
 52     
 53     /**
 54      * 清除圖數據庫數據文件信息。
 55      */
 56     public void clearGraphDB() {
 57         try {
 58             FileUtils.deleteRecursively(new File(this.getGraphDBPath()));
 59             if(graphTemplateList.containsKey(this.getGraphDBPath())) {
 60                 graphTemplateList.remove(this.getGraphDBPath());
 61             }
 62         } catch (Exception ex) {
 63             ex.printStackTrace();
 64         }
 65     }
 66     
 67     /**
 68      * 註冊圖數據庫關閉鉤子。
 69      */
 70     public void registerShutdownHook() {
 71         Runtime.getRuntime().addShutdownHook(new Thread(){ 
 72             @Override
 73             public void run(){ 
 74                 getGraphDBService().shutdown(); 
 75             } 
 76         }); 
 77     }
 78     
 79     /**
 80      * 構造函數。初始化圖數據庫路徑。
 81      * @param graphDBPath
 82      */
 83     private GraphTemplate(String graphDBPath) {
 84         this.graphDBPath = graphDBPath;
 85     }
 86     
 87     private static Map<String, GraphTemplate> graphTemplateList = new HashMap<String, GraphTemplate>();
 88     /**
 89      * 根據圖數據庫路徑信息,獲取對應的GraphTemplate對象實例。<br>
 90      * 目的是採用GraphTemplate的單例模式。
 91      * @param graphPath
 92      * @return
 93      */
 94     public static GraphTemplate getInstance(String graphPath) {
 95         if(graphTemplateList.containsKey(graphPath) == false) {
 96             GraphTemplate template = new GraphTemplate(graphPath);
 97             graphTemplateList.put(graphPath, template);
 98         }
 99         return graphTemplateList.get(graphPath);
100     }
101     
102     /**
103      * 根據圖數據庫名稱標示信息,獲取對應的GraphTemplate對象實例。<br>
104      * 目的是採用GraphTemplate的單例模式。
105      * @param graphName
106      * @return
107      */
108     public static GraphTemplate getInstanceByName(String graphName) {
109         if(GraphManageUtil.getGraphConfigOptionList().containsKey(graphName) == false) {
110             return null;
111         }
112         GraphConfigOption option = GraphManageUtil.getGraphConfigOptionList().get(graphName);
113         return getInstance(option.getPath());
114     }
115     
116     /**
117      * 構建事務。
118      * @return
119      */
120     public Transaction createTransaction() {
121         return this.getGraphDBService().beginTx();
122     }
123     
124     private GraphIndexUtil indexUtil = null;
125     /**
126      * 獲取圖數據庫索引信息管理功能庫。
127      * @return
128      */
129     public GraphIndexUtil getIndexUtil() {
130         if(this.indexUtil == null) {
131             this.indexUtil = new GraphIndexUtil(this.getGraphDBService());
132         }
133         return this.indexUtil;
134     }
135     
136     private GraphNodeUtil nodeUtil = null;
137     /**
138      * 獲取圖數據庫節點信息管理功能庫。
139      * @return
140      */
141     public GraphNodeUtil getNodeUtil() {
142         if(this.nodeUtil == null) {
143             this.nodeUtil = new GraphNodeUtil(this.getGraphDBService());
144         }
145         return this.nodeUtil;
146     }
147     
148     private GraphCypherUtil cypherUtil = null;
149     /**
150      * 獲取圖數據庫Cypher查詢語言功能庫。
151      * @return
152      */
153     public GraphCypherUtil getCypherUtil() {
154         if(this.cypherUtil == null) {
155             this.cypherUtil = new GraphCypherUtil(this.getGraphDBService());
156         }
157         return this.cypherUtil;
158     }
159     
160     private GraphPathUtil pathUtil = null;
161     /**
162      * 獲取圖數據庫Path信息功能庫。
163      * @return
164      */
165     public GraphPathUtil getPathUtil() {
166         if(this.pathUtil == null) {
167             this.pathUtil = new GraphPathUtil(this.getGraphDBService());
168         }
169         return this.pathUtil;
170     }
171     
172     private GraphRelTypeUtil relTypeUtil = null;
173     /**
174      * 獲取圖數據庫關係類型信息功能庫。
175      * @return
176      */
177     public GraphRelTypeUtil getRelTypeUtil() {
178         if(this.relTypeUtil == null) {
179             this.relTypeUtil = new GraphRelTypeUtil(this.getGraphDBService());
180         }
181         return this.relTypeUtil;
182     }
183 }

 

2.7 數據分頁模型GraphPageModel

      數據分頁模型主要是基於Cypher查詢語言中的SKIP和LIMIT而設計的針對Node和Relationship的分頁處理模型。關鍵代碼以下表所示:

 

  1 package com.hnepri.neo4j.common.model;
  2 
  3 import java.io.Serializable;
  4 import java.text.DecimalFormat;
  5 import java.util.ArrayList;
  6 import java.util.List;
  7 
  8 import org.neo4j.graphdb.Node;
  9 import org.neo4j.graphdb.Relationship;
 10 
 11 import com.hnepri.common.util.LogInfoUtil;
 12 
 13 /**
 14  * Description: 圖數據庫數據分頁模型類。<br>
 15  * 利用此類可分頁管理Node數據和Relationship數據等。
 16  * Copyright: Copyright (c) 2015<br>
 17  * Company: 河南電力科學研究院智能電網所<br>
 18  * @author shangbingbing 2015-11-01編寫
 19  * @version 1.0
 20  */
 21 public class GraphPageModel implements Serializable {
 22     private static final long serialVersionUID = 330410716100946538L;
 23     private int pageSize = 10;
 24     private int pageIndex = 1;
 25     private int prevPageIndex = 1;
 26     private int nextPageIndex = 1;
 27     private int pageCount = 0;
 28     private int pageFirstRowIndex = 1;
 29     private boolean hasNextPage = true;
 30     private int totalCount = 0;
 31     private long startTime = System.currentTimeMillis();
 32     private long endTime = System.currentTimeMillis();
 33     private List<Node> nodeList = new ArrayList<Node>();
 34     private List<Relationship> relationshipList = new ArrayList<Relationship>();
 35     
 36     /**
 37      * 分頁對象構造函數
 38      * @param pageSize 每頁記錄數
 39      */
 40     public GraphPageModel(int pageSize) {
 41         this.pageSize = pageSize;
 42     }
 43 
 44     /**
 45      * 獲取分頁記錄數量
 46      * @return
 47      */
 48     public int getPageSize() {
 49         return pageSize;
 50     }
 51     /**
 52      * 獲取當前頁序號
 53      * @return
 54      */
 55     public int getPageIndex() {
 56         return pageIndex;
 57     }
 58     /**
 59      * 設置當前頁序號
 60      * @param pageIndex
 61      */
 62     public void setPageIndex(int pageIndex) {
 63         if(pageIndex <= 0) {
 64             pageIndex = 1;
 65         }
 66         this.pageIndex = pageIndex;
 67     }
 68     /**
 69      * 獲取分頁總數
 70      * @return
 71      */
 72     public int getPageCount() {
 73         if(this.getTotalCount() == 0) {
 74             this.pageCount = 0;
 75         } else {
 76             int shang = this.getTotalCount() / this.getPageSize();
 77             int yu = this.getTotalCount() % this.getPageSize();
 78             if(yu > 0) {
 79                 shang += 1;
 80             }
 81             this.pageCount = shang;
 82         }
 83         return pageCount;
 84     }
 85     /**
 86      * 獲取每頁的第一行序號
 87      * @return
 88      */
 89     public int getPageFirstRowIndex() {
 90         this.pageFirstRowIndex = (this.pageIndex - 1) * this.getPageSize() + 1;
 91         return pageFirstRowIndex;
 92     }
 93     /**
 94      * 獲取上一頁序號
 95      * @return
 96      */
 97     public int getPrevPageIndex() {
 98         if(this.pageIndex > 1) {
 99             this.prevPageIndex = this.pageIndex - 1;
100         } else {
101             this.prevPageIndex = 1;
102         }
103         return prevPageIndex;
104     }
105     /**
106      * 獲取下一頁序號
107      * @return
108      */
109     public int getNextPageIndex() {
110         if(this.pageIndex < this.pageCount) {
111             this.nextPageIndex = this.pageIndex + 1;    
112         } else {
113             this.nextPageIndex = this.pageCount;
114         }
115         return nextPageIndex;
116     }
117     /**
118      * 跳轉到下一頁
119      */
120     public void nextPage() {
121         if(this.totalCount == 0 || this.getPageCount() == 0) {
122             this.pageIndex = 1;
123         } else {
124             if(this.pageIndex < this.pageCount) {
125                 this.pageIndex = this.pageIndex + 1;    
126             } else {
127                 this.pageIndex = this.pageCount;
128             }
129         }
130     }
131     /**
132      * 跳轉到上一頁
133      */
134     public void prevPage() {
135         if(this.pageIndex > 1) {
136             this.pageIndex = this.pageIndex - 1;
137         } else {
138             this.pageIndex = 1;
139         }
140     }
141     /**
142      * 獲取是否有下一頁
143      * @return
144      */
145     public boolean isHasNextPage() {
146         if(this.pageIndex < this.getPageCount()) {
147             this.hasNextPage = true;
148         } else {
149             this.hasNextPage = false;
150         }
151         return hasNextPage;
152     }
153     /**
154      * 獲取總記錄數    
155      */
156     public int getTotalCount() {
157         return totalCount;
158     }
159     /**
160      * 獲取總記錄數    
161      * @param totalCount
162      */
163     public void setTotalCount(int totalCount) {
164         this.totalCount = totalCount;
165     }
166     /**
167      * 初始化起始時間(毫秒)
168      */
169     public void initStartTime() {
170         this.startTime = System.currentTimeMillis();
171     }
172     /**
173      * 初始化截止時間(毫秒)
174      */
175     public void initEndTime() {
176         this.endTime = System.currentTimeMillis();
177     }
178     /**
179      * 獲取毫秒格式的耗時信息
180      * @return
181      */
182     public String getTimeIntervalByMilli() {
183         return String.valueOf(this.endTime - this.startTime) + "毫秒";
184     }
185     /**
186      * 獲取秒格式的耗時信息
187      * @return
188      */
189     public String getTimeIntervalBySecond() {
190         double interval = (this.endTime - this.startTime)/1000.0;
191         DecimalFormat df = new DecimalFormat("#.##");
192         return df.format(interval) + "秒";
193     }
194     /**
195      * 打印時間信息
196      */
197     public void printTimeInfo() {
198         LogInfoUtil.printLog("起始時間:" + this.startTime);
199         LogInfoUtil.printLog("截止時間:" + this.endTime);
200         LogInfoUtil.printLog("耗費時間:" + this.getTimeIntervalBySecond());
201     }
202     /**
203      * 獲取Node檢索結果列表
204      * @return
205      */
206     public List<Node> getNodeList() {
207         return nodeList;
208     }
209     /**
210      * 獲取Relationship檢索結果列表
211      * @return
212      */
213     public List<Relationship> getRelationshipList() {
214         return relationshipList;
215     }
216 }

 

【未完待續】

下一篇  Neo4j圖數據庫應用開發之二:RMI Service開發

相關文章
相關標籤/搜索