🌊 C3P0数据库连接池
💦 方式一
@Test public void test() throws Exception { // 获取c3p0数据库连接池 // 实际开发中只需要一个数据库连接池即可 ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass("com.mysql.jdbc.Driver"); cpds.setJdbcUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8&rewriteBatchedStatements=true"); cpds.setUser("root"); cpds.setPassword("123123"); // 通过设置相关的参数对数据库连接池进行管理 // 设置初始时数据库连接池中的连接数 cpds.setInitialPoolSize(10); // 获取数据库连接 Connection connection = cpds.getConnection(); System.out.println(connection); }
💦 方式二:使用配置文件
c3p0-config.xml(配置文件默认固定为该名,src目录下)
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <named-config name="helloc3p0"> <!-- 提供获取连接的4个基本信息 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/test?characterEncoding=utf8</property> <property name="user">root</property> <property name="password">123123</property> <!-- 进行数据库连接池管理的基本信息 --> <!-- 当数据库连接池中的连接数不够时,c3p0一次性向数据库服务器申请的连接数 --> <property name="acquireIncrement">5</property> <!-- c3p0数据库连接池中初始化时的连接数 --> <property name="initialPoolSize">10</property> <!-- c3p0数据库连接池维护的最少连接数 --> <property name="minPoolSize">10</property> <!-- c3p0数据库连接池维护的最多的连接数 --> <property name="maxPoolSize">100</property> <!-- c3p0数据库连接池最多维护的Statement的个数 --> <property name="maxStatements">50</property> <!-- 每个连接中可以最多使用的Statement的个数 --> <property name="maxStatementsPerConnection">2</property> </named-config> </c3p0-config>
@Test public void test2() throws Exception { // 获取c3p0数据库连接池 // 实际开发中只需要一个数据库连接池即可 // 参数值与<named-config name="hellc3p0">中的name值一致 ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0"); // 获取数据库连接 Connection connection = cpds.getConnection(); System.out.println(connection); }
@Test public void test2() throws Exception { // 获取c3p0数据库连接池 // 参数值与<named-config name="hellc3p0">中的name值一致 ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0"); // 获取数据库连接 Connection connection = cpds.getConnection(); // System.out.println(connection); String sql = "select * from user_table"; PreparedStatement ps = connection.prepareStatement(sql); ps.execute(); ResultSet resultSet = ps.getResultSet(); while (resultSet.next()) { System.out.println(resultSet.getString("user")); } resultSet.close(); ps.close(); connection.close(); }
🌊 DBCP
💦 方式一
@Test public void test1() throws SQLException { // 创建DBCP数据库连接池 // 实际开发中只需要一个数据库连接池即可 BasicDataSource source = new BasicDataSource(); // 设置基本信息 source.setDriverClassName("com.mysql.jdbc.Driver"); source.setUrl("jdbc:mysql://localhost:3306/test?characterEncoding=utf8"); source.setUsername("root"); source.setPassword("123123"); //还可以设置其他涉及数据库连接池管理的相关属性: source.setInitialSize(10); source.setMaxActive(10); Connection connection = source.getConnection(); System.out.println(connection); }
💦 方式二:使用配置文件
src目录下新建 dbcp.properties 配置文件
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8 username=root password=123123 initialSize=10 #...
@Test public void test2() throws Exception { Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("dbcp.properties"); properties.load(is); // 实际开发中只需要一个数据库连接池即可 DataSource source = BasicDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); System.out.println(connection); connection.close(); }
💦 dbcp连接池常用基本配置属性
- initialSize :连接池启动时创建的初始化连接数量(默认值为0)
- maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
- maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)
- minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于minidle个数的连接,类似于jvm参数中的Xmn设置)
- maxWait :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起)
- poolPreparedStatements:开启池的prepared(默认是false,未调整,经过测试,开启后的性能没有关闭的好。)
- maxOpenPreparedStatements:开启池的prepared 后的同时最大连接数(默认无限制,同上,未配置)
- minEvictableIdleTimeMillis :连接池中连接,在时间段内一直空闲, 被逐出连接池的时间
🌊 Druid
💦 使用配置文件获取链接
在src目录下新建 druid.properties 配置文件
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8 username=root password=285013 driverClassName=com.mysql.jdbc.Driver
@Test public void test1() throws Exception { InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); Properties properties = new Properties(); properties.load(is); // 实际开发中只需要一个数据库连接池即可 DataSource source = DruidDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); System.out.println(connection); }
💦 Druid连接池常用基本配置属性
🥽 Apache-DBUtils实现CRUD操作
🌊 QueryRunner类
该类简单化了SQL查询,它与ResultSetHandler组合在一起使用可以完成大部分的数据库操作,能够大大减少编码量。
- QueryRunner类提供了两个构造器:
- 默认的构造器
- 需要一个 javax.sql.DataSource 来作参数的构造器
- QueryRunner类的主要方法:
- 更新
- public int update(Connection conn, String sql, Object… params) throws SQLException:用来执行一个更新(插入、更新或删除)操作。
- …
- 插入
- public T insert(Connection conn,String sql,ResultSetHandler rsh, Object… params) throws SQLException:只支持INSERT语句,其中 rsh - The handler used to create the result object from the ResultSet of auto-generated keys. 返回值: An object generated by the handler.即自动生成的键值
- …
- 批处理
- public int[] batch(Connection conn,String sql,Object[][] params)throws SQLException: INSERT, UPDATE, or DELETE语句
- public T insertBatch(Connection conn,String sql,ResultSetHandler rsh,Object[][] params)throws SQLException:只支持INSERT语句
- …
- 查询
- public Object query(Connection conn, String sql, ResultSetHandler rsh,Object… params) throws SQLException:执行一个查询操作,在这个查询中,对象数组中的每个元素值被用来作为查询语句 的置换参数。该方法会自行处理 PreparedStatement 和 ResultSet 的创建和关闭。
- …
🌊 ResultSetHandler接口及实现类
- 该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式。
- ResultSetHandler 接口提供了一个单独的方法:Object handle (java.sql.ResultSet .rs)。
- 接口的主要实现类:
- ArrayHandler:把结果集中的第一行数据转成对象数组。
- ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中。
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中。
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
- ColumnListHandler:将结果集中某一列的数据存放到List中。
- KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里,再把这些map再存到一个map里,其key为指定的key。
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
- ScalarHandler:查询单个值对象,用于查询特殊值
🌊 插入数据
@Test public void test1() throws Exception { Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); properties.load(is); DataSource source = DruidDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); QueryRunner queryRunner = new QueryRunner(); String sql = "insert into customers(name, email, birth) values(?, ?, ?)"; // 填充执行sql, 返回影响的行数 int insterCount = queryRunner.update(connection, sql, "ZS", "ZSZSZS@qq.com", "2001-11-23"); System.out.println("添加的记录条数为:" + insterCount); connection.close(); }
🌊 查询数据
@Test public void test1() throws Exception { Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); properties.load(is); DataSource source = DruidDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); QueryRunner queryRunner = new QueryRunner(); String sql = "select id, name, email from customers where id=?"; BeanHandler<Customer> customerBeanHandler = new BeanHandler<>(Customer.class); Customer customer = queryRunner.query(connection, sql, customerBeanHandler, 10); System.out.println(customer); }
@Test public void test1() throws Exception { Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); properties.load(is); DataSource source = DruidDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); QueryRunner queryRunner = new QueryRunner(); String sql = "select id, name, email from customers where id<?"; BeanListHandler<Customer> customerBeanHandler = new BeanListHandler<>(Customer.class); List<Customer> customerList = queryRunner.query(connection, sql, customerBeanHandler, 10); customerList.forEach(System.out::println); }
@Test public void test1() throws Exception { Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); properties.load(is); DataSource source = DruidDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); QueryRunner queryRunner = new QueryRunner(); String sql = "select id, name, email from customers where id<?"; MapListHandler mapListHandler = new MapListHandler(); List<Map<String, Object>> query = queryRunner.query(connection, sql, mapListHandler, 10); for (Map<String, Object> q: query) { System.out.println(q); } }
🌊 查询特殊值
@Test public void test1() throws Exception { Properties properties = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); properties.load(is); DataSource source = DruidDataSourceFactory.createDataSource(properties); Connection connection = source.getConnection(); QueryRunner queryRunner = new QueryRunner(); String sql = "select count(*) from customers"; ScalarHandler handler = new ScalarHandler(); Long query = (Long) queryRunner.query(connection, sql, handler); System.out.println(query); }
🌊 自定义ResultSetHandler的实现类
/* * 自定义ResultSetHandler的实现类 */ @Test public void testQuery7(){ Connection conn = null; try { QueryRunner runner = new QueryRunner(); conn = JDBCUtils.getConnection3(); String sql = "select id,name,email,birth from customers where id = ?"; ResultSetHandler<Customer> handler = new ResultSetHandler<Customer>(){ @Override public Customer handle(ResultSet rs) throws SQLException { // System.out.println("handle"); // return null; // return new Customer(12, "成龙", "Jacky@126.com", new Date(234324234324L)); if(rs.next()){ int id = rs.getInt("id"); String name = rs.getString("name"); String email = rs.getString("email"); Date birth = rs.getDate("birth"); Customer customer = new Customer(id, name, email, birth); return customer; } return null; } }; Customer customer = runner.query(conn, sql, handler,23); System.out.println(customer); } catch (SQLException e) { e.printStackTrace(); }finally{ JDBCUtils.closeResource(conn, null); } }