jdbc 程式設計(三)
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); } }