今天,简单学习了JDBC连接池的概念和自定义连接池。
所谓连接池,就是连接完后不close,而是归还到连接池内,可以解决数据库连接的性能问题。
对于自定义连接池,我们可以自己创建连接池,然后通过这个连接池进行连接。如下代码:
1 public class MyDataSource implements DataSource{ 2 // 创建一个List集合用于存放多个连接对象. 3 private List<Connection> list = new ArrayList<Connection>(); 4 // 在程序开始的时候,初始化几个连接,将连接存放到list中. 5 public MyDataSource() { 6 // 初始化3个连接: 7 for(int i=1;i<=3;i++){ 8 Connection conn = JDBCUtils.getConnection(); 9 list.add(conn); 10 } 11 } 12 13 @Override 14 // 获得连接的方法: 15 public Connection getConnection() throws SQLException { 16 if(list.size() <= 0){ 17 for(int i=1;i<=3;i++){ 18 Connection conn = JDBCUtils.getConnection(); 19 list.add(conn); 20 } 21 } 22 Connection conn = list.remove(0); 23 return conn; 24 } 25 26 // 归还连接的方法: 27 public void addBack(Connection conn){ 28 list.add(conn); 29 } 30 ... 31 }
可这样的自定义连接会出现一定的问题,比如需要记住自己定义的API名字,并且不能使用面向对象的接口方式,等于是放弃了一个大好的特性。因此要解决这个问题,我们直接不定义自己的API,通过改写自带的方法,就可以达到一样的效果:
1 public class MyConnection implements Connection{ 2 3 private Connection conn; 4 private List<Connection> list; 5 6 public MyConnection(Connection conn,List<Connection> list) { 7 this.conn = conn; 8 this.list = list; 9 } 10 11 12 @Override 13 public void close() throws SQLException { 14 list.add(conn); 15 } 16 ... 17 } 18 19 连接池的getConnection方法: 20 @Override 21 // 获得连接的方法: 22 public Connection getConnection() throws SQLException { 23 if(list.size() <= 0){ 24 for(int i=1;i<=3;i++){ 25 Connection conn = JDBCUtils.getConnection(); 26 list.add(conn); 27 } 28 } 29 Connection conn = list.remove(0); 30 MyConnection myConn = new MyConnection(conn, list); 31 return myConn; 32 }
但实际开发中,我们可以使用开源的连接池,如DBCP和C3P0,并且学习了这两个开源连接池的使用方式:
C3P0:
第一步:引入C3P0连接池的jar包. 第二步:编写代码: * 手动设置参数: * 配置文件设置参数:
我们也可以通过书写工具类来进行一个更为便捷的操作:
1 public class JDBCUtils2 { 2 private static final ComboPooledDataSource DATA_SOURCE =new ComboPooledDataSource(); 3 /** 4 * 获得连接的方法 5 */ 6 public static Connection getConnection(){ 7 Connection conn = null; 8 try { 9 conn = DATA_SOURCE.getConnection(); 10 } catch (SQLException e) { 11 // TODO Auto-generated catch block 12 e.printStackTrace(); 13 } 14 return conn; 15 } 16 ...
对于DBCP,配置要更为繁琐:
1 @Test 2 /** 3 * 手动方式: 4 */ 5 public void demo1(){ 6 Connection conn = null; 7 PreparedStatement stmt = null; 8 ResultSet rs = null; 9 BasicDataSource dataSource = new BasicDataSource(); 10 dataSource.setDriverClassName("com.mysql.jdbc.Driver"); 11 dataSource.setUrl("jdbc:mysql:///web_07"); 12 dataSource.setUsername("root"); 13 dataSource.setPassword("123"); 14 try{ 15 // 获得连接: 16 conn = dataSource.getConnection(); 17 // 编写SQL: 18 String sql = "select * from category"; 19 // 预编译SQL: 20 stmt = conn.prepareStatement(sql); 21 // 执行SQL: 22 rs = stmt.executeQuery(); 23 while(rs.next()){ 24 System.out.println(rs.getInt("cid")+" "+rs.getString("cname")); 25 } 26 }catch(Exception e){ 27 e.printStackTrace(); 28 }finally{ 29 JDBCUtils.release(rs,stmt, conn); 30 } 31 } 32 33 @Test 34 /** 35 * 配置文件方式: 36 */ 37 public void demo2(){ 38 Connection conn = null; 39 PreparedStatement stmt = null; 40 ResultSet rs = null; 41 Properties properties = new Properties(); 42 43 try{ 44 properties.load(new FileInputStream("src/dbcpconfig.properties")); 45 DataSource dataSource = BasicDataSourceFactory.createDataSource(properties); 46 // 获得连接: 47 conn = dataSource.getConnection(); 48 // 编写SQL: 49 String sql = "select * from category"; 50 // 预编译SQL: 51 stmt = conn.prepareStatement(sql); 52 // 执行SQL: 53 rs = stmt.executeQuery(); 54 while(rs.next()){ 55 System.out.println(rs.getInt("cid")+" "+rs.getString("cname")); 56 } 57 }catch(Exception e){ 58 e.printStackTrace(); 59 }finally{ 60 JDBCUtils.release(rs,stmt, conn); 61 } 62 }
目前来说,C3P0使用的xml配置文件要更为简单和方便。
之后,学习了DBUtils的使用。DBUtils就是把JDBC的各种操作进行了简化,下面是一些实例操作:
1 package cn.itheima.jdbc.test; 2 3 import java.sql.SQLException; 4 5 import org.apache.commons.dbutils.QueryRunner; 6 import org.junit.Test; 7 8 import cn.itheima.jdbc.utils.C3P0Utils; 9 10 /** 11 * 测试DBUtils工具类的增删改操作 12 * 13 * @author Never Say Never 14 * @date 2016年7月31日 15 * @version V1.0 16 */ 17 public class TestDBUtils1 { 18 19 /** 20 * 添加所有用户方法 21 */ 22 @Test 23 public void testAddUser() { 24 try { 25 // 1.创建核心类QueryRunner 26 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 27 // 2.编写SQL语句 28 String sql = "insert into tbl_user values(null,?,?)"; 29 // 3.为站位符设置值 30 Object[] params = { "余淮", "耿耿" }; 31 // 4.执行添加操作 32 int rows = qr.update(sql, params); 33 if (rows > 0) { 34 System.out.println("添加成功!"); 35 } else { 36 System.out.println("添加失败!"); 37 } 38 } catch (SQLException e) { 39 // TODO Auto-generated catch block 40 e.printStackTrace(); 41 } 42 } 43 44 /** 45 * 根据id修改用户方法 46 * 47 */ 48 @Test 49 public void testUpdateUserById() { 50 try { 51 // 1.创建核心类QueryRunner 52 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 53 // 2.编写SQL语句 54 String sql = "update tbl_user set upassword=? where uid=?"; 55 // 3.为站位符设置值 56 Object[] params = { "xxx", 21 }; 57 // 4.执行添加操作 58 int rows = qr.update(sql, params); 59 if (rows > 0) { 60 System.out.println("修改成功!"); 61 } else { 62 System.out.println("修改失败!"); 63 } 64 } catch (SQLException e) { 65 // TODO Auto-generated catch block 66 e.printStackTrace(); 67 } 68 } 69 70 /** 71 * 根据id删除用户方法 72 */ 73 @Test 74 public void testDeleteUserById() { 75 try { 76 // 1.创建核心类QueryRunner 77 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 78 // 2.编写SQL语句 79 String sql = "delete from tbl_user where uid=?"; 80 // 3.为站位符设置值 81 Object[] params = {19}; 82 // 4.执行添加操作 83 int rows = qr.update(sql, params); 84 if (rows > 0) { 85 System.out.println("删除成功!"); 86 } else { 87 System.out.println("删除失败!"); 88 } 89 } catch (SQLException e) { 90 // TODO Auto-generated catch block 91 e.printStackTrace(); 92 } 93 } 94 }
1 package cn.itheima.jdbc.test; 2 3 import java.sql.SQLException; 4 import java.util.List; 5 import java.util.Map; 6 7 import org.apache.commons.dbutils.QueryRunner; 8 import org.apache.commons.dbutils.handlers.BeanHandler; 9 import org.apache.commons.dbutils.handlers.BeanListHandler; 10 import org.apache.commons.dbutils.handlers.ColumnListHandler; 11 import org.apache.commons.dbutils.handlers.MapListHandler; 12 import org.apache.commons.dbutils.handlers.ScalarHandler; 13 import org.junit.Test; 14 15 import cn.itheima.domain.User; 16 import cn.itheima.jdbc.utils.C3P0Utils; 17 18 /** 19 * 测试DBUtils查询操作 20 * 21 * @author Never Say Never 22 * @date 2016年7月31日 23 * @version V1.0 24 */ 25 public class TestDBUtils2 { 26 27 /* 28 * 查询所有用户方法 29 */ 30 @Test 31 public void testQueryAll() { 32 try { 33 // 1.获取核心类queryRunner 34 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 35 // 2.编写sql语句 36 String sql = "select * from tbl_user"; 37 // 3.执行查询操作 38 List<User> users = qr.query(sql, new BeanListHandler<User>(User.class)); 39 // 4.对结果集集合进行遍历 40 for (User user : users) { 41 System.out.println(user.getUname() + " : " + user.getUpassword()); 42 } 43 } catch (SQLException e) { 44 throw new RuntimeException(e); 45 } 46 } 47 48 /* 49 * 根据id查询用户方法 50 */ 51 @Test 52 public void testQueryUserById() { 53 try { 54 // 1.获取核心类queryRunner 55 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 56 // 2.编写sql语句 57 String sql = "select * from tbl_user where uid=?"; 58 //3.为占位符设置值 59 Object[] params = {21}; 60 // 4.执行查询操作 61 User user = qr.query(sql, new BeanHandler<User>(User.class), params); 62 System.out.println(user.getUname() + " : " + user.getUpassword()); 63 } catch (SQLException e) { 64 throw new RuntimeException(e); 65 } 66 } 67 68 /* 69 * 根据所有用户的总个数 70 */ 71 @Test 72 public void testQueryCount() { 73 try { 74 // 1.获取核心类queryRunner 75 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 76 // 2.编写sql语句 77 String sql = "select count(*) from tbl_user"; 78 // 4.执行查询操作 79 Long count = (Long) qr.query(sql, new ScalarHandler()); 80 System.out.println(count); 81 } catch (SQLException e) { 82 throw new RuntimeException(e); 83 } 84 } 85 86 /* 87 * 查询所有用户方法 88 */ 89 @Test 90 public void testQueryAll1() { 91 try { 92 // 1.获取核心类queryRunner 93 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 94 // 2.编写sql语句 95 String sql = "select * from tbl_user"; 96 // 3.执行查询操作 97 List<Map<String, Object>> list = qr.query(sql, new MapListHandler()); 98 // 4.对结果集集合进行遍历 99 for (Map<String, Object> map : list) { 100 System.out.println(map); 101 } 102 } catch (SQLException e) { 103 throw new RuntimeException(e); 104 } 105 } 106 107 /* 108 * 查询所有用户方法 109 */ 110 @Test 111 public void testQueryAll2() { 112 try { 113 // 1.获取核心类queryRunner 114 QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource()); 115 // 2.编写sql语句 116 String sql = "select * from tbl_user"; 117 // 3.执行查询操作 118 List<Object> list = qr.query(sql, new ColumnListHandler("uname")); 119 // 4.对结果集集合进行遍历 120 for (Object object : list) { 121 System.out.println(object); 122 } 123 } catch (SQLException e) { 124 throw new RuntimeException(e); 125 } 126 } 127 }
需要注意的是,DBUtils的方法有一些涉及到map和list等集合,这部分需要好好进行理解。
今日学习的问题:有一些jar包虽然名字一样,但实际使用起来却不一样,需要仔细看看。