公司突然让用neo4j做一个 机构关注用户的功能,要用neo4j的图数据库实现。于是乎我的忙碌就开始了。
搜了一些资料,发现neo4j的数据库连接方式有两种,一种是原生太的javaAPI的方式,神奇的发现居然有JDBC的连接方式,由于时间紧迫,毫无疑问选择我熟悉的JDBC咯~~!
优点:以图的方式来表达节点之间的关系,层级关系查询较快。
缺点:单机版的最多几十万条,就相当慢了本文后面有测试结果。企业版的不免费
引入maven包
Neo4jPool.java
package com.chengshu.neo4j; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Enumeration; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Properties; import java.util.Timer; import java.util.TimerTask; import org.apache.log4j.Logger; import com.chengshu.configure.Configure; /** * @author 张彦 * @email: [email protected] * @date 创建时间:2017年2月21日 下午4:43:56 * @version 1.0 */ public class Neo4jPool { private static final Logger LOG = Logger.getLogger(Neo4jPool.class.getName()); // 配置项 private static Mapmap = new HashMap (); // 当前 连接数 static int connectionCurrLink = 0; private static LinkedList datasourcePool = new LinkedList (); static { try { Class.forName("org.neo4j.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } static { Properties args_properties = new Properties(); try (InputStream resourceAsStream = Configure.class.getResourceAsStream("/conf/neo4j.properties");) { args_properties.load(resourceAsStream); Enumeration
Neo4jUtil.java
package com.chengshu.neo4j; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * @author 张彦 * @email: [email protected] * @date 创建时间:2017年2月22日 上午9:59:03 * @version 1.0 */ public class Neo4jUtil { private static Neo4jPool pool = null; public Neo4jUtil() throws Exception { } /** * 获得连接 * @return * @throws Exception */ public static Connection getConnection() throws Exception { if (pool == null) { synchronized (Neo4jPool.class) { if (pool == null) { pool = new Neo4jPool(); } } } return pool.getConnection(); } // 关闭连接 public static void freeConnection(ResultSet rs, Statement ps, Connection con) throws SQLException { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } finally { try { if (ps != null) { ps.close(); } } catch (Exception e) { e.printStackTrace(); } finally { if (con != null) { pool.freeConnection(con); } } } } // 关闭连接 public static void freeConnection(Connection con) throws SQLException { if (con != null) { pool.freeConnection(con); } } }
neo4jTest.java
package com.chengshu.neo4j; import java.sql.Connection; import java.sql.ResultSet; import java.sql.Statement; import java.util.Date; import java.util.Random; import com.chengshu.constant.NodeTypeEnum; import com.chengshu.constant.RelationTypeEnum; import com.chengshu.tools.DateUtils; /** * @author 张彦 * @email: [email protected] * @date 创建时间:2017年2月22日 上午10:04:54 * @version 1.0 */ public class Neo4jTest { // 创建节点 private static Integer createNode(String nodeName, String type) throws Exception { // String neoCreate = "create (o:" + Type + "{name:\"" + nodeName + "\"}) return ID(o) as id "; StringBuffer neoCreate = new StringBuffer(); neoCreate.append("create (o:"); neoCreate.append(type); neoCreate.append("{name:'"); neoCreate.append(nodeName); neoCreate.append("'}) return ID(o) as id "); Connection conn = Neo4jUtil.getConnection(); Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(neoCreate.toString()); Integer id = null; while (rs.next()) { id = rs.getInt("id"); } Neo4jUtil.freeConnection(null, statement, conn); return id; } // 获取节点 private static Integer getNode(String nodeName, String type) throws Exception { // String neoMatch = "match (o: " + type + " {name:\"" + nodeName + "\"}) return o.name,ID(o) as id"; StringBuffer neoMatch = new StringBuffer(); neoMatch.append("match (o: "); neoMatch.append(type); neoMatch.append("{name:'"); neoMatch.append(nodeName); neoMatch.append("'}) return o.name,ID(o) as id"); Connection conn = Neo4jUtil.getConnection(); Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(neoMatch.toString()); Integer id = null; while (rs.next()) { id = rs.getInt("id"); } Neo4jUtil.freeConnection(null, statement, conn); return id; } // 添加关注关系 private static void addRelationShip(Integer orgId, Integer personId, String relationType) { // String neoRelation = "start a=node(" + orgId + "),b=node(" + personId + ") create (a)-[n:"+relationType+"]->(b)"; StringBuffer neoRelation = new StringBuffer(); neoRelation.append("start a=node("); neoRelation.append(orgId); neoRelation.append("),b=node("); neoRelation.append(personId); neoRelation.append(") create (a)-[n:"); neoRelation.append(relationType); neoRelation.append("{status:1,createTime:'"); neoRelation.append(DateUtils.getSysDate(DateUtils.FULL_DATE_PATTERN)); neoRelation.append("'}]->(b)"); try { Connection conn = Neo4jUtil.getConnection(); Statement statement = conn.createStatement(); statement.execute(neoRelation.toString()); Neo4jUtil.freeConnection(null, statement, conn); } catch (Exception e) { e.printStackTrace(); } } private static Integer related(String orgNode, String personNode, String relationType) { // String related = "Match (n:org)-[r:"+relationType+"]->(p:person) where n.name='" + orgNode + "' and p.name='" + personNode + "' return p"; StringBuffer related = new StringBuffer(); related.append("Match (n:org)-[r:"); related.append(relationType); related.append("]->(p:person) where n.name='"); related.append(orgNode); related.append("' and p.name='"); related.append(personNode); related.append("' return p"); try { Connection conn = Neo4jUtil.getConnection(); Statement statement = conn.createStatement(); ResultSet rs = statement.executeQuery(related.toString()); int count = 0; while (rs.next()) { count++; } Neo4jUtil.freeConnection(null, statement, conn); return count; } catch (Exception e) { e.printStackTrace(); } return null; } private static boolean updateRelationShip(String orgNode, String personNode, String relationType, Integer flag){ StringBuffer update = new StringBuffer(); update.append("MATCH (o)-[rel:"); update.append(relationType); update.append("]->(p) WHERE o.name='"); update.append(orgNode); update.append("' and p.name = '"); update.append(personNode); update.append("' SET rel.status="); update.append(flag); update.append(", rel.updateTime='"); update.append(DateUtils.getSysDate(DateUtils.FULL_DATE_TIME)); update.append("'"); try { Connection conn = Neo4jUtil.getConnection(); Statement statement = conn.createStatement(); boolean result = statement.execute(update.toString()); Neo4jUtil.freeConnection(null, statement, conn); return result; } catch (Exception e) { e.printStackTrace(); } return false; } private static void relationShip(String orgNode, String personNode, String relationType) { boolean flag = false; Integer orgId; Integer personId; try { orgId = getNode(orgNode, NodeTypeEnum.org.getType()); if (orgId == null) { flag = true; orgId = createNode(orgNode, NodeTypeEnum.org.getType()); } personId = getNode(personNode, NodeTypeEnum.person.getType()); if (personId == null) { flag = true; personId = createNode(personNode, NodeTypeEnum.person.getType()); } if (flag || related(orgNode, personNode, RelationTypeEnum.observer.getType()) == 0) { addRelationShip(orgId, personId, RelationTypeEnum.observer.getType()); } } catch (Exception e) { e.printStackTrace(); } } private static String getRandom() { double a = Math.random(); int i = (int) (a * 1000000 + 1000000); String messageCode = String.valueOf(i); return messageCode; } public static String GetRandomString(int Len) { String[] baseString = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "楮", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水" }; Random random = new Random(); int length = baseString.length; String randomString = ""; for (int i = 0; i < length; i++) { randomString += baseString[random.nextInt(length)]; } random = new Random(System.currentTimeMillis()); String resultStr = ""; for (int i = 0; i < Len; i++) { resultStr += randomString.charAt(random.nextInt(randomString.length() - 1)); } return resultStr; } public static void main(String[] args) { System.out.println(new Date()); try { // int i; // for (i = 0; i < 1; i++) { // String org = GetRandomString(1); // if (i % 1000 == 0) { // System.out.println(org); // } // String person = getRandom(); // relationShip(org, person, RelationTypeEnum.observer.getType()); // } relationShip("juxinli", "zhangyan", RelationTypeEnum.observer.getType()); // createNode("juxinli", NodeTypeEnum.person.getType()); // getNode("zhangyan", NodeTypeEnum.person.getType()); // relationShip("juxinli", "maomao", updateRelationShip("juxinli","zhangyan",RelationTypeEnum.observer.getType(),0); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(new Date()); } }
测试结果
测试 机构名10位,用户名6位
第一个 10000条
Wed Feb 22 16:07:15 CST 2017
Wed Feb 22 16:13:20 CST 2017
6分05秒
第二个 10000条
Wed Feb 22 16:14:44 CST 2017
Wed Feb 22 16:22:38 CST 2017
7分54秒
第三个 10000条
测试 机构名1位,用户名3位
Wed Feb 22 16:26:03 CST 2017
Wed Feb 22 16:35:43 CST 2017
9分40秒
机构100,用户1000000
Wed Feb 22 17:26:47 CST 2017 0
Wed Feb 23 10:27:47 CST 2017 322000 30分钟10733条 一分钟358条
Wed Feb 23 17:17:20 CST 2017 389000