美文网首页
10_连接池 & DBUtils

10_连接池 & DBUtils

作者: AndroidCat | 来源:发表于2017-06-06 22:56 被阅读0次
    连接池
    连接池介绍
    • 获取服务器连接和断开连接是非常消耗系统资源的,重复创建和断开连接会造成资源浪费
    • 使用数据库连接池可以解决性能问题
    • 使用连接池技术来共享Connection
    • java为数据库连接池提供了公共的接口:javax.sql.DataSource
    自定义连接池
    • 数据源
      • 获取数据的资源,我们以后需要获取数据库数据,就从连接池中获取连接然后连到数据库里,称之为数据源
    • 创建连接池步骤
      1. 创建连接池实现(实现javax.sql.DataSource接口),使用getConnection()方法
      2. 提供一个集合,用于存放连接,因为移除和添加操作过多,因此选择LinkedList
        • 通过自定义的JDBCUtils获取Connection
      3. 在静态代码块中创建3个连接
      4. 程序需要连接,调用getConnection()方法,方法从LinkedList中获取连接
      5. 用户使用完连接后把连接添加回LinkedList中
    public class MyDataSource implements DataSource{
        private static LinkedList<Connection> pool = new LinkedList<>();
        private MyDataSource() {
            super();
        }
        static {
            Connection conn = null;
            for (int i = 0; i < 15; i++) {
                conn = JDBCUtils.getConnection();
                pool.add(conn);
            }
        }
        @Override
        public static Connection getConnection() throws SQLException {
            if (pool.size() != 0) {
                return pool.removeFirst();
            }
            Thread.sleep(100);
            return getConnection();
            
        }
        
        //回收连接
        public static releaseConnection(Connection conn) {
            if(conn != null) {
                pool.add(conn);
            }
        }
    }
    
    • 自定义连接池需要调用连接池提供的release(connection conn)方法进行回收连接
      • 如果用户调用Connection.close()会真的关闭掉连接
    • 我们需要当用户调用Connection的close方法后,连接重新回到链接池中
      • 实现Connection.close()后连接回到连接池中
    方法增强
    1. 继承:子类继承父类,重写父类的方法从而使方法增强
        * 前提是必须要有父类,且存在继承关系
    2. 装饰设计模式:此设计模式专门用于增强方法
        * 使用前提:必须有接口
        * 缺点:需要将接口所有方法实现
    3. 动态代理:在运行时动态的创建代理类,完成增强的操作,与装饰者相似
        * 使用前提:需要有接口
        * 难点:需要有反射技术
    4. 字节码增强:运行时创建目标类子类,从而进行增强
        * 常见第三方框架:cglib,javassist等
    
    装饰设计模式
    • 专门为解决某一类问题,而编写的固定格式的代码
    • 装饰者固定结构:接口A,已知实现类C,需要装饰者创建代理类B
    1. 创建B,并实现A接口
    2. 提供B类的构造方法,参数类型为A,用于接收A接口的实现类C
    3. 给类B添加类型为A的成员变量,用于存放A接口的其他实现类
    4. 增强需要的方法
    5. 实现不需要增强的方法,方法体重调用成员变量存放的其他实现类对应的方法
    • A接口的实现类C作为参数传递,需要增强C的某个方法,创建A接口实现类B包裹C,修改该方法,然后把B替代C作为参数传递
    A a = c;
    B b = new B(c);
    class B implement A {
        private A a;
        public B(A a)  {
            this.a = a;
        }
        //需要增强的方法
        public void close() {
            ...    
        }
        //需要增强的方法
        public void commit() {
            ...
        }
    }
    
    //1.实现同一个接口Connection
    public class MyConnection implements Connection {
        //3.定义一个变量
        private Connection conn;
        private LinkedList<Connection> pool;
        // 2.编写一个构造方法(参数使用了面相对象的多态特性)
        public MyConnection(Connection conn,LinkedList<Connection> pool) {
            this.conn=conn;
            this.pool=pool;
        }
        //4.书写需要增强的方法
        @Override
        public void close() throws SQLException {
            pool.add(conn);
        }
        /**
         * 此方法必须覆盖!否则会出现空指针异常!!!
         */
        @Override
        public PreparedStatement prepareStatement(String sql) throws SQLException {
            return conn.prepareStatement(sql);
        }
    }
    
    C3P0连接池(使用率最高80%)
    • C3P0是开源免费的连接池,目前使用它的开源项目有:Spring,Hibernate等.

    • 使用第三方工具需要导入jar包,C3P0使用时还需要添加配置文件c3p0-config.xml

    • c3p0工具类

    //创建空参的ComboPooledDataSource对象时,默认会自动读取c3p0-config.xml文件中的<default-config>配置
    public class C3P0Utils {
        private static ComboPooledDataSource dataSource = new ComboPooledDataSource("coinfig_name");
    
        public static DataSource getDataSource() {
            return dataSource;
        }
    
        public static Connection getConnection() {
            try {
                return dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    • c3p0-config.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <default-config>
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql:///web08</property>
            <property name="user">root</property>
            <property name="password">root</property>
            <property name="initialPoolSize">5</property>
            <property name="maxPoolSize">20</property>
        </default-config>
    
        <named-config name="myconfig">
            <property name="driverClass">com.mysql.jdbc.Driver</property>
            <property name="jdbcUrl">jdbc:mysql:///web08</property>
            <property name="user">root</property>
            <property name="password">root</property>
        </named-config>
    </c3p0-config>
    
    DBCP
    • DBCP也是开源免费的连接池,在企业开发中也比较常见
    • tomcat服务器自带DBCP连接池
    • DBCP可以自己手动设置参数,也可以通过Properties对象和BasicDataSourceFactory初始化
    BasicDataSource basicDataSource = new BasicDataSource();
    basicDataSource.setDriverClassName("com.mysql.Driver");
    basicDataSource.setUrl("jdbc:mydql://localhost:3306/mydatabase");
    basicDataSource.setUsername("root");
    basicDataSource.setPassword("root");
    
    public class DBCPUtils {
        private static DataSource dataSource;
        static{
            try {
                //1.加载找properties文件输入流
                InputStream is = DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties");
                //2.加载输入流
                Properties props = new Properties();
                props.load(is);
                //3.创建数据源
                dataSource = BasicDataSourceFactory.createDataSource(props);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        public static DataSource getDataSource(){
            return dataSource;
        }
        
        public static Connection getConnection(){
            try {
                return dataSource.getConnection();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    
    • 配置文件:db.properties
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=utf8
    username=root
    password=root
    initialSize=10
    maxActive=50
    maxIdle=5
    maxWait=6000
    
    DBUtils
    • DBUtils是java编程中操作数据库的实用工具,小巧简单
    • DBUtils封装了对JDBC操作,可以减少代码
    • DBUitls,JDBCUtils,连接池区别
      • JDBCUtils是方便获取连接
      • 数据库连接池是提高代码的性能
      • DBUtils是精简操作数据库代码量
    • DBUtils类在基础加强里面会单独讲
    try {
        // 1.创建核心类QueryRunner
        QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());//参数传入连接池
        // 2.编写SQL语句
        String sql = "insert into tbl_user values(null,?,?)";
        // 3.为站位符设置值
        Object[] params = { "xx", "oo" };
        // 4.执行添加操作
        int rows = qr.update(sql, params);
        if (rows > 0) {
            System.out.println("添加成功!");
        } else {
            System.out.println("添加失败!");
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    

    相关文章

      网友评论

          本文标题:10_连接池 & DBUtils

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