import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
import java.util.LinkedList;
import java.util.Timer;
import java.util.TimerTask;
/**
* Neo4j连接池
* Created by xuliugen on 2017/10/19.
*/
public class Neo4jPool {
private static final Logger LOG = LoggerFactory.getLogger(Neo4jPool.class);
/**
* 最大连接数
*/
private static final int NEO4J_CONN_MAX_LINK = 20;
/**
* 最小连接数
*/
private static final int NEO4J_CONN_MIN_LINK = 5;
/**
* 每次增长的连接数
*/
private static final int NEO4J_CONN_INCREASE_LINK = 5;
/**
* 链接超时时间
*/
private static final int NEO4J_CONN_TIMER = 60000;
//HTTP Driver
private static final String NEO4J_BOLT_URL = "jdbc:neo4j:http://192.168.1.196:7474";
private static final String NEO4J_USERNAME = "neo4j";
private static final String NEO4J_PASSWORD = "neo4j";
/**
* 当前连接数
*/
private static int connectionCurrLink = 0;
private static LinkedList
datasourcePool = new LinkedList<>();
static {
try {
Class.forName("org.neo4j.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
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 = 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 (Exception e) {
e.printStackTrace();
}
}
}, 0, NEO4J_CONN_TIMER);
}
/**
* 创建连接
* @param type
* @throws Exception
*/
private static void createConnection(int type) throws Exception {
try {
int link = 0;
switch (type) {
case 0:
link = NEO4J_CONN_MIN_LINK;
break;
case 1:
// 如果当前连接+增长连接大于设定的最大连接数时,将使用最大连接数-当前连接的数量。以保持平衡
link = NEO4J_CONN_INCREASE_LINK;
int maxLink = NEO4J_CONN_MAX_LINK;
if (link + connectionCurrLink > maxLink) {
link = maxLink - connectionCurrLink;
}
break;
}
for (int i = 0; i < link; i++) {
datasourcePool.addLast(DriverManager.getConnection(NEO4J_BOLT_URL, NEO4J_USERNAME, NEO4J_PASSWORD));
connectionCurrLink++;
}
} catch (NumberFormatException n) {
throw new NumberFormatException("配置连接参数有误");
} catch (Exception e) {
e.printStackTrace();
throw new SQLException("超过最大连接数 ,无法创建更多连接");
}
}
/**
* 获得连接
* @return
* @throws Exception
*/
public static Connection getConnection() throws Exception {
// 取连接加锁,防止并发取的同样的连接
synchronized (datasourcePool) {
if (datasourcePool.size() > 0) {
return datasourcePool.removeFirst();
} else if (connectionCurrLink < 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();
}
/**
* 释放连接
* @param con
*/
public void freeConnection(Connection con) {
datasourcePool.addLast(con);
}
public static void main(String[] args) {
try {
Connection conn = Neo4jPool.getConnection();
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("MATCH (n) RETURN n LIMIT 1");
while (rs.next()) {
System.out.println(rs.getString("n.name"));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}