迷途書童

          敏感、勤學(xué)、多思
          隨筆 - 77, 文章 - 4, 評(píng)論 - 86, 引用 - 0
          數(shù)據(jù)加載中……

          用 Java 5 RowSet 新特性訪問 IBM DB2 數(shù)據(jù)庫

          2006 年 4 月 10 日

          Java 5 在 Java Database Connectivity (JDBC) 方面加強(qiáng)了支持,其中加入了新的包 javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi。本文將通過實(shí)例來演示這些新的特性。

          RowSet 新特性簡介

          Java 5在Java Database Connectivity (JDBC)方面加強(qiáng)了支持,其中加入了新的包javax.sql.rowset,javax.sql.rowset.serial,javax.sql.rowset.spi。從RowSet接口繼承規(guī)定了五個(gè)新的接口:

          1. CachedRowSet: CachedRowset可以不用與數(shù)據(jù)源建立長期的連接,只有當(dāng)從數(shù)據(jù)庫讀取數(shù)據(jù)或是往數(shù)據(jù)庫寫入數(shù)據(jù)的時(shí)候才會(huì)與數(shù)據(jù)庫建立連接,它提供了一種輕量級(jí)的訪問數(shù)據(jù)庫的方式,其數(shù)據(jù)均存在內(nèi)存中。

          2. JdbcRowSet:對ResultSet的對象進(jìn)行包裝,使得可以將ResultSet對象做為一個(gè)JavaBeans ? 組件。

          3. FilteredRowSet:繼承自CachedRowSet,可以根據(jù)設(shè)置條件得到數(shù)據(jù)的子集。

          4. JoinRowSet:繼承自CachedRowSet,可以將多個(gè)RowSet對象進(jìn)行SQL Join語句的合并。

          5. WebRowSet:繼承自CachedRowSet,可以將WebRowSet對象輸出成XML格式。

          下面分別演示如何使用這五個(gè)新接口。

          實(shí)驗(yàn)環(huán)境

          IBM DB2 Universal 8.1
          數(shù)據(jù)庫名:DemoDB
          數(shù)據(jù)庫用戶名:db2admin
          數(shù)據(jù)庫密碼:password





          回頁首


          CachedRowSet

          CachedRowSet可以通過調(diào)用populate(ResuletSet rs)來生成數(shù)據(jù),一旦獲得數(shù)據(jù),CachedRowSet就可以斷開與數(shù)據(jù)庫的連接,直到往數(shù)據(jù)庫寫入數(shù)據(jù)的時(shí)候才需建立連接。

          可以使用自己擴(kuò)展的或是使用Reference Implement的實(shí)現(xiàn)類進(jìn)行訪問數(shù)據(jù)庫。下面的代碼演示了如何根據(jù)ResultSet建立一個(gè)CachedRowSet對象,在中斷與數(shù)據(jù)庫連接的情況下,讀取數(shù)據(jù),并做更新,最后再獲取數(shù)據(jù)庫連接,將更新落實(shí)到數(shù)據(jù)庫中。


          												
          														public static void testCachedRowSet(){
          	Connection conn = null;
          	try {
          		// 獲得數(shù)據(jù)庫連接
          	    conn= DriverManager.getConnection(DB2URL, DB2USER, DB2PASSWORD);
          	    Statement stmt = conn.createStatement();
          	    // 查詢數(shù)據(jù)庫,獲得表數(shù)據(jù)
          	    ResultSet rs = stmt.executeQuery("select * from student");//$NON-NLS-1$
          	    // 根據(jù)ResultSet對象生成CachedRowSet類型的對象
          	    CachedRowSetImpl crs = new CachedRowSetImpl();
          	    crs.populate(rs);
          	    // 關(guān)閉ResultSet
          		rs.close();
          	    // 關(guān)閉數(shù)據(jù)庫的連接
          	    conn.close();
          	    // 在中斷與數(shù)據(jù)庫連接的情況下,對CachedRowSet進(jìn)行操作
          	    operateOnRowSet(crs);
          	    // 重新獲取與數(shù)據(jù)庫的連接
          	    conn= DriverManager.getConnection(DB2URL, DB2USER, DB2PASSWORD);
          	    // 將CachedRowSet的內(nèi)容更新到數(shù)據(jù)庫
          	    crs.acceptChanges(conn);
          	    // 關(guān)閉CachedRowSet
          	    crs.close();
          	    // 關(guān)閉數(shù)據(jù)庫連接
          	    conn.close();
          	} catch (InstantiationException e) {
          	    System.out.println("Andrew: InstantiationException!");//$NON-NLS-1$
          	} catch (IllegalAccessException e) {
          	    System.out.println("Andrew: IllegalAccessException!");//$NON-NLS-1$
          	} catch (ClassNotFoundException e) {
          	    System.out.println("Andrew: ClassNotFoundException!");//$NON-NLS-1$
          	}catch (SQLException e) {
          	  	System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}	
          }
          
          												
          										

          其中operateOnRowSet方法遍歷讀取RowSet中的元素,并將id值加1。RowSet允許注冊監(jiān)聽器,可以在光標(biāo)移動(dòng),RowSet發(fā)生改變時(shí)觸發(fā)。其具體代碼如下:


          												
          														public static void operateOnRowSet(RowSet rs){
          	// 為RowSet注冊監(jiān)聽器
          	MyRowsetListener myListener = new MyRowsetListener();
              rs.addRowSetListener(myListener);
              // 操作RowSet數(shù)據(jù)
          	try{
          		// 遍歷讀取數(shù)據(jù)
          		while (rs.next()) {
          			String id = rs.getString("ID");//$NON-NLS-1$
          	        String name = rs.getString("NAME");//$NON-NLS-1$
          	        System.out.println("ID="+id+",NAME="+name);//$NON-NLS-1$
          	        //在id最末位連接"1"
          	        rs.updateString(1, id+"1");
          	    }
          	}catch (SQLException e) {
          	    System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          class MyRowsetListener implements RowSetListener{
          	// 光標(biāo)發(fā)生移動(dòng)
          	public void cursorMoved(RowSetEvent event) {
          		System.out.println("cursor moved");
          	}
          	// row發(fā)生改變
          	public void rowChanged(RowSetEvent event) {
          		System.out.println("row changed");
          	}
          	// RowSet發(fā)生改變
          	public void rowSetChanged(RowSetEvent event) {
          		System.out.println("row set changed");
          	}
          }
          public static void main(String[] args) {
          	try {
          		Class.forName(DB2DRIVER).newInstance();
          	} catch (InstantiationException e) {
          		System.out.println("Andrew: InstantiationException!");//$NON-NLS-1$
          	} catch (IllegalAccessException e) {
          		System.out.println("Andrew: IllegalAccessException!");//$NON-NLS-1$
          	} catch (ClassNotFoundException e) {
          		System.out.println("Andrew: ClassNotFoundException!");//$NON-NLS-1$
          	}
          	testCachedRowSet();
          }
          
          												
          										

          上面的程序的運(yùn)行結(jié)果如下:


          												
          														cursor moved
          ID=001,NAME=zhou
          cursor moved
          ID=002,NAME=zhang
          cursor moved
          cursor moved
          cursor moved
          cursor moved
          cursor moved
          cursor moved
          row set changed
          
          												
          										

          并且數(shù)據(jù)庫中的id更新為0011,0021。





          回頁首


          JdbcRowSet

          JdbcRowSet功能與ResultSet類似,與CachedRowSet不同,JdbcRowSet在操作時(shí)保持與數(shù)據(jù)庫的連接。可以將與數(shù)據(jù)庫連接的URL,用戶名,密碼以及執(zhí)行的SQL語句通過setXXX形式綁定。另外,JdbcRowSet返回的結(jié)果默認(rèn)是可以上下滾動(dòng)和可更新的,當(dāng)然這需要數(shù)據(jù)庫廠商提供的JDBC Driver支持。下面的代碼演示了如何通過set方法設(shè)定數(shù)據(jù)庫連接參數(shù),以及如何操作JdbcRowSet對象。


          												
          														public static void testJdbcRowSet() {
          	JdbcRowSetImpl jrs = new JdbcRowSetImpl();
          	try {
          		// 設(shè)置連接數(shù)據(jù)庫的URL
          		jrs.setUrl(DB2URL);
          		// 設(shè)置連接數(shù)據(jù)庫的用戶名
          		jrs.setUsername(DB2USER);
          		// 設(shè)置連接數(shù)據(jù)庫的密碼
          		jrs.setPassword(DB2PASSWORD);
          		// 設(shè)置執(zhí)行數(shù)據(jù)庫的SQL語句
          		jrs.setCommand("select * from student");
          		// 執(zhí)行操作
          		jrs.execute();
          		// 對獲得的JdbcRowSet進(jìn)行操作
          		operateOnRowSet(jrs);
          		// 關(guān)閉JdbcRowset
          		jrs.close();
          	} catch (SQLException e) {
          		System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          
          public static void operateOnRowSet(RowSet rs) {
          	// 為RowSet注冊監(jiān)聽器
          	MyRowsetListener myListener = new MyRowsetListener();
          	rs.addRowSetListener(myListener);
          	// 操作RowSet數(shù)據(jù)
          	try {
          		// 遍歷讀取數(shù)據(jù)
          		while (rs.next()) {
          			String id = rs.getString("ID");//$NON-NLS-1$
          			String name = rs.getString("NAME");//$NON-NLS-1$
          			System.out.println("ID=" + id + ",NAME=" + name);//$NON-NLS-1$
          		}
          	} catch (SQLException e) {
          		System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          	
          												
          										

          其運(yùn)行結(jié)果如下:


          												
          														cursor moved
          ID=0011,NAME=zhou
          cursor moved
          ID=0021,NAME=zhang
          cursor moved
          
          												
          										





          回頁首


          FilteredRowSet

          FilteredRowSet接口中規(guī)定了可以設(shè)定過濾器,其過濾接口為Predicate接口,必須實(shí)現(xiàn)Predicate接口中的evaluate方法。具體的代碼如下:


          												
          														public static void testFilteredRowSet() {
          	try {
          		// 獲得數(shù)據(jù)庫連接
          		Connection conn = DriverManager.getConnection(DB2URL, DB2USER,
          			DB2PASSWORD);
          		Statement stmt = conn.createStatement();
          		// 查詢數(shù)據(jù)庫,獲得表數(shù)據(jù)
          		ResultSet rs = stmt.executeQuery("select * from student");//$NON-NLS-1$
          		FilteredRowSet frs = new FilteredRowSetImpl();
          		frs.populate(rs);
          		// 設(shè)置過濾器
          		MyDBFilter filter = new MyDBFilter(11, 100);
          		frs.setFilter(filter);
          		operateOnRowSet(frs);
          		// 關(guān)閉FilteredRowSet
          		frs.close();
          		// 關(guān)閉與數(shù)據(jù)庫的連接
          		conn.close();
          	} catch (SQLException e) {
          		System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          
          public static void operateOnRowSet(RowSet rs) {
          	// 為RowSet注冊監(jiān)聽器
          	System.out.println("operateOnRowSet!");//$NON-NLS-1$
          	MyRowsetListener myListener = new MyRowsetListener();
          	rs.addRowSetListener(myListener);
          	// 操作RowSet數(shù)據(jù)
          	try {
          		// 遍歷讀取數(shù)據(jù)
          		while (rs.next()) {
          			String id = rs.getString("ID");//$NON-NLS-1$
          			String name = rs.getString("NAME");//$NON-NLS-1$
          			System.out.println("ID=" + id + ",NAME=" + name);//$NON-NLS-1$
          		}
          	} catch (SQLException e) {
          		System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          
          public static void main(String[] args) {
          	try {
          		Class.forName(DB2DRIVER).newInstance();
          	} catch (InstantiationException e) {
          		System.out.println("Andrew: InstantiationException!");//$NON-NLS-1$
          	} catch (IllegalAccessException e) {
          		System.out.println("Andrew: IllegalAccessException!");//$NON-NLS-1$
          	} catch (ClassNotFoundException e) {
          		System.out.println("Andrew: ClassNotFoundException!");//$NON-NLS-1$
          	}
          	testFilteredRowSet();
          }
          
          												
          										

          其中MyDBFilter實(shí)現(xiàn)了Predicate接口,其實(shí)現(xiàn)代碼如下:


          												
          														class MyDBFilter implements Predicate {
          	private int low;
          	private int high;
          	public MyDBFilter(int low, int high) {
          		this.low = low;
          		this.high = high;
          	}
          	public boolean evaluate(RowSet rs) {
          		CachedRowSet crs=(CachedRowSet)rs;
          		//如果id在low和high之間返回真
          		try {
          			String id = (String) crs.getString("id");
          			int idValue = Integer.parseInt(id);
          			if (low < idValue && idValue < high) {
          				return true;
          			}
          		} catch (SQLException e) {
          			
          		}
          		return false;
          	}
          	public boolean evaluate(Object arg0, int arg1) throws SQLException {
          		return false;
          	}
          
          	public boolean evaluate(Object arg0, String arg1) throws SQLException {
          		return false;
          	}
          }
          
          												
          										

          其運(yùn)行結(jié)果如下:


          												
          														cursor moved
          ID=0021,NAME=zhang
          cursor moved
          
          												
          										





          回頁首


          JoinRowSet

          JoinRowSet可以將多個(gè)RowSet對象進(jìn)行join合并,Join的列可以通過每個(gè)RowSet通過調(diào)用setMatchColumn方法來設(shè)置。setMatchColumn方式是Joinable接口定義的方法,五種類型的RowSet規(guī)定都需要實(shí)現(xiàn)該接口。下面的代碼演示將student表和intern表中id相同的數(shù)據(jù)進(jìn)行join操作。JoinRowSet不需要保持與數(shù)據(jù)庫的連接。


          												
          														public static void testJoinRowSet(){
          	Connection conn = null;
          	try {
          		JoinRowSet jrs = new JoinRowSetImpl();
          		// 獲得數(shù)據(jù)庫連接
          		conn = DriverManager.getConnection(DB2URL, DB2USER, DB2PASSWORD);
          		Statement stmt = conn.createStatement();
          		// 查詢數(shù)據(jù)庫,獲得表數(shù)據(jù)
          		ResultSet rs1 = stmt.executeQuery("select id,name from student");//$NON-NLS-1$
          		// 根據(jù)ResultSet對象生成CachedRowSet類型的對象
          		CachedRowSetImpl crs1 = new CachedRowSetImpl();
          		crs1.populate(rs1);
          		crs1.setMatchColumn(1);
          		// 關(guān)閉ResultSet
          		jrs.addRowSet(crs1);
          		rs1.close();
          		
          		// 查詢數(shù)據(jù)庫,獲得表數(shù)據(jù)
          		ResultSet rs2 = stmt.executeQuery("select id,company from intern");//$NON-NLS-1$
          		// 根據(jù)ResultSet對象生成CachedRowSet類型的對象
          		CachedRowSetImpl crs2 = new CachedRowSetImpl();
          		crs2.populate(rs2);
          		crs2.setMatchColumn(1);
          		// 關(guān)閉ResultSet
          		rs2.close();
          		// 將Result2放入JoinRowSet中進(jìn)行Join操作
          		jrs.addRowSet(crs2);
          		// 關(guān)閉數(shù)據(jù)庫連接
          		conn.close();
          		
          		while (jrs.next()) {
          			String id = jrs.getString(1);
          			String name = jrs.getString(2);
          			String company = jrs.getString(3);
          			//$NON-NLS-1$
          			System.out.println("ID=" + id + ",NAME=" + name+",COMPNAY="+company);
          		}
          	} catch (SQLException e) {
          		System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          
          												
          										

          其輸出結(jié)果為


          												
          														ID=001111,NAME=zhou,COMPNAY=companyA
          
          												
          										





          回頁首


          WebRowSet

          WebRowSet繼承自CachedRowSet,支持XML格式的查詢,更新等操作,下面的代碼將WebRowSet對象輸出成XML格式到文件。


          												
          														public static void testWebRowSet(){
          	try {
          		// 獲得數(shù)據(jù)庫連接
          		Connection conn = DriverManager.getConnection(DB2URL, DB2USER,
          				DB2PASSWORD);
          		Statement stmt = conn.createStatement();
          		// 查詢數(shù)據(jù)庫,獲得表數(shù)據(jù)
          		ResultSet rs = stmt.executeQuery("select * from student");//$NON-NLS-1$
          		WebRowSetImpl wrs = new WebRowSetImpl();
          		wrs.populate(rs);
          		FileOutputStream out = new FileOutputStream("data.xml");
          		wrs.writeXml(out);
          		wrs.close();
          		// 關(guān)閉與數(shù)據(jù)庫的連接
          		conn.close();
          	} catch (SQLException e) {
          		System.out.println("Andrew: SQLException!");//$NON-NLS-1$
          		e.printStackTrace();
          	} catch(IOException e){
          		System.out.println("Andrew: IOException!");//$NON-NLS-1$
          		e.printStackTrace();
          	}
          }
          
          												
          										

          其運(yùn)行結(jié)果data.xml大致如下:


          												
          														<?xml version="1.0"?>
          XML文件屬性格式 
          ……
          <metadata>
              <column-count>2</column-count>
              <column-definition>
                <column-index>1</column-index>
                <auto-increment>false</auto-increment>
                <case-sensitive>true</case-sensitive>
                <currency>false</currency>
                <nullable>0</nullable>
                <signed>false</signed>
                <searchable>true</searchable>
                <column-display-size>10</column-display-size>
                <column-label>ID</column-label>
                <column-name>ID</column-name>
                <schema-name>ZHOUDP  </schema-name>
                <column-precision>10</column-precision>
                <column-scale>0</column-scale>
                <table-name>STUDENT</table-name>
                <catalog-name>TEST</catalog-name>
                <column-type>12</column-type>
                <column-type-name>VARCHAR</column-type-name>
              </column-definition>
              <column-definition>
                <column-index>2</column-index>
                <auto-increment>false</auto-increment>
                <case-sensitive>true</case-sensitive>
                <currency>false</currency>
                <nullable>1</nullable>
                <signed>false</signed>
                <searchable>true</searchable>
                <column-display-size>50</column-display-size>
                <column-label>NAME</column-label>
                <column-name>NAME</column-name>
                <schema-name>ZHOUDP  </schema-name>
                <column-precision>50</column-precision>
                <column-scale>0</column-scale>
                <table-name>STUDENT</table-name>
                <catalog-name>TEST</catalog-name>
                <column-type>12</column-type>
                <column-type-name>VARCHAR</column-type-name>
              </column-definition>
            </metadata>
            <data>
              <currentRow>
                <columnValue>0011</columnValue>
                <columnValue>zhou</columnValue>
              </currentRow>
              <currentRow>
                <columnValue>0021</columnValue>
                <columnValue>zhang</columnValue>
              </currentRow>
            </data>
          </webRowSet>
          
          												
          										

          posted on 2006-06-10 19:43 迷途書童 閱讀(1135) 評(píng)論(0)  編輯  收藏 所屬分類: java應(yīng)用

          主站蜘蛛池模板: 衡阳市| 汝南县| 通渭县| 来宾市| 华蓥市| 融水| 惠来县| 新闻| 白山市| 家居| 永清县| 武乡县| 山西省| 赣榆县| 稷山县| 康保县| 二连浩特市| 阜城县| 中卫市| 资中县| 随州市| 五原县| 洪雅县| 鄄城县| 怀仁县| 美姑县| 松阳县| 普定县| 蛟河市| 湘乡市| 宕昌县| 新田县| 青海省| 天长市| 长沙县| 施秉县| 聂荣县| 皮山县| 报价| 历史| 琼结县|