数据库连接池

    xiaoxiao2021-03-25  102

    数据库连接池是什么?解决什么问题?

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

    使用数据库连接池能优化程序性能.数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,同时可以释放空闲时间超过最大空闲时间的数据库连接,来避免因为没有释放数据库连接而引起的数据库连接遗漏.

    编写一个基本的连接池实现连接复用

    编写连接池需实现DataSource接口,实现DataSource接口,并实现连接池功能的步骤: 1. 在DataSource构造函数中批量创建数据库连接,并把创建的连接加入LinkedList对象中 2. 实现getConnection方法,getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户 3. 当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库(包装设计模式)

    配置文件

    host=localhost port=3306 db=my05test7 user=root password=123456 //DBUtils //trycatch省略,方便查看 public class DBUtils { static Properties properties; static String host; static String port; static String db; static { // 加载驱动 Class.forName("com.mysql.jdbc.Driver").newInstance(); String path = DBUtils.class.getClassLoader().getResource("conn.prop").getPath(); // 建立连接 properties = new Properties(); properties.load(new FileInputStream(path)); host = properties.getProperty("host"); port = properties.getProperty("port"); db = properties.getProperty("db"); } //连接数据库 public static Connection getConnection() throws SQLException { String url = "jdbc:mysql://" + host + ":" + port + "/" + db; return DriverManager.getConnection(url, properties); } //释放资源 public static void releaseResource(Statement st, ResultSet rs, Connection conn) { if (st != null) { st.close(); } if (rs != null) { rs.close(); } if (conn != null) { conn.close(); } } } // 连接池的原理 //trycatch省略,方便查看 public class MyDataConnectionPool { // 有个池子,存放连接 // 有个容器 ,存放初始化的连接 private static LinkedList<Connection> connPool = new LinkedList<Connection>(); // 初始化,放10个连接 static { for (int i = 0; i < 10; i++) { Connection connection = DBUtils.getConnection(); connPool.add(connection); } } // 有个API,用户可以调用,从池子里拿一个没有人用的connection public Connection getConnectionFromPool() { Connection connection = null; if (connPool.size() > 0) { connection = connPool.getFirst(); return connection; } else { throw new RuntimeException("连接池里没有更多的连接了"); } } // 有个API,用户用完之后,可以放回到池子里 public void returnToConnectionPool(Connection conn) { connPool.addLast(conn); } }

    开源数据库连接池

    DataSource的实现,称之为数据源,数据源中都包含了数据库连接池的实现

    DBCP 数据库连接池

    //DBCP 数据库连接池 static { InputStream in = MyDBCPUtils.class.getClassLoader() .getResourceAsStream("dbcpconfig.properties"); Properties prop = new Properties(); prop.load(in); // 框架提供的数据源 BasicDataSourceFactory factory = new BasicDataSourceFactory(); ds = factory.createDataSource(prop); } //配置文件 #连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/my05test7 username=root password=123456 #<!-- 初始化连接 --> initialSize=10 #最大连接数量 maxActive=50 #<!-- 最大空闲连接 --> maxIdle=20 #<!-- 最小空闲连接 --> minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --> maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;] #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。 connectionProperties=useUnicode=true;characterEncoding=utf8 #指定由连接池所创建的连接的自动提交(auto-commit)状态。 defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。 #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix) defaultReadOnly= #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。 #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE defaultTransactionIsolation=REPEATABLE_READ ////DBCP 的使用 public void testQuery() { Connection connection =null; Statement st =null; ResultSet rs =null; List<User> userList = new ArrayList<User>(); try { //建立连接 connection = MyDBCPUtils.getConnection(); st =connection.createStatement(); //查user表 rs =st.executeQuery("select * from user;"); while (rs.next()) { String username = rs.getString(1); String password = rs.getString(2); String email = rs.getString(3); String path = rs.getString(4); userList.add(new User(username, password, email, path)); } } catch (SQLException e) { e.printStackTrace(); }finally { MyDBCPUtils.releaseResource(st, rs, connection); } for (User user : userList) { System.out.println(user); }

    C3P0 数据库连接池

    //C3P0 数据库连接池 static{ cpds = new ComboPooledDataSource(); cpds.setDriverClass( "com.mysql.jdbc.Driver" ); cpds.setJdbcUrl( "jdbc:mysql://localhost/mytest" ); }

    c3p0-config

    <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="user">root</property> <property name="password">123456</property> <property name="checkoutTimeout">30000</property> <property name="idleConnectionTestPeriod">30</property> <property name="initialPoolSize">10</property> <property name="maxIdleTime">30</property> <property name="maxPoolSize">100</property> <property name="minPoolSize">10</property> <property name="maxStatements">200</property> </default-config> </c3p0-config> //使用C3P0DBUtils public void testQuery() { Connection conn=null; Statement st =null; ResultSet rs =null; List<User> userList = new ArrayList<User>(); try { //建立连接 conn = C3P0DBUtils.getConnection(); st =conn.createStatement(); //查询user表 rs =st.executeQuery("select * from user;"); while (rs.next()) { String username = rs.getString(1); String password = rs.getString(2); String email = rs.getString(3); String path = rs.getString(4); userList.add(new User(username, password, email, path)); } } catch (SQLException e) { e.printStackTrace(); }finally { C3P0DBUtils.releaseResource(st, rs, conn); } //打印出来 for (User user : userList) { System.out.println(user); } }
    转载请注明原文地址: https://ju.6miu.com/read-10366.html

    最新回复(0)