`
xpice
  • 浏览: 1064 次
  • 性别: Icon_minigender_1
  • 来自: 自己输入城市...贵阳
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

发一个自己写的数据库连接池

阅读更多

现在大家都是用配置来连接数据库了,可能都不用写的了。可是如果是在远程的服务器的话,我还不知道怎么去配置,所以自己写了个连接池,各位看了后给点意见,高手轻点拍砖哈。

DB.java

package com.database.config;

public class DB
{
    public final static String driver="sun.jdbc.odbc.JdbcOdbcDriver";
   
    //public final static String driver="com.mysql.jdbc.Driver";
   
    public final static  String dbName="stu.mdb";
   
    public final static String url="jdbc:odbc:driver= {Microsoft Access Driver (*.mdb)};DBQ=D:/javaWeb/Stu/WEB-INF/classes/stu.mdb";
      
    //public final static String url="jdbc:mysql://localhost/test";
   
    public final static String port="";
   
    public final static String username="";
   
    public final static String pwd="";
   
    public final static int max =50;
   
    public final static int min=5;
   
    /*
     * 经测试以下参数为最佳合理配置,请勿更改!
     * 根据不同的电脑配置,配置不同的参数
     * */
    public final static int inc=5;
   
    public final static int timeout=20; //等待timeout时间后获取连接
   
    public final static int timer=1000;   //多少时间关掉多余的连接
   
}


//数据库连接包装类
ConnState.java

/*
* 创建日期 Jan 2, 2009
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package com.database.pool;

import java.sql.Connection;

public class ConnState
{
    private boolean isOpen=false;
   
    private Connection conn;

    public Connection getConn()
   
    {
        return conn;
    }

    public void setConn(Connection conn)
    {
        this.conn = conn;
    }

    public boolean isOpen()
    {
        return isOpen;
    }

    public void setOpen(boolean isOpen)
    {
        this.isOpen = isOpen;
    }
   
   
}

DatabasePool.java
/*
* 创建日期 Jan 2, 2009
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package com.database.pool;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.database.config.DB;



/*数据库连接池
* 程序会将多余的连接关掉和在连接池里删除掉
*
* */

public class DatabasePool
{
    private static List<ConnState> pool;
   
    private static DatabasePool instance;
   
    public TimerTask task=new TimerTask()
    {
        public void run()
        {
            System.out.println("run()");
            System.out.println("DatabasePool 类使用中的连接总数:"+ getConnCount());
          // if(pool.size()>DB.min)
            {
                Iterator<ConnState> it =pool.iterator();
               
                while(it.hasNext())
                {
                    ConnState st=it.next();
                    if(pool.size()<=DB.min)
                    {
                        if(st.isOpen()==true && null!=st.getConn())
                        {
                            try
                            {
                                st.getConn().commit();
                                st.setOpen(false);
                            }catch(SQLException e)
                            {       
                                System.out.println("强行执行sql语句失败");
                            }
                        }
                    }
                    else
                    {
                        if(st.isOpen()==true && null!=st.getConn())
                        {
                            try
                            {
                                st.getConn().commit();
                                st.getConn().close();
                                //it.remove();
                            }catch(SQLException e)
                            {
                               try
                               {
                                   Thread.sleep(200);
                                   st.getConn().commit();
                                   st.getConn().close();
                               }catch(InterruptedException ex)
                               {
                                   ex.printStackTrace();
                               }catch(SQLException se)
                               {
                                  se.printStackTrace();
                               }
                            }finally
                            {
                                try
                                {
                                    st.setConn(null);
                                    st=null;
                                    System.out.println("最后的关闭");
                                    it.remove();
                                    System.gc();
                                }catch(Exception e)
                                {
                                    e.printStackTrace();
                                }
                            }
                        }
                    }
                }
            }
        }
    };
    public DatabasePool() throws Exception
    {
        /*
         * 连接池使用ArrayList对象进行封装ConnState,这里使用了泛型
         * */
       pool=new ArrayList<ConnState>();
       Init();
       StartTimer();
    }
/*    创建数据库连接
* 返回ConnState对象
* ConnState 对象封装Connection对象
* */
    private static ConnState createConnection() throws ClassNotFoundException,SQLException
    {
         Connection conn;
        
        Class.forName(DB.driver);
       
        conn=DriverManager.getConnection(DB.url);
       
        conn.setAutoCommit(false);
       
        ConnState state =new ConnState();
       
        state.setConn(conn);
       
        return state;
    }
   
    /*数据库连接池的初始化过程*/
    private static  void Init() throws Exception
    {
        if(null==pool)
        {
           getInstance();
        }
        else
        {
           
            /*
             * 创建预定义大小的连接
             * */
            for(int i=0;i<DB.min;i++)
            {
                pool.add(createConnection());
            }
        }
    }
   
    private static void inc() throws Exception
    {
        if(null==pool)
        {
            getInstance();
            Init();
        }
        else if(pool.size()<DB.max)
        {
            int c=(pool.size()+DB.inc)>DB.max?DB.max-pool.size():DB.inc;
           
            for(int i=0;i<c;i++)
            {
                pool.add(createConnection());
            }
        }
    }
    private static   DatabasePool getInstance() throws Exception
    {
        instance =new DatabasePool();
        return instance;
    }
    /*
     * 返回数据库连接
     * */
    public synchronized static Connection getConnection() throws Exception
    {
        if(null ==instance )
        {
            getInstance();
        }
       Connection conn=findConnection();
       int count=1;
       /*
        * 如果没有找到可用的连接或三次
        * 将会抛出异常
        * */
      while(null==conn && count<=3)
      {
         count++;
          Thread.sleep(DB.timeout);
          conn=findConnection();
          if(null!=conn)
          {
              break;
          }
          else
          {
              inc();   // 增加指定个数的连接
              conn=findConnection();
          }
       
      }
     
      if(null==conn) throw new Exception("当前连接己达到最连接池,没有可以使用的数据库连接了");
       return conn;
    }
   
    private static Connection findConnection() throws Exception   
    {
        Iterator<ConnState> it =pool.iterator();
        Connection conn=null;

        while(it.hasNext())
        {
            ConnState cs=it.next();
            if(cs.isOpen()==false)
            {
                conn=cs.getConn();
                cs.setOpen(true);
                break;
            }
        }
        return conn;
    }
   
    public void StartTimer()
    {
        Timer time=new Timer();
        time.schedule(task, DB.timer,2000);
    }
   
    public static int getConnCount()
    {
        return pool.size();
    }
}

 

分享到:
评论
4 楼 xpice 2009-03-16  
楼上的朋友,谢谢你们的意见.网上的的确很多而且也很不错,可是那是别人写的,我觉得不写就没会有进步.
Rooock
数据库连接有释放的,只是不是手动的,是自动的
3 楼 Rooock 2009-03-16  
有getConnection方法.我怎么没看见释放的方法呢?
连接池是List<ConnState>. 从list取了资源不归还它.难道不怕精尽人亡吗?

sqlDao感觉不太好.参考下Spring数据库模版.

另外,代码放在[ code ][/ code ]中,就有格式了.
2 楼 otom31 2009-03-16  
个人认为重复发明轮子了,连接池现有的很多,而且都做的很好。。。
1 楼 xpice 2009-03-16  
还没有完,继续。奇怪了,我看了别人的代码都有格式的,我的怎么就没有了呢?

SqlAware.java

/*
* 创建日期 Jan 3, 2009
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package com.database.pool;

import java.util.List;
import java.util.Map;

public interface SqlAware
{
    public List getData(String sql) throws Exception;
   
    public Map getOneData(String sql) throws Exception;
   
    public int execute(String sql) throws Exception;
   
    public int executeBatch(String sql) throws Exception;
}


SqlDao.java
/*
* 创建日期 Jan 3, 2009
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/
package com.database.pool;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.database.exception.SqlException;

public  class SqlDao implements SqlAware
{
    public void close(ResultSet rs) throws SQLException
    {
        if(null!=rs)
        {
            rs.close();
        }
    }
   
    public void close(ResultSet rs,Statement stmt) throws SQLException
    {
        if(null!=rs) rs.close();
        if(null!=stmt) stmt.close();
    }
   
    public void close(PreparedStatement pstmt) throws SQLException
    {
        if(null!=pstmt) pstmt.close();
    }
   
    public void close(ResultSet rs,PreparedStatement pstmt) throws SQLException
    {
        if(null!=rs) rs.close();
        if(null!=pstmt) pstmt.close();
    }

    public int executeBatch(ArrayList<Map<String,String>> list, String sql) throws Exception
    {
        // TODO 自动生成方法存根
        return 0;
    }

    public int executeBatch(String sql) throws Exception
    {
        // TODO 自动生成方法存根
        return 0;
    }

    public int execute(String sql) throws Exception
    {
        int n=0;
       
        Connection conn=DatabasePool.getConnection();
       
        PreparedStatement pstmt=conn.prepareStatement(sql);
       
        n=pstmt.executeUpdate();
       
        close(pstmt);
       
        return n;
    }

    public List<Map<String,String>> getData(String sql) throws Exception
    {
        ArrayList<Map<String,String>> list=new ArrayList<Map<String,String>>();
       
        Connection conn=DatabasePool.getConnection();
       
        PreparedStatement pstmt=conn.prepareStatement(sql);
       
        ResultSet rs=pstmt.executeQuery();
       
        ResultSetMetaData rsmd=rs.getMetaData();
       
        int c=rsmd.getColumnCount();
       
        while(rs.next())
        {
           
            Map<String,String>  hp=new HashMap<String,String>();
           
            for(int i=1;i<=c;i++)
            {
                String label=rsmd.getColumnName(i);
               
                System.out.println(label);
               
                String value=rs.getString(i);
               
                hp.put(label, value);
               
                if(null==hp) throw new SqlException();
              
            }
           
            list.add(hp);

        }
       
        close(rs,pstmt);
       
        return list;
    }

    public Map<String,String> getOneData(String sql) throws Exception
    {
        HashMap<String,String> hp=null;
       
        Connection conn=DatabasePool.getConnection();
       
        PreparedStatement pstmt=conn.prepareStatement(sql);
       
        ResultSet rs=pstmt.executeQuery();
       
        ResultSetMetaData rsmd=rs.getMetaData();
       
        int c=rsmd.getColumnCount();
       
        if(rs.next())
        {
            hp=new HashMap<String,String>(1);
           
            for(int i=1;i<c;i++)
            {
                String label=rsmd.getColumnName(i);
               
                hp.put(label, rs.getString(i));
            }
        }
      
        close(rs,pstmt);
       
        if(null==hp) throw new SqlException();
        return hp;
       
    }
   
   
}


一般写一个业务操作类继承SqlDao类就可以了。

各位如有好的意见,请留言.

相关推荐

    自己写的数据库连接池(java)

    在给定的标题“自己写的数据库连接池(java)”中,我们可以推测这是一个用户自定义的数据库连接池实现,可能是为了学习或实践目的。描述提到的“XML版读取属性文件”和“普通的”,暗示了两种不同的配置方式,一种是...

    java手写数据库连接池

    数据库连接池是Java应用程序中非常重要的一个组件,它在提高应用性能、节省系统资源方面起着关键作用。本文将深入探讨如何使用Java手写数据库连接池,并基于maven进行项目构建。我们将分析四个核心类的功能,以及...

    数据库连接池技术详解

    对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接池技术。某一应用最大可用数据库连接数的限制,避免某一应用独占所有数据库资源。 在较为完备的数据库连接池实现中,可根据...

    java写的数据库连接池

    数据库连接池是Java开发中非常重要的一个概念,它在处理大量并发访问数据库的应用场景中扮演着关键角色。本文将深入探讨数据库连接池的工作原理、重要性以及如何在Java中实现一个简单的连接池。 首先,数据库连接池...

    自己写的数据库连接池

    在这个项目中,你使用Java实现了一个自定义的数据库连接池,应用了代理模式来优化连接管理和提高性能。下面我们将深入探讨这个主题。 首先,让我们了解什么是数据库连接池。在传统的数据库操作中,每当有新的数据库...

    C#高效数据库连接池源码

    `Demo`可能是一个示例应用程序,展示如何使用自定义的数据库连接池。 5. **连接池实现细节**: - **初始化**:在应用程序启动时,连接池会被初始化,预创建一定数量的数据库连接。 - **连接分配**:当应用程序...

    C# 数据库连接池 C# 数据库连接池

    数据库连接池是数据库管理中的一个重要概念,它在C#编程中扮演着优化数据库操作的关键角色。C#数据库连接池是一种管理数据库连接的技术,通过复用已存在的连接而不是每次请求时都创建新的连接,从而提高数据库操作的...

    Qt 多线程连接数据库——数据库连接池

    * 数据库连接池特点: * 获取连接时不需要了解连接的名字,连接池内部维护连接的名字 * 支持多线程,保证获取到的连接一定是没有被其他线程正在使用 * 按需创建连接,可以创建多个连接,可以控制连接的数量 * 连接...

    Java jdbc数据库连接池总结

    数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来...

    03-数据库连接池驱动_数据库连接池;驱动_

    其次,Druid是阿里巴巴开源的数据库连接池实现,它不仅是一个连接池,还集成了监控、SQL解析、WebStatFilter等特性。Druid以其强大的监控能力、优秀的性能和全面的功能深受开发者喜爱。它提供了实时的监控界面,可以...

    常用jdbc数据库连接jar包,数据库连接池jar包

    数据库连接池在初始化时会创建一定数量的数据库连接并保存起来,当应用程序需要连接时,可以从池中获取一个已存在的连接,而不是每次都去新建,用完后也不立即关闭,而是归还给连接池。这样可以显著减少建立和释放...

    c# mysql数据库连接池实现

    本文将深入探讨如何在C#中使用MySQL数据库连接池。 首先,我们需要了解什么是数据库连接池。数据库连接池是一种资源管理技术,它预先创建并维护一定数量的数据库连接,当应用需要时,可以从池中获取连接,使用完毕...

    数据库连接池java代码实现

    本文将深入探讨如何使用Java代码来实现一个简单的数据库连接池,并解释其核心概念和工作原理。 连接池的基本思想是维护一组预初始化的数据库连接,当应用程序需要时,可以从池中获取一个连接,使用完毕后,再归还回...

    delphi实现数据库连接池

    数据库连接池(Database Connection Pool)是预先在内存中创建一定数量的数据库连接,当应用程序需要时,可以从池中获取一个已存在的连接,而不是每次都去创建新的。这种方式减少了创建和关闭连接的开销,提高了系统...

    C# 数据库连接池

    数据库连接池是数据库管理系统中的一个重要概念,主要用于优化数据库的连接操作。在C#编程中,数据库连接池可以高效地管理数据库连接,避免频繁创建和销毁连接导致的性能开销。本文将详细介绍C#中数据库连接池的工作...

    配置数据库连接池

    数据库连接池的基本思想是预先创建并维护一定数量的数据库连接,当应用需要与数据库通信时,可以快速地从连接池中获取一个已建立的连接,而不是每次都新建一个。用完后,连接会归还到池中,供其他请求使用,而不是...

    JAVA数据库连接池

    数据库连接池在初始化时会创建一定数量的数据库连接并保存在池中,当应用程序需要连接数据库时,不是直接创建新的连接,而是从连接池中获取一个已经存在的连接;使用完毕后,连接不会被立即关闭,而是归还到连接池,...

Global site tag (gtag.js) - Google Analytics