JDBC连接池
- 概念:其实就是一个容器(集合),存放数据库连接的容器
- 当系统初始化好之后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器
- 好处:节约资源;用户访问高效
- 实现:
- 标准接口:DataSource javax.sql包下
- 方法:
- 获取连接:
getConnection()
*归还连接:如果连接对象Connection是从连接池中获取的,那么调用Connection.close()
方法,则不会再关闭连接了,二十归还连接
- 获取连接:
- 方法:
- 一般我们不去实现,由数据库厂商来实现(实现接口)
- C3P0:数据库连接技术
- Druid:数据库连接池实现技术,由阿里巴巴提供
- 标准接口:DataSource javax.sql包下
- C3P0:数据库连接池技术
- 步骤:导入jar包和依赖jar包(再加上驱动jar包一共要导入三个包)
- 定义配置文件:
- 名称:c3p0.properties 或者 c3p0-config.xml(其中由默认配置文件和自定义配置文件组成,包含连接池的参数信息)
- 路径:直接将文件放在src目录下即可
- 创建核心对象 数据库连接池对象
ComboPooledDataSource
- 获取路径:
getConnection()
- 归还连接:
close()
- 步骤:
- 获取 DataSource:
DataSource ds = new ComboPooledDataSource()
- 获取连接:
Connection conn = ds.getConnection()
- 归还连接:
conn.close()
- Druid:
- 步骤:
-
导入druid jar包和驱动jar包
-
定义配置文件:
- properties形式
- 可以叫任意名称,可以放在任意目录下
-
获取数据库连接池对象:通过工厂类来获取
DruidDataSourceFactory
例子:DataSource ds = DruidDataSourceFactory.createDataSource(Properties pro)
-
获取连接:
getConnection()
代码:public class DruidDemo{ public static void main(String[] args) throw Exception{ //1.导入jar包(将文件复制到libs下并添加) //2.定义配置文件 //3.加载配置文件 Properties pro = new Properties(); InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); //获取连接池对象 DataSource ds = DruidDataSourceFatory.createDataSource(pro); -这里直接传入properties的对象pro //获取连接 Connection conn = ds.getConnection(); //归还连接 ds.close();
- 定义工具类
- 定义一个类 JDBCUtils
- 提供静态代码块加载配置文件,初始化连接池对象
- 提供方法:
- 获取连接方法:通过数据库连接池获取连接
- 释放资源
- 获取连接池方法
public class JDBCUtils { //1.定义成员变量 DataSource private static DataSource ds ; static{ try { //1.加载配置文件 Properties pro = new Properties(); pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.获取DataSource ds = DruidDataSourceFactory.createDataSource(pro); --ds就是连接池对象 } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取连接 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /** * 释放资源 */ public static void close(Statement stmt,Connection conn){ /* if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } }*/ close(null,stmt,conn); } public static void close(ResultSet rs , Statement stmt, Connection conn){ if(rs != null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt != null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try { conn.close();//归还连接 } catch (SQLException e) { e.printStackTrace(); } } } /** * 获取连接池方法 */ public static DataSource getDataSource(){ return ds; --即使ds是null也可以返回 } }
Spring JDBC
- Spring框架提供的JDBC简单封装.提供了一个JDBCTemplate对象简化JDBC的开发(自己写的封装类来格式化管理JDBC和Java有些麻烦)
- 步骤
- 导入jar包
- 创建JdbcTemplate对象.依赖于数据源DataSource
JdbcTemplate template = new JdbcTemplate(ds);
- 调用JdbcTemplate的方法来完成CRUD的操作
-
update()
:执行DML语句 增删改语句 -
queryForMap()
:查询结构将结构集封装为map集合- 注意:这个方法查询的结果集长度只能是1
-
queryForList()
:查询结果将结果集封装为list集合- 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
-
query()
:查询结果,将结果封装为JavaBean对象- query参数:RowMapper
- 一般使用BeanPropertyRowMapper实现类.可以完成数据到JavaBean的自动封装
- new BeanPropertyRowMapper<类型>(类型.class)
- query参数:RowMapper
-
queryForObject
:查询结果,将结果封装为对象- 一般用于聚合函数的查询
public class JdbcTemplateDemo1{ public static void main(String[] args){ //1.导入jar包 (Spring JDBC的包,连接池包,驱动包) //2.创建JdbcTemplate对象 JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); //3.调用方法 String sql = "update account set balance = ? where id = ?"; --这里类似PreparedStatement预加载 template.update(sql,5000,3);--5000对应第一个问好,3对应第二个问号 System.out.println(count);
这里JDBC自动封装,自动从连接池调取连接,自动归还连接,只用专注于sql语句的书写
-
- 练习:
- 需求:(update…set…,insert into…values…,delete from…都是DML语句,直接用template对象的
update()方法
,并且还是预加载 )-
修改1号数据的salary为10000
//1.获取JdbcTemplate对象 JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); //2.定义sql String sql = "update emp set salary = 10000 where id = 1"; //3.执行sql int count = template.update(sql); System.out.println(count);
-
添加一条记录
String sql = "insert into emp(id,ename,dept_id) values(?,?,?)"; int count = template.update(sql,1015,"猴子",11); System.out.println(count);
-
删除刚才添加的记录
String sql = "delete from emp where id =?"; int count = template.update(sql); System.out.println(count);
-
查询id为1的记录,将其封装为Map集合(以下为DQL语句)
- 注意:这个方法查询的结果集长度只能是1,也就是只能查一行数据
String sql = "select * from emp where id = ?"; Map<String,Object> map = template.queryForMap(sql,1001); System.out.println(map); --这里的输出结果 {id = 1001,ename = 猴子,job_id = 4,...} --直接输出了封装后的结合
-
查询所有记录,将其封装为List集合
String sql = "select * from emp"; List<Map<String,Object>> list = template.queryForList(sql); --这里会先将数据变为Map类型,然后储存再List之中
- 注意:将每一条记录封装为Map集合,再将Map集合装载到List集合中
-
查询所有记录,将其封装为Emp对象的List集合
String sql = "select * from emp"; List<Emp> list = template.query(sql,new BeanPropertyRowMapper<Emp>(Emp.class)); for(Emp emp:list){ System.out.println(emp); }
- 注意方法
template.query(sql,new BeanPropertyRowMapper<Emp>(Emp.class));
可以直接将表中数据格式化为Emp类的格式并且储存再list之中
- 注意方法
-
查询一共有几条记录:
String sql = "select count(id) from emp"; Long total = template.queryForObject(sql,Long.class); System.out.println(total); }
-
- 需求:(update…set…,insert into…values…,delete from…都是DML语句,直接用template对象的