2

i am using jboss server and postgresql as the database. Right now I am connecting to the database each time in the servlet like this:

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);
                 }

This code is present in every servet of mine. For each request a new connection object is made. Will this affect performance? Is there any way in jboss where the connection can be initialized only once(possibly on startup) and then passed on to the servlets when required? Should I put it in the init() method of servlet?

4

2 に答える 2

5

これを行うためのはるかに優れた方法は、接続プールを使用することです。また、接続を適切に閉じることを確認する必要があります (これが発生している場合、コードからは明確ではありません。プールを使用する必要があります)。接続の保存に関しては、サーブレットがマルチスレッドであるため(私はこれを難しい方法で学びました)、すべてのアクセスを同期する必要があるため、これは実際には良い考えではありません。

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()」でやらないのですか?

「サーブレットのライフサイクル」について学びます。

init() は、コンテナによってサーブレットがセットアップされるときに 1 回だけ呼び出されます。

各リクエストは、リクエストごとに新しいインスタンスではなく、同じサーブレットを使用しています。そのため、リクエストに対して init() は呼び出されません。

各リクエストは同じサーブレット インスタンスによって処理されるため、コードをマルチスレッド化する必要があります。

于 2012-05-15T10:14:32.910 に答える
5

あなたがここで持っているのはおそらく良い解決策ではありません。アプリケーションがロードする何かを行うためにサーブレットを使用している場合、リスナーを使用できます。あなたがしなければならないことは、最初に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();
            }
        }
    
    }
    
    
    
}

その後、db 接続を取得したいときはいつでも、静的な 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 でサーブレットの初期化パラメーターを使用できます。

希望、これはあなたの質問に答えます。

于 2012-05-15T10:19:39.417 に答える