2

我使用 jboss 服务器和 postgresql 作为数据库。现在我每次都在 servlet 中连接到数据库,如下所示:

public void doPost(HttpServletRequest req, HttpServletResponse resp)
{
Connection conn =null; // Create connection object
             String database = "jbossdb"; // Name of database
             String user = "qwerty"; //
             String password = "qwerty";
             String url = "jdbc:postgresql://localhost:5432/" + database;
             ResultSet rs = null;
             ResultSetMetaData rsm = null;
             ObjectInputStream in=new ObjectInputStream(req.getInputStream());
             String input=(String) in.readObject();
             String[] s_input=input.split(",");

              try{
                    Class.forName("org.postgresql.Driver").newInstance();
                    //.newInstance()
                 } catch(Exception e) 
                    {
                    System.err.println(e);
                    }

            try{
                conn = DriverManager.getConnection(url, user, password);

                }catch(SQLException se) 
                 {
                        System.err.println(se);
                 }

此代码存在于我的每个服务器中。对于每个请求,都会创建一个新的连接对象。这会影响性能吗?在 jboss 中有什么方法可以只初始化一次连接(可能在启动时),然后在需要时传递给 servlet?我应该把它放在init()servlet的方法中吗?

4

2 回答 2

5

一个更好的方法是使用连接池。您还需要确保正确关闭连接(如果发生这种情况,您的代码尚不清楚,仍然需要使用池来完成)。至于存储连接,这并不是一个好主意,因为您的 servlet 是多线程的(我很难学到这一点),并且您需要同步所有访问,这将是一场灾难。

http://geekexplains.blogspot.co.uk/2008/06/what-is-connection-pooling-why-do-we.html

http://confluence.atlassian.com/display/DOC/Configuring+a+PostgreSQL+Datasource+in+Apache+Tomcat

http://www.devdaily.com/blog/post/java/how-configure-tomcat-dbcp-connection-pool-pooling-postgres

--EDIT-- 为什么不在“init()”中做呢?

了解“servlet 的生命周期”。

init() 仅在容器设置 servlet 时调用一次。

每个请求都使用相同的 servlet,而不是每个请求的新实例。所以 init() 不会被请求调用。

由于每个请求都由同一个 servlet 实例处理,因此您的代码需要是多线程的。

于 2012-05-15T10:14:32.910 回答
5

您在这里可能不是一个好的解决方案。当您使用 servlet 来执行应用程序加载的操作时,您可以拥有侦听器。您要做的是,首先创建一个实现ServletContextListener的类。

public class ContextListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context=sce.getServletContext();
        String dburl=context.getInitParameter("dbUrl");
        String dbusername=context.getInitParameter("dbUserName");
        String dbpassword=context.getInitParameter("dbPassword");
        
        DBConnector.createConnection(dburl, dbusername, dbpassword);
        System.out.println("Connection Establised.........");
    }

    public void contextDestroyed(ServletContextEvent sce) {
        DBConnector.closeConnection();
    }
    
}

之后,您可以创建另一个类以在应用程序加载时创建连接。

public class DBConnector {
    
    private static Connection con;
    
    public static void createConnection(String dbUrl,String dbusername,String dbPassword){
        try {
            Class.forName("org.postgresql.Driver");
            con=DriverManager.getConnection(dbUrl, dbusername, dbPassword);     
        } catch (Exception ex) {
            ex.printStackTrace();
        }    
    }
    
    public static Connection getConnection(){
        return con;
    }
    
    public static void closeConnection(){
        if(con!=null){
            try {
                con.close();
            } catch (SQLException ex) {
                 ex.printStackTrace();
            }
        }
    
    }
    
    
    
}

然后,当您想要获取数据库连接时,您可以调用静态 getConnection 方法并获取它。为了调用您的侦听器类,您必须在 web.xml 中添加侦听器标签。

<context-param>
    <param-name>dbUrl</param-name>
    <param-value>jdbc:postgresql://localhost:5432/jbossdb</param-value>
</context-param>
<context-param>
    <param-name>dbUserName</param-name>
    <param-value>qwerty</param-value>
</context-param>
<context-param>
    <param-name>dbPassword</param-name>
    <param-value>qwerty</param-value>
</context-param>
<listener>
    <listener-class>com.icbt.bookstore.listener.ContextListener</listener-class>
</listener>

硬编码您的数据库用户名和密码不是一个好习惯。相反,您可以使用 web.xml 中的 servlet 初始化参数,如图所示。

希望,这回答了你的问题。

于 2012-05-15T10:19:39.417 回答