公司突然让用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 Map map = 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