数据库连接池
1.数据库连接池——数据库的连接对象创建工作,比较消耗性能,因此创建了数据库连接池。
一开始先在内存中开辟一块空间(集合),一开始先在池子里面放置多个连接对象。后面需要连接的化,直接从池子里面拿。不要去自己创建连接了。使用完毕后要记得归还连接,确保连接对象能循环利用。
如图所示,表示连接池的位置。
2.开源的连接池
DBCP——DataBase Connection Pool,数据库连接池,是java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放。
C3p0(使用最多)——实现了数据源和JND绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目由Hibernate、Spring等。
针对C3p0有如下例子:
1)不使用配置文件
@Test
public void testC3p0() {
Connection connection = null;
PreparedStatement ps = null;
try {
//1.创建datasource
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2.设置连接数据的信息
dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/bank?useSSL=false&serverTimezone=UTC");
dataSource.setUser("root");
dataSource.setPassword("201633100048");
//3、得到连接对象
connection = dataSource.getConnection();
String sql = "insert into account values(null, ?, ?)";
ps = connection.prepareStatement(sql);
ps.setString(1, "sj");
ps.setInt(2, 600);
ps.executeUpdate();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(connection, ps);
}
2)使用配置文件
@Test
public void testC3p0() {
Connection connection = null;
PreparedStatement ps = null;
try {
ComboPooledDataSource dataSource = new ComboPooledDataSource("mysql");
//3、得到连接对象
connection = dataSource.getConnection();
String sql = "insert into account values(null, ?, ?)";
ps = connection.prepareStatement(sql);
ps.setString(1, "xl");
ps.setInt(2, 8000);
ps.executeUpdate();
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
JDBCUtil.release(connection, ps);
}
}
DBUtils
1.DBUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。
@Test
public void testInsert() throws SQLException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//dbutils只是帮助简化CRUD的代码,但是连接的创建以及获取工作不涉及
QueryRunner queryRunner = new QueryRunner(dataSource);
//增加
//queryRunner.update("insert into account(null, ?, ?)", "lkh", 900);
//删除
//queryRunner.update("delect from account where id = ?", 5);
//更新
//queryRunner.update("update account set money = money - ? where id =?", 200, 3);
//去执行查询,查询到的数据还是在那个reslut里面,然后调用下面的handle方法,由用户手动去封装
//直接new接口的匿名实现类
/*
* Account account = queryRunner.query("select * from account where id = ?", new
* ResultSetHandler<Account>(){
*
* @Override public Account handle(ResultSet rs) throws SQLException { Account
* account = new Account(); while(rs.next()) { int id = rs.getInt("id"); String
* name = rs.getString("name"); int money = rs.getInt("money");
*
* account.setId(id); account.setName(name); account.setMoney(money); } return
* account; }
*
*
* }, 4);
*
* System.out.println(account.toString());
*/
//通过类的字节码得到该类的实例
/*
* Account a = new Account();
* try { //创建一个类的实例
* Account a1 = Account.class.newInstance();
* } catch (InstantiationException e) { // TODO
* Auto-generated catch block e.printStackTrace(); } catch
* (IllegalAccessException e) { // TODO Auto-generated catch block
* e.printStackTrace(); }
*/
//查询单个对象,直接使用框架
/*
* Account account = queryRunner.query("select * from account where id = ?", new
* BeanHandler<Account>(Account.class),4) ;
* System.out.println(account.toString());
*/
List<Account> list = queryRunner.query("select * from account ", new
BeanListHandler<Account>(Account.class)) ;
for(Account account:list) {
System.out.print(account.toString());
}
}
2.ResultSetHeader常用实现类
使用频率最高
ArrayHandler,查询到的单个数据封装成一个数组
ArrayListHandler,查询到的多个数据封装成一个集合,集合里面的元素是数组
使用频率相对较低
BeanHandler,查询到的单个数据封装成一个对象
BeanListHandler,查询到的多个数据封装成一个集合,集合里面的元素是对象
MapHandler,查询到的单个数据封装成一个Map
MapListHandler,查询到的多个数据封装成一个集合,集合里面的元素是Map
使用频率更低
ColumnListHandler/KeyedHandler/ScalarHandler