<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

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

    2009-12-11傳智播客——jdbc與DBUtil

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

             今日是JDBC的最后一天了,繼續JDBC的高級應用。說是高級應用,只是針對JDBC的再次封裝,使得使用JDBC變得更加簡單。DBUtil就是這樣的庫!今日上午首先講解JDBC操作多個實體之多對多關系,Hibnate正是使用了這樣的手法,這一功能讓人感覺很好。然后方老師將以前使用的JDBC操作中,有重復的代碼提取出來,形成一個單獨的類,大大簡化了JDBC的操作。起初我還沒有想到這就是DBUtil,若不是老方說:我們是不是還有DBUtil沒講?我們現在就已經做出來了!呵呵,就這么簡單!

     

             開始復習、總結今日的主要內容!

     

    一、JDBC操作多個實體——多對多

             昨天有簡單的介紹一對多的關系,使用的是部門表與員工表式之間的關系。下面舉例使用,老師表與學生表之間的關系。

     

             首先讓我們設計一個老師表(老師能找到自己的學生):

    ID

    姓名

    學生ID(外鍵)

    1

    張三峰

    1

    2

    方世玉

    2

    1

    張三峰

    1

    2

    方世玉

    2

     

     

     

             再設計一個學生表(學生能找到自己的老師):

            

    ID

    姓名

    教師ID(外鍵)

    1

    AAA

    1

    2

    BBB

    2

    1

    AAA

    1

    2

    BBB

    2

     

     

     

             顯而易見上邊的兩張表設計的有問題,比較“臟”一點也不優雅。我們得想一個辦法解決它!

             創建一個中間表:

    教師_ID(外鍵)

    學生_ID(外鍵)

    1

    1

    2

    2

    1

    2

    2

    1

     

     

     

     

     

     

            

     

     

    “教師_ID”字段是外鍵,指向教師表中的ID?!皩W生_ID”是個外鍵,指向學生表中的ID。在某些情況下中間表還定義一些其他字段。

     

             去除教師表中的“學生ID”和學生表中的“教師ID”,這樣以后只要連表查詢即可。

     

             上面只是舉個例子,在實際開發中應該先創建對象模型,然后再創建數據庫關系模型。使用對象反應上邊的關系模型,依然是兩個對象。教師對象和學生對象,教師對象有一個SET成員,記錄他的所有學生。學生對象包含一個SET記錄他的所有教師。

     

             創建多個學生對象(不需要設置SET成員),將他們添加到教師對象的SET中。將教師對象傳遞給DAO工具對象,DAO工具對象讀取教師,將教師信息保存到教師表中。然后遍歷所有學生,將學生信息保存到學生表中,同時將教師ID與學生ID保存到中間表中。OK,這樣就完成了!

     

             這就是多對多關系——建立兩個一對多關系!

     

             再次注意:要盡量使用多對一關系,而避免使用一對多或多對多關系!

     

    二、簡化JDBC操作——DBUtil實現原理和元數據

             還記得我們以前寫的操作數據庫記錄的DOMAIN類嗎?回想一下,插入記錄、修改記錄、查詢記錄、刪除記錄。在這些方法中,我們都需要獲取數據庫連接,對數據記錄操作完成后,還需要釋放這些記錄。沒感覺到什么不對嗎?當然感覺到了,重復的代碼。既然有重復的代碼就應該將它提取出來,實現代碼的重用。OK,現在我們就把重復的代碼提取出來。為了減小篇章,我們只提取插入記錄(update)和查詢記錄。因為修改和查詢與插入一樣都是調用update語句。

     

    MyDBUtil.java

    /**

     * 封裝JDBC操作中重復的代碼,使JDBC操作變得簡單。

     * @author Administrator

     *

     */

    public class MyDBUtil {

        // update可以執行 添加、修改、刪除操作!

        public void update(String sql, Object[] args) {

           Connection conn = null;

           PreparedStatement ps = null;

           ResultSet rs = null;

           try {

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

               // 將參數填充到sql語句中

               ps = conn.prepareStatement(sql);

               for (int i = 0; args != null && i < args.length; i++) {

                  ps.setObject(i + 1, args[i]);

               }

               ps.executeUpdate();

     

           } catch (SQLException e) {

               e.printStackTrace();

           } finally {

               // 釋放連接

               JdbcUtil.release(conn, ps, rs);

           }

        }

     

        // 查詢操作

        public Object find(String sql, Object[] args, ResultSetHandler rsh) {

           Connection conn = null;

           PreparedStatement ps = null;

           ResultSet rs = null;

           Object obj = null;

           try {

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

               // 將參數填充到sql語句中

               ps = conn.prepareStatement(sql);

               // 獲取查詢結果

               rs = ps.executeQuery();

               for (int i = 0; args != null && i < args.length; i++) {

                  ps.setObject(i + 1, args[i]);

               }

               // 調用Handler封裝數據

               obj = rsh.handler(rs);

           } catch (Exception e) {

               e.printStackTrace();

           } finally {

               // 釋放連接

               JdbcUtil.release(conn, ps, rs);

           }

           return obj;

        }

    }

     

    ResultSetHandler.java

    /**

     * Handler,使用策略模式封裝ResultSet中的數據到Bean中。

     * @author Administrator

     *

     */

    interface ResultSetHandler{

        Object handler(ResultSet rs);

    }

     

    BeanHandler.java

    /**

     * Handler,實現類

     * @author Administrator

     *

     */

    class BeanHandler implements ResultSetHandler{

        Class clazz;

       

        public BeanHandler(Class clazz){

           this.clazz = clazz;

        }

       

        public Object handler(ResultSet rs) {    

           Object obj = null;

           try {

    // 注意此處使用的ResultSetMetaData,元數據

               ResultSetMetaData rsd;

               rsd = rs.getMetaData();

               obj = this.clazz.newInstance();

               // 將讀取的記錄設置到Bean對象中

               for (int i = 1; i <= rsd.getColumnCount(); i++) {

                  // 獲取字段名

                  String cln = rsd.getColumnName(i);

                  // 獲取成員

                  Field field = this.clazz.getDeclaredField(cln);

                  // 設置成員值

                  field.setAccessible(true);

                  field.set(obj, rs.getObject(i));

               }

              

           } catch (Exception e) {

               e.printStackTrace();

           }

           return obj;

        }  

    }

     

             上面只是簡單的對JDBC的重復代碼進行了封裝,并使用策略模式對find操作返回值進行了與具體Bean的分離,十分優雅。DBUtil工具包,就是使用上面的原理實現的!

     

             注意:Handler實現類中的“ResultSetMetaData”,它被稱為元數據。JDBC的元數據有:

    1.        Connection.getDataBaseMetaData(),返回DataBaseMetaData,它包含的方法有:

    getURL():返回一個String類對象,代表數據庫的URL

    getUserName():返回連接當前數據庫管理系統的用戶名。

    getDatabaseProductName():返回數據庫的產品名稱。

    getDatabaseProductVersion():返回數據庫的版本號。

    getDriverName():返回驅動驅動程序的名稱。

    getDriverVersion():返回驅動程序的版本號。

    isReadOnly():返回一個boolean值,指示數據庫是否只允許讀操作。

     

    老方說有的框架會使用到它,來獲取數據庫的連接等信息。具體在框架中如何應用,等到學習框架時再深入吧!

     

    2.        PreparedStatement.getParameterMetaData(),返回ParameterMetaData,它包含的方法:

    getParameterCount():獲得指定參數的個數

    getParameterType(int param):獲得指定參數的sql類型

     

    在上面的例子中有用到過,在DBUtil中有使用getParameterType獲取數據類型填充空的Statement參數。

     

    3.        ResultSet.getMetaData(),返回ResultSetMetaData,它包含的方法:

    getColumnCount():返回resultset對象的列數

    getColumnName(int column):獲得指定列的名稱

    getColumnTypeName(int column):獲得指定列的類型

     

             在上面的例子中我們有使用ResultSetMetaData

     

             O-R Mapping(Object – Relation Mapping)映射工具,對象模型與關系模型的映射:Hibernate、IbatisDBUtil。

     

             DBUtil在此就不多做介紹了,學了上邊的實現原理,自己也可以編寫一個DBUtil出來。DBUtil的具體使用方式可以查看它的文檔! 

     

    三、XML Schema

             今日的課程的補充,咱們的Servletweb.xml文件正是使用Schema描述的。以后的框架中也會使用它。Schema已經成為w3c組織的標準,并逐步取代DTD。Schema要比DTD復雜的多,因為它引入了命名空間,多數據類型這些操作。Schema也是個XML文件!

     

             今日就簡單學習一下Schema,不深入介紹了,其實它也沒什么。

     

    1.        定義Schema約束文件:     

    <?xml version="1.0" encoding="UTF-8" ?>

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"

        targetNamespace="http://www.changcheng.org"

           elementFormDefault="qualified">

    <xs:element>

        <xs:complexType>

           <!-- 要求元素必須按照下邊的順序排列,沒有數量限制 -->

           <xs:sequence maxOccurs='unbounded' >

           <!-- 根元素 -->

           <xs:element name='根元素名稱' >

           <!-- 可添加多個子元素 -->

               <xs:complexType>

                  <!-- 要求元素必須按照下邊的順序排列 -->

                  <xs:sequence>

                      <!-- 子元素可以定義自己的多個子元素 -->

                      <xs:element name='子元素名稱' type='xs:元素類型' />

                  </xs:sequence>

               </xs:complexType>

           </xs:element>

           </xs:sequence>

        </xs:complexType>

    </xs:schema>

            

             其中“targetNamespace”定義自己編寫的Schema的命名空間。

     

    2.        XML引入并使用Schema約束:

    <cc:根元素 xmlns:cc="http://www.changcheng.org"

                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

                  xsi:schemaLocation="http://www.changcheng.org book.xsd">

           <cc:子元素>元素值</cc:子元素>

    </cc:根元素>

     

             其中“xsi:schemaLocation”指定引入的Schema文件所在的位置。一個XML文件中可以引入多個Schema約束文件。同樣在“xsi:schemaLocation”使用空格分隔,指定Schema約束文件的位置?!?/span>xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"”不需要指定位置,因為它是w3c組織定義的文件,Schema解析器,知道它的具體位置。

     

             Schema文檔通常稱之為模式文檔(約束文檔),遵循這個文檔書寫的xml文件稱之為實例文檔。Schema具體使用方式參見w3c的文檔吧!

     

             OK,今天的課程內容總結到此結束!老方剛上課時就提到大家一起合影,但課上一直很忙。今天本要合影的,但也沒抽出時間。大家一起定下后天中午合影。早就想跟大家一起合影了!

     

             老方還有5天的課程就結束了JAVAWEB基礎部分,由此步入高級應用的殿堂。大家學習興致勃勃,一定要多練習啊!到后來的項目,一天寫上千行代碼都正常。高級應用,使用上非常簡單,其實我們學習的基礎部分,也為學習高級應用打下了堅實的基礎。因為高級應用中那些框架正是使用這些基礎知識實現的。

     

             我來此學習還有一個大的目標就是,項目架構、文檔的編寫、項目的管理、UML…這些對我來說太重要了,我可不是新手哦!我對此十分期待!

     

             加油!


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


    網站導航:
     
    主站蜘蛛池模板: 亚洲欧洲春色校园另类小说| 91精品国产免费久久久久久青草| 亚洲黄色激情视频| 亚洲AV永久青草无码精品| 又爽又高潮的BB视频免费看| 日本免费网址大全在线观看| 免费在线看污视频| 一级特黄录像免费播放肥| 国产精品亚洲综合网站| 亚洲粉嫩美白在线| 亚洲日韩中文字幕| 色婷婷六月亚洲婷婷丁香| 亚洲国产精品成人精品无码区| 四虎影视精品永久免费网站| 在线播放高清国语自产拍免费 | 在线免费观看毛片网站| 亚洲视频免费在线播放| 久久青草免费91线频观看不卡| 好男人资源在线WWW免费| 一级毛片免费不卡| 又黄又大的激情视频在线观看免费视频社区在线 | 亚洲精品无码高潮喷水在线| 亚洲精品国产电影| 成人亚洲综合天堂| 免费一级肉体全黄毛片| 国产精品无码素人福利免费| 在线免费观看一级片| 精品国产麻豆免费网站| 美女被免费视频网站a国产| 精品免费国产一区二区| 日韩免费观看一级毛片看看| 成人五级毛片免费播放| 在线免费视频一区| 免费人成无码大片在线观看| 亚洲 另类 无码 在线| 亚洲综合激情另类专区| 亚洲精品无码高潮喷水在线| 亚洲国产天堂久久综合网站| 亚洲欧洲日产国产最新| 国产成人亚洲综合一区| 亚洲av日韩av永久在线观看|