In der gestrigen Übung muss bei jeder Übung eine Verbindung mit der Datenbank hergestellt werden Wenn die verarbeitete Datenmenge jedoch besonders groß ist, ist dies sehr zeitaufwändig und verringert die Effizienz. Heute lernen wir, den Verbindungspool zu verwenden, die Verbindung in den Verbindungspool einzufügen und bei Bedarf zu entfernen, Es nach Gebrauch wieder in den Pool zu stellen bedeutet nicht, es vom Netz zu trennen.
Die Grundidee des Datenbankverbindungspools besteht darin, einen „Pufferpool“ für Datenbankverbindungen einzurichten. Legen Sie im Voraus eine bestimmte Anzahl von Verbindungen in den Pufferpool. Wenn Sie eine Datenbankverbindung herstellen müssen, müssen Sie nur eine aus dem „Pufferpool“ nehmen und nach der Verwendung wieder hinzufügen.
Der Datenbankverbindungspool erstellt eine bestimmte Anzahl von Datenbankverbindungen und fügt diese während der Initialisierung in den Verbindungspool ein. Die Anzahl dieser Datenbankverbindungen wird durch die Mindestanzahl von Datenbankverbindungen festgelegt. Unabhängig davon, ob diese Datenbankverbindungen verwendet werden oder nicht, ist immer gewährleistet, dass der Verbindungspool über mindestens so viele Verbindungen verfügt. Die maximale Anzahl von Datenbankverbindungen im Verbindungspool begrenzt die maximale Anzahl von Verbindungen, die der Verbindungspool belegen kann. Wenn die Anzahl der von der Anwendung aus dem Verbindungspool angeforderten Verbindungen die maximale Anzahl von Verbindungen überschreitet, werden diese Anforderungen dem hinzugefügt Warteschlange.
Um das Datenbankverbindungsproblem in der traditionellen Entwicklung zu lösen, kann die Datenbankverbindungspooltechnologie verwendet werden.
Der Datenbankverbindungspool ist für die Zuweisung, Verwaltung und Freigabe von Datenbankverbindungen verantwortlich. Er ermöglicht es Anwendungen, eine vorhandene Datenbankverbindung wiederzuverwenden, anstatt eine neu aufzubauen.
Zuerst verwenden wir den DBCP-Verbindungspool (einen kostenlosen und Open-Source-Verbindungspool). Zuerst müssen wir die Datei commons-dbcp-1.4.jar darunter platzieren das aktuelle Projekt und konfigurieren Sie die Umgebung (zum Build-Pfad hinzufügen). Lassen Sie uns lernen, wie Sie den DBCP-Verbindungspool über ein Programm verwenden:
Hier müssen wir wie zuvor eine „dbcp.properties“-Datei erstellen und die erforderlichen Parameter darin einfügen Der Inhalt lautet wie folgt (diese Datei wird unter dem aktuellen Projekt abgelegt). Mit dieser Datei können Sie die Einrichtung von MySQL- und Oracle-Verbindungspools abschließen, es kann jedoch jeweils nur einer erstellt werden, und der andere muss erstellt werden kommentiert werden.
driverClassName = com.mysql.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/company
Benutzername = Root
Passwort = 123456
initialSize = 5
maxActive = 50
maxIdle = 10
#driverClassName = oracle.jdbc.driver.OracleDriver
#url = jdbc:oracle:thin:@127.0.0.1:1521:orcl
#Benutzername = Scott
#Passwort = Tiger
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(); } }
Als nächstes lernen wir einen leistungsfähigeren Verbindungspool, C3P0 (immer noch ein kostenloser und Open-Source-Verbindungspool, den wir zuerst hinzufügen müssen). Die Datei commons -dbcp-1.4.jar wird unter dem aktuellen Projekt platziert und die Umgebung wird konfiguriert (zum Build-Pfad hinzugefügt).
Hier ist ein Programm, um zu lernen, wie man den DBCP-Verbindungspool verwendet:
Wie beim DBCP-Verbindungspool müssen wir eine „c3p0-config.xml“-Datei erstellen und die erforderlichen Daten einfügen Parameter in Unter ihnen ist der Inhalt wie folgt (diese Datei wird im src-Verzeichnis des aktuellen Projekts abgelegt)
410e9fdc4dfed7c6bf6579b026d5784d
c51687d1a05d78a9c8bfbf9e7c74eb820d6c32e92ae989fc34d9e00b7bc32b5acom.mysql.jdbc.Driverdde4123f2ed5a21d0bae333af89830f9cf7527e3d84e835db325c5614ed272eejdbc:mysql://127.0.0.1:3306/schooldde4123f2ed5a21d0bae333af89830f9f7373e25e87d494693d434429b7ce642rootdde4123f2ed5a21d0bae333af89830f9ee828f7b579ab9fcb520bd2707eb425f123456dde4123f2ed5a21d0bae333af89830f997693d639e0067a4db3de784c5c67a405dde4123f2ed5a21d0bae333af89830f9fcb4c8c9635d4481996c28519c5e3a065dde4123f2ed5a21d0bae333af89830f9f8b9c1fa45b70539ab4b242d549b921d5dde4123f2ed5a21d0bae333af89830f92a833e8e9752629d2edd3c4c76fc437950dde4123f2ed5a21d0bae333af89830f90ea635411359c6d8b4b061ea2d91e1d90dde4123f2ed5a21d0bae333af89830f9ebb4d20ac968f7136ede8a953b3318815dde4123f2ed5a21d0bae333af89830f9aec5776c7f3aacabd9df06bc1412f08fc980b48734bacc1c8c19987d562b9b050d6c32e92ae989fc34d9e00b7bc32b5aoracle.jdbc.driver.OracleDriverdde4123f2ed5a21d0bae333af89830f9cf7527e3d84e835db325c5614ed272eejdbc:mysql://127.0.0.1:3306/schooldde4123f2ed5a21d0bae333af89830f9f7373e25e87d494693d434429b7ce642rootdde4123f2ed5a21d0bae333af89830f9ee828f7b579ab9fcb520bd2707eb425f123456dde4123f2ed5a21d0bae333af89830f9aec5776c7f3aacabd9df06bc1412f08f
e2c7bc088748bdf90a420dcdf517c408
DBCP连接池使用这个文件可以完成mysql、oracle的连接池的建立,每次只能建立一个,但是另一个需要注释起来。因为我们是根据c51687d1a05d78a9c8bfbf9e7c74eb82 名建立连接,
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]); } } }
综合之前学习过的知识,在这里创建一个BaseDAO8742468051c85b06f0a0af9e3e506b5c类借助DBUtils工具类实现数据操作功能:
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)!