Dans l'exercice d'hier, chaque exercice doit établir une connexion avec la base de données Complète. Cependant, lorsque la quantité de données traitées est particulière, cela prend beaucoup de temps et réduit l'efficacité. Aujourd'hui, nous apprenons à utiliser le pool de connexions, à mettre la connexion dans le pool de connexions et à la supprimer en cas de besoin, Le remettre dans la piscine après utilisation ne signifie pas le débrancher.
L'idée de base du pool de connexions à la base de données est d'établir un "pool tampon" pour les connexions à la base de données. Mettez à l'avance un certain nombre de connexions dans le pool tampon. Lorsque vous devez établir une connexion à la base de données, il vous suffit d'en retirer une du « pool tampon » et de la remettre après utilisation. Le pool de connexions à la base de données créera un certain nombre de connexions à la base de données et les placera dans le pool de connexions lors de l'initialisation. Le nombre de ces connexions à la base de données est défini par le nombre minimum de connexions à la base de données. Que ces connexions à la base de données soient utilisées ou non, le pool de connexions sera toujours assuré d'avoir au moins ce nombre de connexions. Le nombre maximum de connexions à la base de données dans le pool de connexions limite le nombre maximum de connexions que le pool de connexions peut occuper. Lorsque le nombre de connexions demandées par l'application au pool de connexions dépasse le nombre maximum de connexions, ces requêtes seront ajoutées au pool de connexions. file d'attente.
Afin de résoudre le problème de connexion à la base de données dans le développement traditionnel, la technologie de pool de connexions à la base de données peut être utilisée.
Le pool de connexions à la base de données est responsable de l'allocation, de la gestion et de la libération des connexions à la base de données. Il permet aux applications de réutiliser une connexion à la base de données existante au lieu d'en rétablir une.
driverClassName = com.mysql.jdbc.Driverurl = jdbc:mysql://127.0.0.1:3306/companynom d'utilisateur = rootmot de passe = 123456initialSize = 5maxActive = 50maxIdle = 10
#driverClassName = oracle.jdbc.driver.OracleDriver#url = jdbc:oracle:thin:@127.0.0.1:1521:orcl #username = scott#password = tigre
package com.atguigu.jdbc; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; import org.junit.Test; public class DBCPTest { @Test public void test2() throws Exception { Properties properties = new Properties(); properties.load(new FileInputStream("dbcp.properties")); DataSource dataSource = BasicDataSourceFactory.createDataSource(properties); System.out.println("inital:" + ((BasicDataSource)dataSource).getInitialSize()); System.out.println("getMaxActive:" + ((BasicDataSource)dataSource).getMaxActive()); System.out.println("getMaxIdle:" + ((BasicDataSource)dataSource).getMaxIdle()); Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close(); } }
com.mysql.jdbc.Driver jdbc:mysql://127.0.0.1:3306/school root 123456 5 5 5 50 0 5 oracle.jdbc.driver.OracleDriver jdbc:mysql://127.0.0.1:3306/school root 123456
DBCP连接池使用这个文件可以完成mysql、oracle的连接池的建立,每次只能建立一个,但是另一个需要注释起来。因为我们是根据
package com.atguigu.jdbc; import java.beans.PropertyVetoException; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import org.junit.Test; import com.mchange.v2.c3p0.*; public class C3P0Test { @Test public void test1() throws PropertyVetoException, SQLException { DataSource dataSource = new ComboPooledDataSource("mysql-config"); // 它会默认自动去读取文件 System.out.println(dataSource); Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close();// 把连接归还给连接池 DataSources.destroy(dataSource);// 完全释放池中所有连接,并销毁连接池!! } @Test public void test2() throws PropertyVetoException, SQLException { DataSource dataSource = new ComboPooledDataSource("oracle-config"); // 它会默认自动去读取文件 System.out.println(dataSource); Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close();// 把连接归还给连接池 DataSources.destroy(dataSource);// 完全释放池中所有连接,并销毁连接池!! } }
学习了连接池之后,JdbcUtil工具类中的getConnection方法就可以应用,如下:
package com.atguigu.jdbc; import java.io.FileInputStream; import java.io.IOException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.DataSources; /** * 预备工作 : * 1) 把要访问的数据库相关的驱动程序复制到项目中, 就是jar包 * 2) 配置项目属性, 把jar包导入到本项目的buildpath中 * @author Administrator * */ public class JdbcUtil { private static DataSource dataSource; // 声明静态属性对象引用. static { dataSource = new ComboPooledDataSource("mysql-config"); // 连接池对象只需要创建一次就可以了 } public static Connection getConnection() throws SQLException { return dataSource.getConnection(); // 要想获取连接, 只需要从连接池中获取,用完以后, 再归还回来 } public static Connection getConnectionOld() throws IOException, ClassNotFoundException, SQLException { // 1) 读取配置文件 Properties properties = new Properties(); properties.load(new FileInputStream("jdbc.properties")); // 2) 获取配置文件中的必要的信息 String driverClass = properties.getProperty("driverClass"); String url = properties.getProperty("url"); String user = properties.getProperty("user"); String password = properties.getProperty("password"); // 3) 注册驱动 , 加载驱动类 Class.forName(driverClass); // 4) 通过驱动管理器获取连接(需要url,用户,密码) return DriverManager.getConnection(url, user, password);// 暗含 new Socket(host,port), 认证,其他各种初始化操作 } //关闭连接 public static void close(Connection connection) { close(connection, null); } public static void close(Connection connection, Statement statement) { close(connection, statement, null); } public static void close(Connection connection, Statement statement, ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (Exception e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (Exception e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (Exception e) { e.printStackTrace(); } } } //销毁连接池 public static void destroy() { try { DataSources.destroy(dataSource); } catch (SQLException e) { e.printStackTrace(); } } }
将常用的操作数据库的JDBC的类和方法集合在一起,就是DBUtils.JDBC。提供供我们使用的工具类QueryRunner来执行操作。
在使用之前我们仍然需要将commons-dbutils-1.3.jar添加到当前工程下,并添加到path路径。
package com.atguigu.jdbc; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test; public class QueryRunnerTest { // 使用我们自定义工具实现表的创建 @Test public void test1() throws SQLException { QueryRunner qr = new QueryRunner(); Connection connection = JdbcUtil.getConnection(); qr.update(connection, "create table test2(aa int, bb varchar(10))"); JdbcUtil.close(connection); } // 使用我们自定义工具向表中插入一条记录 @Test public void test2() throws SQLException { QueryRunner qr = new QueryRunner(); Connection connection = JdbcUtil.getConnection(); int rows = qr.update(connection, "insert into test2(aa, bb) values(?,?)", 10, "xxx"); System.out.println(rows + " rows"); JdbcUtil.close(connection); } // 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,把结果集中的所有记录转换为department对象集合并存入List集合中,然后遍历输出对象 @Test public void test3() throws SQLException { //query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) String sql = "select * from departments where department_id > ?"; QueryRunner qr = new QueryRunner(); Connection connection = JdbcUtil.getConnection(); BeanListHandler<Department> rsh = new BeanListHandler<Department>(Department.class); // 把结果集中的所有记录转换为对象集合 List<Department> list = qr.query(connection, sql, rsh, 20); for (Department department : list) { System.out.println(department); } } // 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,把结果集中的一条记录转换为department实体对象,然后输出对象 @Test public void test4() throws SQLException { String sql = "select * from departments where department_id = ?"; QueryRunner qr = new QueryRunner(); Connection connection = JdbcUtil.getConnection(); BeanHandler<Department> rsh = new BeanHandler<Department>(Department.class); // 把结果集中的一条记录转换为实体对象 Department objDepartment = qr.query(connection, sql, rsh, 20); System.out.println(objDepartment); } // 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,将每一条记录存入集合中,然后遍历输出每一个数据 @Test public void test5() throws SQLException { String sql = "select * from employees"; QueryRunner qr = new QueryRunner(); Connection connection = JdbcUtil.getConnection(); ArrayListHandler rsh = new ArrayListHandler(); List<Object[]> list = qr.query(connection, sql, rsh); for (Object[] objects : list) { for (int i = 0; i < objects.length; i++) { System.out.print(objects[i] + "\t"); } System.out.println(); } } // 使用DBUtils.JDBC接口中提供的方法对departments表进行查询,将查询到的一个数据输出 @Test public void test6 () throws SQLException { String sql = "select count(*) from world.country"; QueryRunner qr = new QueryRunner(); Connection connection = JdbcUtil.getConnection(); ScalarHandler rsh = new ScalarHandler(); Object singleValue = qr.query(connection, sql, rsh); System.out.println(singleValue); } @Test public void test7() throws Exception { QueryRunner qr = new QueryRunner(); List<Object> list = qr.query(JdbcUtil.getConnection(), "select * from student", new ColumnListHandler(1)); for (Object object : list) { System.out.println(object); } } //MapHandler把第一行数据封装到Map集合中, 列名作为键, 对应值作为值 @Test public void test8() throws Exception { QueryRunner qr = new QueryRunner(); Map<String, Object> map = qr.query(JdbcUtil.getConnection(), "select * from student", new MapHandler()); Set<String> keys = map.keySet(); for (String key : keys) { Object value = map.get(key); System.out.println(key + " -------- " + value); } } //MapListHandler把一行数据封装到Map集合中, 并把所有行生成的Map再放入一个List集合 @Test public void test9() throws Exception { QueryRunner qr = new QueryRunner(); List<Map<String, Object>> list = qr.query(JdbcUtil.getConnection(), "select * from student", new MapListHandler()); for (Map<String, Object> map2 : list) { Set<String> keys = map2.keySet(); for (String key : keys) { Object value = map2.get(key); System.out.println(key + " -------- " + value); } System.out.println(); } } }
到这里就可以统一整理一下自己定义的JdbcUtil工具类、CommonUtil工具类,使自定义的工具类能达到JDButi.JDBC相同的功能,如下:
JdbcUtils.java
package com.atguigu.jdbc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; import com.mchange.v2.c3p0.DataSources; public class JdbcUtil { private static DataSource dataSource; static { dataSource = new ComboPooledDataSource("config1"); // 它必须依赖文件src/c3p0-config.xml } // 获取c3p0连接池的连接 public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } public static void close(Connection connection) { close(connection, null); } public static void close(Connection connection, Statement statement) { close(connection, statement, null); } public static void close(Connection connection, Statement statement, ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (Exception e) { e.printStackTrace(); } } if (statement != null) { try { statement.close(); } catch (Exception e) { e.printStackTrace(); } } if (connection != null) { try { connection.close(); } catch (Exception e) { e.printStackTrace(); } } } public static void destroy() { try { DataSources.destroy(dataSource); } catch (SQLException e) { e.printStackTrace(); } } }
CommonUtil.java
package com.atguigu.jdbc; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; public class CommonUtil { /** * 把结果集中的每一行都放入Object对象数组中, 再把所有的Object对象数组放入一个List集合中. * @throws SQLException */ public static List<Object[]> query(Connection connection, String sql, Object... values) throws SQLException { PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); fillArguments(preparedStatement, values); resultSet = preparedStatement.executeQuery(); List<Object[]> list = new ArrayList<Object[]>(); int cols = resultSet.getMetaData().getColumnCount(); while (resultSet.next()) { Object[] dataRow = new Object[cols]; for (int i = 0; i < dataRow.length; i++) { dataRow[i] = resultSet.getObject(i + 1); } list.add(dataRow); } return list; } finally { JdbcUtil.close(null, preparedStatement, resultSet); } } /** * 把结果集中的第一行数据,全放入一个对象数组中 * @throws SQLException */ public static Object[] queryValueArray(Connection connection, String sql, Object... values) throws SQLException { PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); fillArguments(preparedStatement, values); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { Object[] dataRow = new Object[resultSet.getMetaData().getColumnCount()]; for (int i = 0; i < dataRow.length; i++) { dataRow[i] = resultSet.getObject(i + 1); } return dataRow; } else { return null; } } finally { JdbcUtil.close(null, preparedStatement, resultSet); } } /** * 从结果集中获取第一行的第一列 * @throws SQLException */ public static Object queryValue(Connection connection, String sql, Object... values) throws SQLException { PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); fillArguments(preparedStatement, values); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { return resultSet.getObject(1); } else { return null; } } finally { JdbcUtil.close(null, preparedStatement, resultSet); } } /** * 把结果集中第一行转换为对象返回 * @throws SQLException * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalAccessException * @throws InstantiationException */ public static <T> T queryBean(Connection connection, String sql, Class<T> clazz, Object... values) throws SQLException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException { PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); fillArguments(preparedStatement, values); resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { T t = clazz.newInstance(); ResultSetMetaData metaData = resultSet.getMetaData(); int cols = metaData.getColumnCount(); for (int i = 0; i < cols; i++) { String label = metaData.getColumnLabel(i + 1); Object value = resultSet.getObject(label); Field field = clazz.getDeclaredField(label); field.setAccessible(true); field.set(t, value); } return t; } else { return null; } } finally { JdbcUtil.close(null, preparedStatement, resultSet); } } /** * 把结果集的所有记录都封装成对象,并把所有对象放在一个List集合中 * @throws SQLException * @throws IllegalAccessException * @throws InstantiationException * @throws SecurityException * @throws NoSuchFieldException */ public static <T> List<T> query(Connection connection, String sql, Class<T> clazz, Object... values) throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException { PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { preparedStatement = connection.prepareStatement(sql); fillArguments(preparedStatement, values); resultSet = preparedStatement.executeQuery(); List<T> list = new ArrayList<T>(); ResultSetMetaData metaData = resultSet.getMetaData(); int cols = metaData.getColumnCount(); while (resultSet.next()) { T t = clazz.newInstance(); for (int i = 0; i < cols; i++) { String label = metaData.getColumnLabel(i + 1); Object value = resultSet.getObject(label); if (value != null) { Field field = clazz.getDeclaredField(label); field.setAccessible(true); field.set(t, value); } } list.add(t); } return list; } finally { JdbcUtil.close(null, preparedStatement, resultSet); } } /** * 通用更新操作 * @throws SQLException */ public static int update(Connection connection, String sql, Object... values) throws SQLException { PreparedStatement preparedStatement = null; try { preparedStatement = connection.prepareStatement(sql); fillArguments(preparedStatement, values); return preparedStatement.executeUpdate(); } finally { JdbcUtil.close(null, preparedStatement); } } public static void fillArguments(PreparedStatement preparedStatement, Object... values) throws SQLException { for (int i = 0; i < values.length; i++) { preparedStatement.setObject(i + 1, values[i]); } } }
综合之前学习过的知识,在这里创建一个BaseDAO
package com.atguigu.jdbc; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.Connection; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; public class BaseDAO<T>{ protected Class<T> clazz; // T泛型究竟是什么类型, 用类模板对象来描述 protected QueryRunner qr = new QueryRunner(); // 用于执行通用查询和更新的工具类对象 protected Connection connection; // 数据库连接 protected String tableName; // 涉及到的表,需要通过构造器初始化赋值 public JdbcDAO(String tableName) { // 以下代码的执行者是子类对象,所以this.getClass是获取子类的类模板对象 Type type = this.getClass().getGenericSuperclass(); // JdbcDAO<Teacher> if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType)type;//JdbcDAO<Teacher> Type[] types = parameterizedType.getActualTypeArguments(); clazz = (Class<T>)types[0]; } else { clazz = (Class<T>)Object.class; } // 获取一个连接供所有方法使用 try { connection = JdbcUtil.getConnection(); } catch (SQLException e) { e.printStackTrace(); } this.tableName = tableName; } //获得记录中具体的一个数据 public Object getValue(String sql, Object... values) { try { return qr.query(connection, sql, new ScalarHandler(), values); } catch (SQLException e) { e.printStackTrace(); } return null; } //获得一行数据并封装成javabean对象 public T get(String sql, Object... values) { try { return qr.query(connection, sql, new BeanHandler<T>(clazz), values); } catch (SQLException e) { e.printStackTrace(); } return null; } //获得多行记录,封装成javabean对象,保存在list集合中 public List<T> getList(String sql, Object... values) { try { return qr.query(connection, sql, new BeanListHandler<T>(clazz), values); } catch (SQLException e) { e.printStackTrace(); } return null; } //获得所有记录,封装成javabean对象,保存在list集合中 public List<T> getAll() { return getList("select * from " + tableName); } //根据id获取某一条记录,并封装成javabean对象返回 public T getById(int id) { return get("select * from " + tableName + " where id = ?", id); } //根据id删除某一条记录,删除成功返回ture,失败返回false public boolean deleteById(int id) { int rows = update("delete from " + tableName + " where id = ?", id); if (rows > 0) { return true; } return false; } //通用的更新操作 public int update(String sql, Object... values) { try { return qr.update(connection, sql, values); } catch (SQLException e) { e.printStackTrace(); } return 0; } //关闭连接 public void close() { JdbcUtil.close(connection); } }
以上就是JDBC-数据连接池的使用 的内容,更多相关内容请关注PHP中文网(www.php.cn)!