proxool池应用

来源:互联网 发布:音悦台mac版 编辑:程序博客网 时间:2024/04/29 00:03
    01.  proxool属于第三方驱动了,所以要是使用的话,要下载它的jar包http://sourceforge.net/projects/proxool,我 使用的是proxool-0.8.3.jar,所以这里就以proxool-0.8.3.jar为例。下载proxool-0.8.3.jar后就要把他放在/WEB-INF/lib下。这样就能找到驱动了。

      02.  编辑web.xml文件,加入下面的语句:

 <servlet>
  <servlet-name>proxool</servlet-name>
  <servlet-class>org.logicalcobwebs.proxool.admin.servlet.AdminServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>proxool</servlet-name>
  <url-pattern>/Admin/proxool,./</url-pattern>
</servlet-mapping>

这样你执行执行http://localhost:8080/proxool-test/Admin/proxool,./( proxool-test 是你的应用名称 ),这样你就可以监控 connection pooling 的状态了。

    03.  proxool.xml文件的编写:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- the proxool configuration can be embedded within your own application's.
Anything outside the "proxool" tag is ignored. -->
<something-else-entirely>
  <proxool>
    <alias>xml-db</alias>
    <driver-url>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=shop</driver-url>
    <driver-class>com.microsoft.jdbc.sqlserver.SQLServerDriver</driver-class>
    <driver-properties>
      <property name="user" value="sa"/>
      <property name="password" value="sa"/>
    </driver-properties>
        <!--minimum-connection-count>2</minimum-connection-count-->
    <maximum-active-time>30000</maximum-active-time>
 <maximum-connection-count>100</maximum-connection-count>
 <maximum-connection-lifetime>15000</maximum-connection-lifetime> <!-- 5 hours -->
  </proxool>
</something-else-entirely>

    04.  要使用这个驱动就要用到2个类,DBConnectionPoolManager.java和Conn.java,Conn.java调用DBConnectionPoolManager.java,

DBConnectionPoolManager.java代码如下:

 import java.sql.*;
 import org.logicalcobwebs.proxool.configuration.JAXPConfigurator;
 import java.io.*;
 
 public class DBConnectionPoolManager {    
     private static DBConnectionPoolManager dbcpm = null;
     private Connection con = null;
     
     private  DBConnectionPoolManager() {
        InputStream is = getClass().getResourceAsStream("/proxool.xml");
        try{         
            JAXPConfigurator.configure(new InputStreamReader(is), false);
            System.out.println("Configuration file(proxool.xml) has been loaded !");
        }catch(Exception e){ 
          System.out.println("Load Configuration failed ! " + e.getMessage());
              }finally{
              try{ 
                  is.close();
                   }catch(Exception ex){}
              }
     }
     static synchronized public  DBConnectionPoolManager getInstance(){
        if(null==dbcpm)
             dbcpm =new DBConnectionPoolManager();
         return dbcpm;
       }
     public Connection getConnection(){
         try{ 
             con = DriverManager.getConnection("proxool.xml-db");
             }catch(Exception e){
                   System.out.println("Connection failed ! "+e.getMessage());
               }
           return con;
       }
   
 } 

Conn.java代码如下:

import java.sql.*;
import com.dcon.DBConnectionPoolManager;

public class Conn
{
 private DBConnectionPoolManager dbc = null;

 private Connection con = null;

 private PreparedStatement ps = null;

 private Statement stmt = null;

 private ResultSet rs = null;

 public Conn()
 {
  dbc = DBConnectionPoolManager.getInstance();
 }

 public PreparedStatement prepareStatement(String sql) throws SQLException
 {
  try
  {
   con = dbc.getConnection();
   ps = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
     ResultSet.CONCUR_UPDATABLE);
   return ps;
  }
  catch (Exception e)
  {
   e.printStackTrace();
   System.out.println("psDBA exception !");
   return null;
  }
 }

 public Statement createStatement() throws SQLException
 {
  try
  {
   con = dbc.getConnection();
   stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
     ResultSet.CONCUR_UPDATABLE);
   return stmt;
  }
  catch (Exception e)
  {
   e.printStackTrace();
   System.out.println("stDBA exception !");
   return null;
  }
 }

 public ResultSet resultSet(String sql) throws SQLException
 {
  rs = createStatement().executeQuery(sql);
  return rs;
 }

 public void close()
 {
  try
  {
    if(rs!=null) {rs.close();}
    if(stmt!=null){stmt.close();}
    if(ps!=null) {ps.close();}
   if (con != null)
   {
    con.close();
   }
  }
  catch (Exception e)
  {
  }
 }
}
使用方法就是使用Conn.java的prepareStatement和createStatement方法。

    03.  使用prepareStatement和createStatement方法一般就是下面这种情况:

   PreparedStatement ps=dbc.prepareStatement("select * from tt");
   rs=ps.executeQuery();
   while(rs.next())
   {
    Test test=new Test();
    test.setId(rs.getInt("id"));
    test.setName(rs.getString("name"));
   }

原来的方法是:

   Statement st=con.createStatement();
   rs=st.executeQuery("select * from tt");
   while(rs.next())
   {
    Test test=new Test();
    test.setId(rs.getInt("id"));
    test.setName(rs.getString("name"));
   }

大家可以参考一下。

    05.  慎用或尽量不要用微软自带的sqlserver的jdbc驱动。在商业应用中,很少有公司真正实用微软的那个什么com.microsoft.jdbc.sqlserver.SQLServerDriver。

    其实发现微软驱动的不足,也是很偶然的机会。在一次移植应用中,系统报告了[Microsoft][SQLServer JDBC Driver]ResultSet can not re-read row data for column之类的错误。为了解决这个错误,跟踪程序忙了大半天,也没有查出问题所在。只能确定在在rs.getString("XXX")的时候必然会出现错误(rs为ResultSet对象)。那么现在就模拟以下当时的环境:
    数据库表:TestTable
    表字段及类型:
         guid char(38)
         title varchar(100)
         content Text
         username varchar(20)
    查询sql语句:
         select guid,username,content,title from TestTable where····
    java代码:
         rs.getString("guid");
         rs.getBinaryStream("content");
         rs.getString("username");
    -----------------------------------------------------------

    上面那段代码,很不荣幸是。使用微软的驱动,必然会报错(就是上面说的那个错误)。如果你跟踪的话,必然是这一行:rs.getString("username")抛出错误。

    那么,如果你把rs.getString("username")和rs.getBinaryStream("content");位置互换以下,会怎么样呢。结果就是可以正常运行。

    为什么会出现这种情况呢,因为微软的驱动,在包含了blob或clob类型(就是Image和Text类型)的字段。那么就必须按照select顺序查询,且不支持重复查询。

原创粉丝点击