[英]How to share a databse connection among classes? (JDBC)
我试图弄清楚如何在类之间共享与数据库的已建立连接以执行不同的SQL语句。 我通读了一些主题,但是由于我是编程的新手,因此很难适应给定的信息以解决我的问题。
问题:我有两个类,一个类打开与数据库的连接,执行一些SQL语句,然后调用另一个类仅使用不同的表和SQL语句执行相同的操作。 现在,只要我使用自己的主方法和连接分别运行这些类,一切就可以正常工作。 但是当一个类调用另一个类时,我会得到不同的异常,这取决于到目前为止我尝试过的解决方法( MySQLNonTransientConnectionException:数据源拒绝建立连接或StackOverflowException )。
这是我尝试建立的连接,该连接用于执行两个不同类中的某些sql操作:
public ClassA{
public static Connection dbConn;
//Set up a connection to the database
String dbURL = "jdbc:mysql://<some database>"; //put host, port and database here
Properties connectionProbs = new Properties();
connectionProbs.put("user", "root"); //insert USER here
connectionProbs.put("password", "root"); //insert PASSWORD here
dbConn = null;
try{
dbConn = DriverManager.getConnection(dbURL, connectionProbs);
PreparedStatement useStmt;
try{
useStmt = dbConn.prepareStatement("USE <some database>"); //insert DATABASE here
useStmt.executeUpdate();
}
catch(SQLException e){
e.printStackTrace();
}
//Do some SQL operations
//Call class B to do some SQL operations using the same connection
}
catch(SQLException e){
System.err.println("There was a problem connecting to the database");
e.printStackTrace();
}
finally{
if(dbConn != null)
try{dbConn.close();}catch(SQLException e){e.printStackTrace();}
}
}
为什么类B无法使用类A的连接,例如通过执行以下操作(这会导致StackOverflow):
PreparedStatement Stmt = ClassA.dbConn.prepareStatement("INSERT INTO table(ID, name) VALUES (?,?)");
另一方面,如果我试图建立到同一数据库(同时运行)的两个单独的Connections(使用与上面相同的代码)(同时运行),则会得到MySQLNonTransientConnectionException:数据源拒绝建立连接。
处理此问题的最佳方法是什么? 我在论坛上偶然发现了ConnectionPooling,但找不到适合初学者的资料来详细说明如何将其付诸实践。 是否有一种直接的方法来确保不同的类可以连接并在一个数据库上运行?
感谢您的任何反馈
我会避免将连接放在静态变量中。 在您的特定实例中,这并没有太大的区别,但是最好不要养成那样的习惯。
您应该创建一个控制类,然后创建数据库连接,然后将其作为方法参数传递给其他两个类。 这样,控制类可以处理其他类抛出的任何异常,并确保正确关闭了连接。
您可以通过为Class A中的Connection创建一个非静态全局变量,然后创建一个非静态public方法来返回此连接来实现,如下所示。
public ClassA{
// non-static global private Connection object
private Connection dbConn = null;
// non-static public method to get dbConn connection object
public Connection getConnection() {
// this condition will check if the Connection is not already open then open it.
if(null == dbConn) {
//Set up a connection to the database
String dbURL = "jdbc:mysql://<some database>"; //put host, port and database here
Properties connectionProbs = new Properties();
connectionProbs.put("user", "root"); //insert USER here
connectionProbs.put("password", "root"); //insert PASSWORD here
try{
dbConn = DriverManager.getConnection(dbURL, connectionProbs);
PreparedStatement useStmt;
try{
useStmt = dbConn.prepareStatement("USE <some database>"); //insert DATABASE here
useStmt.executeUpdate();
}
catch(SQLException e){
e.printStackTrace();
}
//Do some SQL operations
//Call class B to do some SQL operations using the same connection
}
catch(SQLException e){
System.err.println("There was a problem connecting to the database");
e.printStackTrace();
}
finally{
if(dbConn != null)
try{dbConn.close();}catch(SQLException e){e.printStackTrace();}
}
}
return dbConn;
}
}
然后在B类中,您可以执行以下操作。
A a = new A();
PreparedStatement Stmt = a.getConnection().prepareStatement("INSERT INTO table(ID, name) VALUES (?,?)");
希望这可以帮助你。
您应该创建一个控制类,然后创建数据库连接,然后将其作为方法参数传递给其他两个类。
public class ConnectionManager {
private static String url = "jdbc:mysql://localhost:3306/DbName";
private static String username = "YourUsername";
private static String password = "yourDbPass";
private static Connection con;
public static Connection getConnection() throws Exception {
con = DriverManager.getConnection(url, username, password);
return con;
}
}
public class main {
public static void main(String[] args) throws Exception {
Connection con = null;
con = ConnectionManager.getConnection();
CrudCity s = new CrudCity();
s = s.read(con);
System.out.println(s);
CrudCountry c = new CrudCountry();
c = c.read(con);
System.out.println(c);
CrudCountryLanguage lang = new CrudCountryLanguage();
lang = lang.read(con);
System.out.println(lang);
}
}
public class CrudCity extends City implements CrudInterface {
public CrudCity read(Connection con) throws Exception{
CrudCity p = new CrudCity();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT ID,Name,CountryCode FROM world.city");
while (rs.next()) {
p.setId(rs.getInt("ID"));
p.setName(rs.getString("Name"));
p.setCountryCode(rs.getString("CountryCode"));
}
rs.close();
return p;
}
}
public class CrudCountry extends Country implements CrudInterface{
public CrudCountry read(Connection con) throws Exception{
CrudCountry c = new CrudCountry();
Statement stmt =con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT Code,Name,Continent FROM world.country");
while (rs.next()) {
c.setCountryCode(rs.getString("Code"));
c.setCountryName(rs.getString("Name"));
c.setCodeContinent(rs.getString("Continent"));
}
rs.close();
return c;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.