我们在使用数据库连接的时候一般是不会让我们去手动实现jdbc去连接数据库的,不,是一定。因为jdbc不停的去创建关闭连接是很耗费资源的,所以就有了数据库连接池
数据库连接池
概念:其实就是一个容器(集合),存放数据库连接的容器。
当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
资源池的优点:
1. 节约资源 2. 用户访问高效
数据库连接池分类:
有很多种 我们来举例两个 免费的: C3P0:数据库连接池技术 --- 可以省略一本不会去使用 Druid:数据库连接池实现技术,由阿里巴巴提供的 ---主要使用这个
Druid :使用步骤
1: 首先导入 Druid的jar包 :druid-1.0.9.jar 2. 定义配置文件: * 是properties形式的 * 可以叫任意名称,可以放在任意目录下 3. 加载配置文件。Properties 4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory 5. 获取连接:getConnection
数据库连接池的close()
数据库连接池的close()是归还连接,将从数据库连接池获取的连接归还到池内不是关闭数据库连接
eg:
配置文件.properties
driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql:///girls username=zhao password=123456 # 初始化连接数量 initialSize=5 # 最大连接数 maxActive=10 # 最大等待时间 maxWait=3000
定义工具类获取配置文件建立连接
public static DataSource source; static { try { Properties pro = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); // 加载配置文件 pro.load(is); source = DruidDataSourceFactory.createDataSource(pro); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnectionOne() throws SQLException { Connection conn = source.getConnection(); return conn; }
使用
public void Update(){ Connection conn = null; PreparedStatement state = null; try { conn = JdbcPool.getConnectionOne(); -- 使用数据库连接池获取连接 String sql = "update admin set username =? where password =?"; state = conn.prepareStatement(sql); state.setObject(1,"AugustFive"); state.setObject(2,"500"); state.execute(); } catch (SQLException e) { e.printStackTrace(); } finally { if(state != null){ try { state.close(); 释放连接 将连接归还到数据库连接池内 } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。
Spring Jdbc
spring-beans-5.0.0.RELEASE-sources.jar spring-core-5.0.0.RELEASE-sources.jar spring-jdbc-5.0.0.RELEASE-sources.jar spring-tx-5.0.0.RELEASE-sources.jar commons-logging-1.2.jar 这五个jar包的导入
* 步骤: 1. 导入jar包 2. 创建JdbcTemplate对象。依赖于数据源DataSource * JdbcTemplate template = new JdbcTemplate(ds); 3. 调用JdbcTemplate的方法来完成CRUD的操作 * update():执行DML语句。增、删、改语句 * queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合 * 注意:这个方法查询的结果集长度只能是1 * queryForList():查询结果将结果集封装为list集合 * 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中 * query():查询结果,将结果封装为JavaBean对象 * query的参数:RowMapper * 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装 * new BeanPropertyRowMapper<类型>(类型.class) * queryForObject:查询结果,将结果封装为对象 * 一般用于聚合函数的查询
// Druid连接池的工具类 private static DataSource source; static { try { Properties pro = new Properties(); InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties"); pro.load(is); source = DruidDataSourceFactory.createDataSource(pro); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { Connection conn = source.getConnection(); return conn; } // 获取连接池方法 public static DataSource getSource(){ return source; }
package cn.itcast.jdbctemplate; import cn.itcast.domain.Emp; import cn.itcast.utils.JDBCUtils; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import java.sql.Date; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; public class JdbcTemplateDemo2 { //Junit单元测试,可以让方法独立执行 //1. 获取JDBCTemplate对象 private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /** * 1. 修改1号数据的 salary 为 10000 */ @Test public void test1(){ //2. 定义sql String sql = "update emp set salary = 10000 where id = 1001"; //3. 执行sql int count = template.update(sql); System.out.println(count); } /** * 2. 添加一条记录 */ @Test public void test2(){ String sql = "insert into emp(id,ename,dept_id) values(?,?,?)"; int count = template.update(sql, 1015, "郭靖", 10); System.out.println(count); } /** * 3.删除刚才添加的记录 */ @Test public void test3(){ String sql = "delete from emp where id = ?"; int count = template.update(sql, 1015); System.out.println(count); } /** * 4.查询id为1001的记录,将其封装为Map集合 * 注意:这个方法查询的结果集长度只能是1 */ @Test public void test4(){ String sql = "select * from emp where id = ? or id = ?"; Map<String, Object> map = template.queryForMap(sql, 1001,1002); System.out.println(map); //{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20} } /** * 5. 查询所有记录,将其封装为List */ @Test public void test5(){ String sql = "select * from emp"; List<Map<String, Object>> list = template.queryForList(sql); for (Map<String, Object> stringObjectMap : list) { System.out.println(stringObjectMap); } } /** * 6. 查询所有记录,将其封装为Emp对象的List集合 */ @Test public void test6(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new RowMapper<Emp>() { @Override public Emp mapRow(ResultSet rs, int i) throws SQLException { Emp emp = new Emp(); int id = rs.getInt("id"); String ename = rs.getString("ename"); int job_id = rs.getInt("job_id"); int mgr = rs.getInt("mgr"); Date joindate = rs.getDate("joindate"); double salary = rs.getDouble("salary"); double bonus = rs.getDouble("bonus"); int dept_id = rs.getInt("dept_id"); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); emp.setMgr(mgr); emp.setJoindate(joindate); emp.setSalary(salary); emp.setBonus(bonus); emp.setDept_id(dept_id); return emp; } }); for (Emp emp : list) { System.out.println(emp); } } /** * 6. 查询所有记录,将其封装为Emp对象的List集合 */ @Test public void test6_2(){ String sql = "select * from emp"; List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class)); for (Emp emp : list) { System.out.println(emp); } } /** * 7. 查询总记录数 */ @Test public void test7(){ String sql = "select count(id) from emp"; Long total = template.queryForObject(sql, Long.class); System.out.println(total); } }
.