posts - 78, comments - 34, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          2009-12-10傳智播客jdbc——高級應用

          Posted on 2009-12-11 00:18 長城 閱讀(346) 評論(0)  編輯  收藏

                   Oracle數據庫部分終于在昨天結束了,整理學習日志到很晚。今天繼續講解JDBC,是方老師授課的。方老師在我們班還有六堂的課程,多少有些舍不得,他是個好老師。學完這六堂課,JAVAWEB基礎到此也就結束了(09-12-18)。十分渴望快些學習到項目那,把這些技術混合運用,做出個像模像樣的東西來!

           

                   今天的內容依然很多,我還是好好把它整理出來吧!

           

          一、JDBC中調用Oracle存儲過程:

                   例,在Oracle中創建一個存儲過程:

          CREATE OR REPLACE PROCEDURE UPEMPFUN(

                 ARG_EMPNO IN NUMBER,

                 ARG_SAL IN NUMBER,

                 ARG_RES OUT VARCHAR

          )IS BEGIN 

              UPDATE EMP SET SAL = ARG_SAL WHERE EMPNO=ARG_EMPNO;

              COMMIT; 

              ARG_RES := 'OK!';

          END;

                   JDBC中,調用上面的存儲過程(我的Oralce出問題了,沒有測試):

          CallableStatement cStmt = conn.prepareCall("{call UPEMPFUN(?, ?, ?)}");

          // 注冊接收返回值的變量

          cStmt.registerOutParameter(3, Types.VARCHAR);

          cStmt.setInt(1, 7360);

          cStmt.setFloat(1, 8888);

          cStmt.execute();

          // 打印返回值

          System.out.println(cStmt.getString(3));

           

          二、JDBC數據庫中的分布技術:

          1.ResultSet提供了對結果集進行滾動的功能:

          next():移動到下一行

          Previous():移動到前一行

          absolute(int row):移動到指定行

          beforeFirst():移動resultSet的最前面

          afterLast() :移動到resultSet的最后面

           

                   使用上面的滾動記錄功能可以實現分頁功能,但建議不要使用這種技術進行分頁。因為當記錄數量大的時間,會帶來性能上的下降,資源的浪費。

           

                   2.MySQL分頁語句:

                   Select * from tab_ame limit M,N;

                   M:記錄起始索引位置

                   N:獲取記錄數量

           

                   3.Oracle分頁語句(TOP-N技術):

                   Select * from (

                             Select rownum rn,* from (

                                      Select * from tab_name where 條件

          ) where rownum <=結束位置

          )where rn >=起始位置

                   它與MySql分頁相比,MySql更方便些。而且MySql中的N直接獲取記錄數量,但Oracle中卻是結束位置的索引和起始位置的索引之間的記錄。

           

                   4.編寫一個WEB應用,使用分布技術顯示數據庫中的記錄:

          簡易流程圖:(如果看不到圖片,請到這里:http://www.aygfsteel.com/changcheng/)

          clip_image002

          ListStudent.javadoGet部分:

              public void doGet(HttpServletRequest request, HttpServletResponse response)

                     throws ServletException, IOException {

                 // 獲取總記錄數量

                 StudentDao sd = new StudentDao();

                 int totalrecord = 0;

                 int pagenum = 0;

                 Page page = null;

                 try {

                     totalrecord = sd.getTotal();

                     // 獲取記錄信息

                     String currage = request.getParameter("currpage");

                     page = new Page(totalrecord, (currage != null) ? Integer

                            .parseInt(currage) : 1);

                     page.setRecord(sd.getRecord(page.getStartindex(), page.getPagesize()));

                 } catch (Exception e) {

                     e.printStackTrace();

                 }

                

                 // 將信息發往index.jsp進行顯示

                 request.setAttribute("page", page);

                 request.getRequestDispatcher("index.jsp").forward(request, response);

              }

           

          Student.java

          public class StudentDao {

              // 獲取學生總數

              public int getTotal() throws SQLException {

                 // 獲取連接

                 Connection conn = JdbcUtil.getDataSource().getConnection();

                 // 查詢數量

                 PreparedStatement ps = conn

                        .prepareStatement("select count(*) from student");

                 ResultSet rs = ps.executeQuery();

                 int total = 0;

                 while (rs.next()) {

                     total = rs.getInt(1);

                 }

                 // 釋放連接

                 JdbcUtil.release(rs, ps, conn);

                 return total;

              }

           

              // 獲取記錄

              public List getRecord(int startindex, int count) throws SQLException {

                 // 獲取連接

                 Connection conn = JdbcUtil.getDataSource().getConnection();

                 // 查詢記錄

                 PreparedStatement ps = conn

                        .prepareStatement("select id,name,sex from student limit ?,?;");

                 ps.setInt(1, startindex);

                 ps.setInt(2, count);

                 ResultSet rs = ps.executeQuery();

                 // 讀取記錄

                 List result = new ArrayList();

                 while (rs.next()) {

                     StudentBean stuben = new StudentBean();

                     stuben.setId(rs.getInt("id"));

                     stuben.setName(rs.getString("name"));

                     stuben.setSex(rs.getBoolean("sex"));

                     result.add(stuben);

                 }

                 // 釋放連接

                 JdbcUtil.release(rs, ps, conn);

                 return result;

              }

           

          }

           

          Page.java

          public class Page {

              private int totalrecord;// 總記錄數

              private int totalpage;// 總頁面數

              private int pagesize = 3;// 頁面顯示記錄數

              private int startindex;// 起始索引

              private int currpage;// 當前頁面

              private List record;// 記錄

           

              public Page(int totalrecord, int currpage) {

                 this.totalrecord = totalrecord;

                 this.currpage = currpage;

              }

              public int getTotalrecord() {

                 return this.totalrecord;

              }

              public List getRecord() {

                 return record;

              }

              public void setRecord(List record) {

                 this.record = record;

              }

              // 計算總頁面數

              public int getTotalpage() {

                 if (this.totalrecord % this.pagesize == 0)

                     totalpage = this.totalrecord / this.pagesize;

                 else

                     totalpage = this.totalrecord / this.pagesize + 1;

           

                 return this.totalpage;

              }

              // 計算起始索引

              public int getStartindex() {

                 this.startindex = (this.currpage - 1) * this.pagesize;

                 return this.startindex;

              }

              public int getPagesize() {

                 return this.pagesize;

              }

          }

           

          Index.jspbody部分:

              <body>

                  HI

                  <hr>

                  <table border="1">

                  <tr>

                      <td>ID</td><td>姓名</td><td>性別</td>

                  </tr>

                  <!-- 顯示記錄信息 -->

                  <cc:forEach var="record" items="${page.record}">

                  <tr>

                      <td>${record.id }</td><td>${record.name }</td><td>${record.sex }</td>

                  </tr>

                  </cc:forEach>

                 

                  <!-- 顯示翻頁信息 -->

                  </table>

                  <cc:forEach var="i" begin="1" end="${page.totalpage}">

                   <a href="http://localhost:8080/091210/ListStudent?currpage=${i}">${i}</a>

              </cc:forEach>

              </body>

           

                   如果連接的是Oracle數據庫,則使用Oracle數據庫的TOP-N技術即可!

           

          三、JDBC對數據庫LOB操作:

                   LOB數據(LargeObject),簡稱大對象。它分為兩類:

          1.        CLOBCharactorLargeObject,專門用于處理字符的大對象。

          2.        BLOBByteLargeObject,專門用于處理二進制數據,比如圖片等。

           

          1.        MySQL中的LOB操作:

          MySQL中:TEXTCLOB對應,BLOBBLOB對應。

          調用下面的方法設置TEXT

          PreparedStatement.setCharacterStream(index, reader, length);

          //注意length長度須設置,并且設置為int

          調用下面的方法獲取TEXT

          1.reader = resultSet. getCharacterStream(i);

          2.reader = resultSet.getClob(i).getCharacterStream();

          3.string = resultSet.getString(i);

           

          調用下面的方法設置BLOB

          PreparedStatement.setBinaryStream(i, inputStream, length);

          調用下面的方法獲取BLOB

          1.InputStream in = resultSet.getBinaryStream(i);

          2.InputStream in = resultSet.getBlob(i).getBinaryStream();

           

          MySql數據庫中使用LOB字段,直接定義這個字段的類型為“TEXT”或“BLOB”即可!

           

          2.        Oracle中的LOB操作:

          OracleCLOB與“EMPTY_CLOB()”對應,“BLOB”與“EMPTY_BLOB()”對應。

          Oracle中設置和獲取BLOBJDBC方法與MySQL相同。

          Oralce中添加LOB字段插入內容時,必須在事件中進行否則極可能出錯。

           

          注意:在Oracle數據庫中添加CLOB字段必須使用“empty_clob()”,添加BLOB字段必須使用“empty_blob()”。在對他們進行賦值時,必須使用查詢語句獲取對應字段名的指針。在獲取字段指針的查詢語句結尾必須使用“fro update”這樣鎖定該行,保證不會發生沖突。

           

          例,向Oracle數據庫寫入大文本操作:

          private static void save() throws Exception {

                 // 獲取連接

                 Connection conn = JdbcUtil.getDataSource().getConnection();

                 conn.setAutoCommit(false);

                 PreparedStatement ps = conn

                        .prepareStatement("insert into ocolb(id, text) values (1,empty_clob())");

                 ps.executeUpdate();

                 // 獲取指針

          ps = conn.prepareStatement("select text from ocolb where id=1 for update;");

                 ResultSet rs = ps.executeQuery();

                 // 寫入數據

                 File imfi = new File("C:/ocolb.txt");

                 Reader reader = new FileReader(imfi);

                 //ps.setCharacterStream(1, reader, imfi.length());

                 CLOB clob = (CLOB) rs.getClob("text");

                 Writer writer = clob.getCharacterOutputStream();

                 char[] buf = new char[1024];

                 int len = 0;

                 while((len = reader.read(buf)) != -1){

                     writer.write(buf, 0, len);

                 }

                 reader.close();

                 writer.close();

                 // 提交

                 conn.commit();

                 // 釋放連接

                 JdbcUtil.release(rs, ps, conn);

              }

           

          四、JDBC對數據庫批量操作:

          當我們向數據庫的一個表中插入100條記錄時,比如向employee表中插入100名員工。難道我們要一條條語句執行?如果插入100萬條呢?后果可想而知,所以需要批量操作來完成此任務。

           

          JDBC中有兩種方法可以進行指操作:

          1.        Statement.addBatch(sql)

          實現批處理的缺點:當向表中使用sql語句批量插入數據時,采用此種方式需重復寫上多條語句相同,只參數不同的sql語句,工作量大,可讀性差。

          String sql1 = "insert into employee(id,name) values(1,'aaa')";       

          String sql2 = "insert into employee(id,name) values(2,'bbb')";

          st = conn.createStatement();

          st.addBatch(sql1);

          st.addBatch(sql2);

          st.executeBatch();

           

          2.        PreparedStatement. addBatch()

          SQL語句相同,但參數相同。此種方法主要用于在同一個表中批量插入數據、或批量更新數據。

          String sql2 = "insert into employee(name,department_id) values(?,?)";

          ps = conn.prepareStatement(sql2);            

          Iterator it = department.getEmployees().iterator();

          while(it.hasNext()){

              Employee e = (Employee) it.next();

              ps.setString(1, e.getName());

              ps.setInt(2, id);

              ps.addBatch();

          }

           

           

          五、JDBC操作多個實體:

          操作多個實體?這個玩法第一次聽說。說直白些就是將JAVA對象與數據庫的表,關聯起來。如何關聯?當然是通過代碼關聯了。

           

          例:

          1.創建departmentemployee表:

          Create table department(

              id int primary key auto_increment,

              name varchar(50)

          )

           

          Create table employee(

              id int primary key auto_increment,

              name varchar(30),

              department_id int,

              constraint for_ke foreign key(department_id) references department(id)

          )

           

          2.定義DepartmentEmployee類:

          public class Department {

              private int id;

              private String name;

              private Set<Employee> employees = new HashSet<Employee>();

          }

           

          public class Employee {

              private int id;

              private String name;

              private Department department;

          }

           

          3.創建一個多Department對象,創建多個個Employee對象,添加到Department對象的SET中。

           

          4.定義一個工具類,將Department對象給工具類的SAVE方法,SAVE方法使用批量操作,將數據添加到數據庫的departmentemployee表中。

           

          注意:

          JAVA里邊無論對象和對象之間什么關系,反應到數據庫中就是外鍵關聯。

          在應用設計中盡量不要使用一對多的關系或多對多關系,而是使用多對一的關系。

           

          整理日志比較辛苦,加油!


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 固始县| 聊城市| 精河县| 南康市| 义乌市| 大厂| 温州市| 娄底市| 柞水县| 滁州市| 岑巩县| 尼勒克县| 米脂县| 抚松县| 漯河市| 来宾市| 安多县| 伽师县| 岳普湖县| 健康| 高台县| 珠海市| 彭州市| 焦作市| 昌黎县| 花莲县| 东城区| 城口县| 宁国市| 林周县| 广东省| 庆城县| 德安县| 宣威市| 论坛| 本溪市| 平阴县| 铜川市| 花莲县| 前郭尔| 五家渠市|