`

JDBC连接池 (neo4j)

阅读更多

公司突然让用neo4j做一个 机构关注用户的功能,要用neo4j的图数据库实现。于是乎我的忙碌就开始了。

 

搜了一些资料,发现neo4j的数据库连接方式有两种,一种是原生太的javaAPI的方式,神奇的发现居然有JDBC的连接方式,由于时间紧迫,毫无疑问选择我熟悉的JDBC咯~~!

 

优点:以图的方式来表达节点之间的关系,层级关系查询较快。

缺点:单机版的最多几十万条,就相当慢了本文后面有测试结果。企业版的不免费

 

引入maven包

<!-- https://mvnrepository.com/artifact/org.neo4j/neo4j-kernel -->

<dependency>

   <groupId>org.neo4j</groupId>

   <artifactId>neo4j-kernel</artifactId>

   <version>3.1.1</version>

</dependency>

 

<!-- https://mvnrepository.com/artifact/org.neo4j/neo4j-cypher -->

<dependency>

   <groupId>org.neo4j</groupId>

   <artifactId>neo4j-cypher</artifactId>

   <version>3.1.1</version>

</dependency>

 

<dependency>

   <groupId>org.neo4j</groupId>

   <artifactId>neo4j-jdbc-driver</artifactId>

   <version>3.0</version>

</dependency>

 

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: zhangyan1@juxinli.com
 * @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<String, String> map = new HashMap<String, String>();

    // 当前 连接数
    static int connectionCurrLink = 0;

    private static LinkedList<Connection> datasourcePool = new LinkedList<Connection>();

   

    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<Object> dataSourceSet = args_properties.keys();
            while (dataSourceSet.hasMoreElements()) {
                String key = (String) dataSourceSet.nextElement();
                map.put(key, args_properties.getProperty(key));
            }
        } catch (IOException e) {
        }
        LOG.info("#init_serverconfig");
        LOG.info("#读取 args 配置文件");
    }

    public Neo4jPool() {
        try {
            createConnection(0);
        } catch (Exception e1) {
            LOG.error("创建连接失败", e1);
        }
        // 通过构造函数启动定时器以达到定时释放空闲连接目的
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    // 得到空闲连接,datasourcePool里面有几个对象就表示有几个空闲连接
                    int leisureLink = Neo4jPool.datasourcePool.size();
//                    System.out.println(leisureLink);
                    // 最小连接数
                    int connectionMinLink = Integer.parseInt(Neo4jPool.map.get("neo4j_conn_min_link"));
                    // 当空闲连接大于DataSourcePool设置的最小连接数时则关闭
                    if (leisureLink > connectionMinLink) {
                        for (int i = 0; i < leisureLink - connectionMinLink; i++) {
                            Neo4jPool.closeConnection(Neo4jPool.getConnection());
                            connectionCurrLink--;
                        }
                    } else {
//                        System.out.println("保持最小连接,将继续保持连接池");
                    }
                } catch (NumberFormatException e) {
                    throw new NumberFormatException("设置了无效的最小连接数");
                } catch (SQLException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 0, Long.parseLong(map.get("neo4j_conn_timer")));

    }

    // 创建连接
    private static void createConnection(int type) throws Exception {
        try {
            int link = 0;
            switch (type) {
            case 0:
                link = Integer.parseInt(map.get("neo4j_conn_min_link"));
                break;
            case 1:
                // 如果当前连接+增长连接大于设定的最大连接数时,将使用最大连接数-当前连接的数量。以保持平衡
                link = Integer.parseInt(map.get("neo4j_conn_increase_link"));
                int maxLink = Integer.parseInt(map.get("neo4j_conn_max_link"));
                if (link + connectionCurrLink > maxLink) {
                    link = maxLink - connectionCurrLink;
                }
                break;
            }
            for (int i = 0; i < link; i++) {
                datasourcePool.addLast(DriverManager.getConnection(map.get("neo4j_url"), map.get("neo4j_username"), map.get("neo4j_password")));
                connectionCurrLink++;
            }
        } catch (NumberFormatException n) {
            throw new NumberFormatException("配置连接参数有误");
        } catch (Exception e) {
            e.printStackTrace();
            throw new SQLException("超过最大连接数 ,无法创建更多连接");
        }
    }

    // 获得连接
    public static Connection getConnection() throws Exception {
        // 取连接加锁,防止并发取的同样的连接
        synchronized (datasourcePool) {
            if (datasourcePool.size() > 0) {
                return datasourcePool.removeFirst();
            } else if (connectionCurrLink < Integer.parseInt(map.get("neo4j_conn_max_link"))) {
                createConnection(1);
                return datasourcePool.removeFirst();
            }
        }
        return null;
    }

    /**
     * 关闭连接
     * 
     * @param con
     * @throws SQLException
     */
    public static void closeConnection(Connection con) throws SQLException {
        con.close();
    }

    // 释放连接
    public void freeConnection(Connection con) {
        datasourcePool.addLast(con);
    }

    public static void main(String[] args) {
        Neo4jPool pool = new Neo4jPool();
        try {
            Connection conn = pool.getConnection();
            // Querying
            try (Statement stmt = conn.createStatement()) {
                ResultSet rs = stmt.executeQuery("MATCH (n:Person) RETURN n.name");
                while (rs.next()) {
                    System.out.println(rs.getString("n.name"));
                }
            }
        } catch (Exception e) {

            e.printStackTrace();
        }

    }

//    public static void main(String[] args) throws Exception {
//        // Make sure Neo4j Driver is registered
//        Class.forName("org.neo4j.jdbc.Driver");
//        // Connect
//        // Connection con =
//        DriverManager.getConnection("jdbc:neo4j://localhost:7474/", "neo4j", "123456");
//        Connection con = DriverManager.getConnection("jdbc:neo4j:bolt://localhost/", "neo4j", "123456");
//
//        // Querying
//        try (Statement stmt = con.createStatement()) {
//            ResultSet rs = stmt.executeQuery("match (p:Person) return p.name");
//            while (rs.next()) {
//                System.out.println(rs.getString("p.name"));
//            }
//        }
//    }

}

 

Neo4jUtil.java

package com.chengshu.neo4j;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


/**
 * @author 张彦
 * @email: zhangyan1@juxinli.com
 * @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: zhangyan1@juxinli.com
 * @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

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics