连接池

作者: 张无忌_ | 来源:发表于2016-07-26 19:50 被阅读35次

    1.数据库连接池原理?

    1.1 什么是数据库连接池?

    个人觉得了解一个技术首先要清楚它的出现解决了什么样的问题 ,扮演怎样的角色。目前数据库直接获取链接有这样的问题:

    用户每次请求都需要向数据库获得链接,而数据库创建链接通常需要消耗相对较大的资源,创建时间也较长,如果网站一天有10万访问量,数据库服务器就需要创建10万次链接,极大的浪费数据库的资源,并且极易造成数据库服务内存溢出 拓机。

    如果当你需要链接的时候,有一个在你需要可以直接给你提供,那效率将会得到很大的提升。而这个库就是数据库连接池

    数据库连接池的优点:提高数据库链接的效率;

    1.2 模拟简单的数据库连接池?

    // 存放链接对象的池

    private static Listpool = Collections.synchronizedList(new ArrayList());

    // 初始化一些链接到池中

    static{

    for (int i = 0; i < 10; i++) {

    Connection conn = JDBCUtils.getConn();

    pool.add(conn);

    }

    }

    // 从连接池中获取链接

    public static Connection getConnection(){

    if (pool.size()>0) {

    return pool.remove(0);

    }else{

    throw new RuntimeException("service busy!");

    }

    }

    // 用完之后还回池中

    public static void release (Connection conn){

    pool.add(conn);

    }

    1.3编写标准的数据源?

    需要实现javax.sql.datasource

    实现 getConnection,就可以了。

    public Connection getConnection() throws SQLException {

    if (pool.size()>0) {

    return pool.remove(0);

    }else{

    throw new RuntimeException("service busy!");

    }

    }

    编程会遇到的问题?

    conn.close(); //把链接关闭了。  不应该关闭,应该放回池中。

    解决方案:

    第一反应是继承Connection,覆盖系统的close()方法。 但是在这里不合适。

    会涉及到多个数据库混乱。

    1>.装饰设计模式

    装饰设计模式的步骤:

    1.编写一个类,实现与被装饰类相同的接口。目的是使他们有相同的行为。

    2.定义一个实例变量,引用被装饰对象。目的是和原来的老对象进行交接

    3.定义构造方法把被装饰对象注入进来。

    4. 对于不需要改写的方法,调用被装饰的对象。

    5.对于要改写的方法改写即可。

    private Connection conn;

    private Listpool;

    public MyConnection(Connection conn, Listpoo) {

    this.conn = conn;

    this.pool = pool;

    }

    // 把connection还会池中

    public void close() throws SQLException {

    // TODO Auto-generated method stub

    pool.add(conn);

    }

    2>. 默认适配器

    编写一个类,实现与被装饰类相同的接口。 

    编写一个类,继承上个类,实现要操作的方法  -> 避免每次操作都要是实现很多原声的方法。

    3>. 代理模式(重点)

    代理的概念: 自己想要做的事情,通过外界(具体怎么做到的我不管),然后实现了自己的目的。

    AOP编程技术实现,动态代理:

    基于接口的动态代理:

    前提: 被代理对象的类,至少实现了一个接口。

    基于子类的动态代理:

    借助第三方。CGLIB

    public Connection getConnection() throws SQLException {

    if (pool.size()>0) {

    final Connection conn =  pool.remove(0);

    //MyConnection mConn = new MyConnection(conn, pool);

    Connection proxyConn = (Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(),

    conn.getClass().getInterfaces(), new InvocationHandler() {

    public Object invoke(Object proxy, Method method, Object[] args)

    throws Throwable {

    if ("close".equals(method.getName())){

    //用户调用的colse还会

    return pool.add(conn);

    }else{

    // 返回对应的方法

    return invoke(conn, method, args);

    }

    }

    });

    return proxyConn;

    }else{

    throw new RuntimeException("service busy!");

    }

    }

    2.数据库连接池怎么用?

    1> DBCP的使用:

    1.是apache的开源组件。 导入 jar  commons-dbcp-1.4.jar 跟  commons-pool-1.5.6.jar

    2.添加配置文件

    3.编写一个工具类。

    代码:

    private static DataSource ds;

    static{

    // 读取配置文件

    Properties props = new Properties();

    InputStream in = DBCPUtial.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");

    try {

    props.load(in);

    ds=BasicDataSourceFactory.createDataSource(props);

    } catch (Exception e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    public static DataSource getDataSource(){

    return ds;

    }

    public static Connection getConnection(){

    try {

    return ds.getConnection();

    } catch (SQLException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    return null;

    }

    }

    2>C3P0的使用:

    1. 开源的数据库

    2. 拷贝jar包  c3p0-0.9.1.2.jar

    3>利用Web服务器管理数据元(JNDI)

    1. 主流的web服务器都提供数据源的实现,基本都是配置一下。

    2. JNDI: Java Naming and Driectory Inerface;

    3.JDBC框架?

    3.1.数据库的元信息的获取?

    数据库或表的定义信息,或者结果集的一些信息。

    rs.getMetaData();

    3.2.编写自己的JDBC框架(约定优于编码)?

    相关文章

      网友评论

        本文标题:连接池

        本文链接:https://www.haomeiwen.com/subject/bcznjttx.html