1.为什么要使用连接池?
如果应用程序直接获取数据库连接,有弊端:用户每次请求都需要向数据库获得连接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设一个网站每天有10万次访问量,那么数据库服务器就需要创建10万次连接,这极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、脱机。
为了解决上述问题,数据库连接池的技术便得到了广泛的使用。为了优化性能,应用程序一启动,就向数据库要一批连接放到池(也就是一个集合而已)中,当用户箱操作数据库的时候,直接找连接池要,当完成对数据库的操作后,再把连接还给连接池供其他用户使用。
2.使用javax.sql.DataSource接口来表示连接池
使用连接池获得连接池对象的三种方式:
1.参数设置的方式:
/*使用dbcp连接池获取连接对象时,必须配置的四个参数*/ /* BasicDataSource bds = new BasicDataSource(); bds.setDriverClassName("com.mysql.jdbc.Driver"); bds.setUrl("jdbc:mysql://localhost:3306/database"); bds.setUsername("root"); bds.setPassword("root"); */
2.读取资源配置文件的方式
/*Properties prop = new Properties(); try { prop.load(new FileInputStream("dbcp.properties")); bds.setDriverClassName(prop.getProperty("driverClassName")); bds.setUrl(prop.getProperty("url")); bds.setUsername(prop.getProperty("username")); bds.setPassword(prop.getProperty("password")); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); }*/
3.通过BasicDataSourceFactory 工厂 直接读取配置文件 获得连接池对象
public static DataSource getDataSource(){ Properties pro = new Properties(); DataSource ds = null; try { pro.load(new FileInputStream("gjp.properties")); ds = new BasicDataSourceFactory().createDataSource(pro); } catch (Exception e) { e.printStackTrace(); } return ds; }
注意:在日常编写代码的时候都使用第三种方式,
配置文件 一定注意里面的属性名称必需要和这边的对应上,参考下面的格式。
driverClassName = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/jdbcwork?useUnicode=true&characterEncoding=UTF-8 username = root password = root initialSize=10 #连接池启动时的初始值 maxActive=50 #连接池的最大值 maxIdle=20 #连接池的最大空闲数 minIdle=5 #连接池的最小空闲数
3.DBUtils就是JDBC的简化开发工具包
在此顺便介绍下有关jdbc 常用的 jar 包
- commons-dbutils-1.4.jar:封装并简化了JDBC;
- commons-dbcp-1.4.jar:apache commons提供的数据库连接池组件,命名为DBCP;
- commons.pool-1.3.jar:DBCP连接池依赖该jar包;
- mysql-connector-java-5.1.28-bin.jar:MySQL的JDBC驱动包,用JDBC连接MySQL数据库必须使用该JAR包。
Dbutils三个核心类介绍:
1. QueryRunner中提供对sql语句操作的API.
update(Connection conn, String sql, Object... params) ,用来完成表数据的增加、删除、更新操作
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) ,用来完成表数据的查询操作
2. ResultSetHandler接口,用于定义select操作后,怎样封装结果集.
3. DbUtils类,它就是一个工具类,定义了关闭资源与事务处理的方法
4.使用 DBUtils 工具包对教师表格 进行增删改查
1.Teacher 实体类
public class Teacher { private String username; private String passWord; private int age; private boolean sex; private String intro; public String getUsername() { return username; }。。。。。。
2. TeacherDaoImpl 类对数据库操作
public class TeacherDaoImpl { QueryRunner qr = new QueryRunner();//创建封装类对象(提供了 update(),query() // 插入一条数据 public void insert(String sql,Object... params){ try { Connection conn = JDBCUtils.getDataSource().getConnection(); //获取连接对象 qr.update(conn,sql, params); } catch (Exception e) { e.printStackTrace(); } } /*方式一:查多个*/ public void select(String sql, Object[] params) { //ArrayListHandler:将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。 //ArrayHandler:将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值 try { Connection conn = JDBCUtils.getDataSource().getConnection(); List<Object[]> stus = qr.query(conn,sql,new ArrayListHandler(), params); for (Object[] i : stus) { System.out.println(Arrays.toString(i)); } /*Object[] teas = qr.query(conn,sql,new ArrayHandler(), params); System.out.println(Arrays.toString(teas));*/ } catch (Exception e) { e.printStackTrace(); } } /*方式二:查多个*/ public List<Teacher> select2(String sql) { // BeanHandler将结果集中第一条记录封装到一个指定的javaBean中。 // BeanListHandler将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中 List<Teacher> teas = null; try { Connection conn = JDBCUtils.getDataSource().getConnection(); teas= qr.query(conn, sql,new BeanListHandler<Teacher>(Teacher.class)); System.out.println("--------"); Teacher t1 = qr.query(conn, sql, new BeanHandler<>(Teacher.class)); System.out.println(t1); System.out.println("--------"); } catch (Exception e) { }finally { } return teas; } /*查寻某列的所有值*/ public List select3(String sql, Object[] params) { List strs = null; try { Connection conn = JDBCUtils.getDataSource().getConnection(); strs = qr.query(conn, sql, new ColumnListHandler<>(), params); } catch (Exception e) { } return strs; } /*当结果集返回一条记录时*/ public int select4(String sql) { int num = 0; try { Connection conn = JDBCUtils.getDataSource().getConnection(); num = qr.query(conn, sql, new ScalarHandler<Integer>()); } catch (Exception e) { e.printStackTrace(); } return num; } }
3.测试类
public class TestTeacher { //插入一条数据 @Test public void insert(){ Object[] params = {"王五","121456",29,1,"英语老师"}; String sql = "insert into teacher(id,username,password,age,sex,intro)values(null,?,?,?,?,?)"; new TeacherDaoImpl().insert(sql, params); } /*方式一:查多个*/ @Test public void select(){ Object[] params = {}; String sql = "select * from teacher"; new TeacherDaoImpl().select(sql, params); } /*方式二:查多个*/ @Test public void select2(){ String sql = "select username,password,age,intro,sex from teacher"; List<Teacher> teas = new TeacherDaoImpl().select2(sql); for (Teacher i : teas) { System.out.println(i); } } /*查寻某列的所有值*/ @Test public void select3(){ String sql = "select username from teacher where age >= ?"; Object[] params = {19}; List teas = new TeacherDaoImpl().select3(sql,params); for (Object str : teas) { System.out.println(str); } } /*当结果集返回一条记录时*/ @Test public void select4(){ //String sql = "select count(*) from student where age >= ?";//查年龄大于等于19岁的人的个数 String sql = "select max(age) from teacher";//查记录中最大的年龄 Object[] params = {19}; int num = new TeacherDaoImpl().select4(sql); System.out.println(num); } }