使用JERSEY的MySQL连接池
我正在用Jersey和MySQL开发一个RESTful API 实际上,我正在使用JDBC驱动程序连接数据库,每次我想访问它时,我都会创建一个新的连接。由于这显然是内存泄漏,我开始实现使用JERSEY的MySQL连接池,mysql,jdbc,jersey,connection-pooling,Mysql,Jdbc,Jersey,Connection Pooling,我正在用Jersey和MySQL开发一个RESTful API 实际上,我正在使用JDBC驱动程序连接数据库,每次我想访问它时,我都会创建一个新的连接。由于这显然是内存泄漏,我开始实现ServletContextClass类,但我不知道在需要获取SQL查询结果时如何调用该方法 以下是我是如何做错的: DbConnection.java 公共类数据库连接{ public Connection getConnection() throws Exception { try {
ServletContextClass
类,但我不知道在需要获取SQL查询结果时如何调用该方法
以下是我是如何做错的:
DbConnection.java
公共类数据库连接{
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
}
catch (SQLException e) {
throw e;
}
}
}
DbData.java
public ArrayList<Product> getAllProducts(Connection connection) throws Exception {
ArrayList<Product> productList = new ArrayList<Product>();
try {
PreparedStatement ps = connection.prepareStatement("SELECT id, name FROM product");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Product product = new Product();
product.setId(rs.getInt("id"));
product.setName(rs.getString("name"));
productList.add(product);
}
return productList;
} catch (Exception e) {
throw e;
}
}
@GET
@Path("task/{taskId}")
@Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(@PathParam("taskId") int taskId) throws Exception {
try {
DbConnection database= new DbConnection();
Connection connection = database.getConnection();
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
public class ServletContextClass implements ServletContextListener {
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
} catch (SQLException e) {
throw e;
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
DbConnection database = new DbConnection();
try {
Connection connection = database.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
//con.close ();
}
}
下面是我尝试实现新类的地方:
ServletContextClass.java
public ArrayList<Product> getAllProducts(Connection connection) throws Exception {
ArrayList<Product> productList = new ArrayList<Product>();
try {
PreparedStatement ps = connection.prepareStatement("SELECT id, name FROM product");
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Product product = new Product();
product.setId(rs.getInt("id"));
product.setName(rs.getString("name"));
productList.add(product);
}
return productList;
} catch (Exception e) {
throw e;
}
}
@GET
@Path("task/{taskId}")
@Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(@PathParam("taskId") int taskId) throws Exception {
try {
DbConnection database= new DbConnection();
Connection connection = database.getConnection();
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
public class ServletContextClass implements ServletContextListener {
public Connection getConnection() throws Exception {
try {
String connectionURL = "jdbc:mysql://root:port/path";
Connection connection = null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
return connection;
} catch (SQLException e) {
throw e;
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
DbConnection database = new DbConnection();
try {
Connection connection = database.getConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
//con.close ();
}
}
但问题是,我不知道下一步该怎么办。有什么帮助吗?谢谢你,你需要将连接变量设置为
ServletContext
的属性。另外,我建议你使用Connection
作为静态类变量,这样你就可以在contextdestromed
方法中关闭它。
稍后,您可以在任何servlet中检索connection
属性,以便执行DB操作
public class ServletContextClass implements ServletContextListener {
public static Connection connection;
public Connection getConnection(){
try {
String connectionURL = "jdbc:mysql://root:port/path";
Class.forName("com.mysql.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL, "root", "password");
} catch (SQLException e) {
// Do something
}
}
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("ServletContextListener started");
getConnection();
arg0.getServletContext().setAttribute("connection", connection);
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("ServletContextListener destroyed");
try{
if(connection != null){
connection.close();
}
}catch(SQLException se){
// Do something
}
}
}
最后访问Servlet(资源)中的连接
属性。确保将@Context-ServletContext
传递给响应
方法,以便访问上下文属性
@GET
@Path("task/{taskId}")
@Consumes(MediaType.APPLICATION_JSON)
public Response getInfos(@PathParam("taskId") int taskId, @Context ServletContext context) throws Exception {
try {
Connection connection = (Connection) context.getAttribute("connection");
Task task = new Task();
DbData dbData = new DbData();
task = dbData.getTask(connection, taskId);
return Response.status(200).entity(task).build();
} catch (Exception e) {
throw e;
}
}
现在我们已经解决了您当前的问题,我们需要知道这种方法会出现什么问题
首先,您只创建一个连接
对象,该对象将在任何地方使用。想象多个用户同时访问您的API,单个连接
将在所有用户之间共享,这将降低您的响应时间
其次,您到DB的连接将在闲置一段时间后终止(除非您将MySql
服务器配置为不终止空闲连接,这不是一个好主意),当您尝试访问它时,会抛出SQLException
s。这可以在servlet中解决,您可以检查连接是否已断开,重新创建连接,然后更新context属性
使用Mysql连接池的最佳方法是使用JNDI资源。您可以创建一个连接池
,该连接池将由servlet容器
管理。您可以配置该池,以便在连接闲置后失效时重新创建连接。如果您使用Tomcat作为servlet容器,您可以k了解JNDI连接池的简短教程。谢谢@imranarshad,我刚刚在getConnection()
函数中得到了一个返回值和一些catch
,但它可以工作。我将查看您消息的第二部分。这是一个很好的建议