JNDI簡介,jndi在tomcat中的配置,jdbc api簡介,java連接數據庫服務

發表于:2007-07-01來源:作者:點擊數: 標簽:
JNDI( Java 命名和目錄接口) JNDI(Java命名和目錄接口) 分布式計算環境通常使用命名和目錄服務來獲取共享的組件和資源。命名和目錄服務將名稱與位置、服務、信息和資源關聯起來。 命名服務提供名稱對象的映射。目錄服務提供有關對象的信息,并提供定位這



JNDI(Java 命名和目錄接口)



 



JNDI(Java 命名和目錄接口) 分布式計算環境通常使用命名和目錄服務來獲取共享的組件和資源。命名和目錄服務將名稱與位置、服務、信息和資源關聯起來。  命名服務提供名稱—對象的映射。目錄服務提供有關對象的信息,并提供定位這些對象所需的搜索工具。有許多命名和目錄服務實現,并且到它們的接口是不同的。 Java 命名和目錄接口或 JNDI 提供了一個用于訪問不同的命名和目錄服務的公共接口。請參閱 URL java.sun.com/products/jndi/serviceproviders.html 以獲取支持通過 JNDI 接口訪問命名和目錄服務的供應商列表。  JNDI(Java Naming and Directory Interface) 當你在開發企業beans時,JNDI很重要,因為對一個EJB的訪問是通過JNDI的命名服務完成的。運用一個命名服務來查找與一個特定名字相關的一個對象。在EJB context中,一個命名服務找到一個企業bean,給定這個bean的名字。因此,了解JNDI在開發一個EJB應用程序中是至關重要的。另外,JDBC可以用JNDI來訪問一個關系數據庫。 附:The JNDI Tutorial http://java.sun.com/products/jndi/tutorial/index.html (下載) http://java.sun.com/products/jndi/docs.html#TUTORIAL



 



 



JDBC2.0擴展API



 



 



   JDBC 2.0 API被劃分為兩部分:JDBC 2.0核心API和JDBC 2.0標準擴展API。核心API在java.sql里面。這是原來的版本就實現了的基本的功能。標準擴展API在javax.sql里面。由JDBC2.0規范新規定的一些接口在這里面。當然,JDBC2.0也對原來版本的java.sql核心做了一些改動。不過不是很大。原來JDBC1.0的程序可以不加修改的在JDBC2.0上運行。這是Java的一貫的良好的作風。最新的JDBC包可以從sun公司的網站上下載。    JDBC2.0的擴展API增加了一些數據訪問和數據源訪問的重大的功能。這中間有一些是主要用來做企業計算的。用JDBC2.0的新的擴展包,JDBC提供了一個從JAVA2平臺的通用的數據訪問的方法。   首先,我們來看看JDBC標準擴展的API怎樣來和JDBC2.0結合在一起的。JDBC2.0包括兩個包:   1、 java.sql包,個包里面是JDBC2.0的核心API。它包括了原來的JDBC API(JDBC 1.0版本),再加上一些新的2.0版本的API。這個包在Java 2 Platform SDK里面有。   2、 javax.sql包,這里面是JDBC2.0的標準擴展API。這個包是一個全新的,在Java 2 Platform SDK, Enterprise Edition里面單獨提供。   JDBC2.0的核心API包括了JDBC1.0的API,并在此基礎上增加了一些功能,對某些性能做了增強。使java語言在數據庫計算的前端提供了統一的數據訪問方法,效率也得到了提高。   JDBC是向后兼容的,JDBC1.0的程序可以不加修改的運行在JDBC2.0上。但是,假如程序中用到了JDBC2.0的新特性,就必須要運行在JDBC2.0版本上。   概括的來說,JDBC核心API的新特性在兩個方面做了工作。一個是支持一些新的功能,另一個就是支持SQL3的數據類型。   1、 在支持新功能方面:包括結果集可以向后滾動,批量的更新數據。另外,還提供了UNICODE字符集的字符流操作。   2、 在支持SQL3的數據類型方面:包括新的SQL3數據類型,增加了對持久性對象的存貯。   為了對數據的存取,操作更加方便,JDBC的新特性是應用程序的設計更容易了。例如:數據塊的操作能夠顯著的提高數據庫訪問的性能。新增加的BLOB, CLOB,和數組接口能夠是應用程序操作大塊的數據類型,而不必客戶端在存貯之前進行其它的處理。這樣,就顯著的提高了內存的使用效率。    下面我們來介紹JDBC2.0的標準擴展API。標準擴展API分為如下幾個方面:   1、 DataSource接口:和Java名字目錄服務(JNDI)一起工作的數據源接口。它提供了對數 吹囊恢指?玫牧?臃椒ā?br>  2、 Connection pooling(連接池):可以重復使用連接,而不是對每個請求都使用一個新的連接。   3、 Distrubute transaction(分布式的事務):在一個事務中涉及到了多個數據庫服務器。   4、 Rowsets:JavaBean組件包含了結果集,主要用來將數據傳給瘦客戶,或者提供一個可以滾動的結果集。   下面我們一個一個來介紹:   一、DataSource接口是一個更好的連接數據源的方法:   JDBC1.0是原來是用DriverManager類來產生一個對數據源的連接。JDBC2.0用一種替代的方法,使用DataSource的實現,代碼變的更小巧精致,也更容易控制。   一個DataSource對象代表了一個真正的數據源。根據DataSource的實現方法,數據源既可以是從關系數據庫,也電子表格,還可以是一個表格形式的文件。當一個DataSource對象注冊到名字服務中,應用程序就可以通過名字服務獲得DataSource對象,并用它來產生一個與DataSource代表的數據源之間的連接。   關于數據源的信息和如何來定位數據源,例如數據庫服務器的名字,在哪臺機器上,端口號等等,都包含在DataSource對象的屬性里面去了。這樣,對應用程序的設計來說是更方便了,因為并不需要硬性的把驅動的名字寫死到程序里面去。通常驅動名字中都包含了驅動提供商的名字,而在DriverManager類中通常是這么做的。如果數據源要移植到另一個數據庫驅動中,代碼也很容易做修改。所需要做的修改只是更改DataSource的相關的屬性。而使用DataSource對象的代碼不需要做任何改動。   由系統管理員或者有相應權限的人來配置DataSource對象。配置DataSource,包括設定DataSource的屬性,然后將它注冊到JNDI名字服務中去。在注冊DataSource對象的的過程中,系統管理員需要把DataSource對象和一個邏輯名字關聯起來。名字可以是任意的,通常取成能代表數據源并且容易記住的名字。在下面的例子中,名字起為:InventoryDB,按照慣例,邏輯名字通常都在jdbc的子上下文中。這樣,邏輯名字的全名就是:jdbc/ InventoryDB。   一旦配置好了數據源對象,應用程序設計者就可以用它來產生一個與數據源的連接。下面的代碼片段示例了如何用JNDI上下文獲得一個一個數據源對象,然后如何用數據源對象產生一個與數據源的連接。開始的兩行用的是JNDI API,第三行用的才是JDBC的API:    Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/InventoryDB");Connection con = ds.getConnection("myPassword", "myUserName");   在一個基本的DataSource實現中,DataSource.getConnection方法返回的Connection對象和用DriverManager.getConnection方法返回的Connection對象是一樣的。因為DataSource提供的方便性,我們推薦使用DataSource對象來得到一個Connection對象。我們希望所以的基于JDBC2.0技術的數據庫驅動都包含一個基本的DataSource的實現,這樣就可以在應用程序中很容易的使用它。   對于普通的應用程序設計者,是否使用DataSource對象只是一個選擇問題。但是,對于那些需要用的連接池或者分布式的事務的應用程序設計者來說,就必須使用DataSource對象來獲得Connection,原因在下面我們會提到。    二、Connection pooling(連接池):   連接池是這么一種機制,當應用程序關閉一個Connection的時候,這個連接被回收,而不是被destroy,因為建立一個連接是一個很費資源的操作。如果能把回收的連接重新利用,會減少新創建連接的數目,顯著的提高運行的性能。   假設應用程序需要建立到一個名字為EmpolyeeDB的DataSource的連接。使用連接池得到連接的代碼如下:    Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/EmployeeDB");Connection con = ds.getConnection("myPassword", "myUserName");除了邏輯名字以外,我們發現其代碼和上面舉的例子的代碼是一樣的。邏輯名字不同,就可以連接到不同的數據庫。DataSource對象的getConnection方法返回的Connection是否是一個連接池中的連接完全取決于DataSource對象的實現方法。如果DataSource對象實現與一個支持連接池的中間層的服務器一起工作,DataSource對象就會自動的返回連接池中的連接,這個連接也是可以重復利用的。   是否使用連接池獲得一個連接,在應用程序的代碼上是看不出不同的。在使用這個Connection連接上也沒有什么不一樣的地方,唯一的不同是在java的finally語句塊中來關閉一個連接。在finally中關閉連接是一個好的編程習慣。這樣,即使方法拋出異常,Connection也會被關閉并回收到連接池中去。代碼應該如下所示:   try{…   }catch(){…   }finally{ if(con!=null)con.close();}   三、分布式事務:   獲得一個用來支持分布式事務的連接與獲得連接池中的連接是很相似的。同樣,不同之處在于DataSource的實現上的不同,而不是在應用程序中獲得連接的方式上有什么不同。假設DataSource的實現可以與支持分布式事務中間層服務器一起工作,得到連接的代碼還是如下所示:    Context ctx = new InitialContext(); DataSource ds = (DataSource)ctx.lookup("jdbc/EmployeeDB"); Connection con = ds.getConnection("myPassword", "myUserName");由于性能上的原因,如果一個DataSource能夠支持分布式的事務,它同樣也可以支持連接池管理。   從應用程序設計者的觀點來看。是否支持分布式的事務的連接對它來說沒什么不同,唯一的不同是在事務的邊界上(開始一個事務的地方和結束一個事務的地方),開始一個事務或者結束一個事務都是由事務服務器來控制的。應用程序不應該做任何可能妨礙服務的事情。應用程序不能夠直接調用事務提交commit或者回滾rollback操作,也不能夠使用事務的自動提交模式auto-commit mode(在數據庫操作完成的時候自動的調用commit或者rollback)。    在一個連接參與了分布式事務的時候,下面的代碼是你不能做的(con表示支持分布式事務的連接Connection)。   con.commit();或者con.rollback();或者con.setAutoCommit(true);對于通常的Connection來說,缺省的是auto-commit模式。而對于支持分布式事務的Connection來說,缺省不是auto-commit模式。注意,即使Connection是支持事務的,它也可以用于沒有事務的情況。關于事務邊界的限制只是是對分布式事務的情況下才成立的。   配置支持連接池的DataSource的時候,涉及到配置ConnectionPoolDataSource對象,這個對象是三層體系結構中的中間層來管理連接池的。同樣的,在配置支持分布式事務的時候,需要配置XADataSource,XADataSource是中間層用來管理分布式事物的對象。ConnectionPoolDataSource和XADataSource是由驅動提供商提供的,對應用程序的設計者來說是透明的。和基本的DataSource一樣,系統管理員來配置ConnectionPoolDataSource和XADataSource對象。   四、結果集:   結果集對象是一行行數據的容器。根據其目的,可以通過多種方法實現。RowSet及其相關的接口與JDBC2.0的標準擴展API有點不同,他們并不是驅動的一部分,RowSet是在驅動的上層實現的,可以由其它的任何人來實現他們。   任何類型的rowset都實現了RowSet接口,RowSet接口擴展了ResultSet接口。這樣RowSet對象就有了ResultSet對象所有的功能。能夠通過getXXX方法得到數據庫中的某列值,通過updateXXX方法可以修改某列值,可以移動光標,是當前行變為另一行。   當然,我們更感興趣的是RowSet接口提供的新的功能。作為一個JavaBean組件,RowSet對象可以增加或者刪除一個listener(監聽者),可以get或者set其屬性值,這些屬性中,有一個是字符串,表示一個對數據庫Query請求,RowSet接口定義了設定參數的方法,也提供了執行這個請求的方法。這意味著RowSet對象能夠執行查詢請求,可以根據它產生的結果集進行計算。同樣,RowSet也可以根據任何表格數據源進行計算,所以,它不局限于關系數據庫。   從數據源得到數據之后,RowSet對象可以和數據源斷開連接,rowset也可以被序列化。這樣,RowSet就可以通過網絡傳遞給瘦客戶端。   RowSet可以被重新連接到數據源,這樣,做的修改就可以存回到數據源中去。如果產生了一個listener,當RowSet的當前行移動,或者數據被修改的時候,監聽者就會收到通知。例如,圖形用戶界面組件可以注冊成為監聽者,當RowSet更改的時候,圖形用戶界面接到通知,就可以修改界面,來符合它所表示的RowSet。   根據不同的需要,RowSet接口可以通過多種方法來實現。Java software已經寫了一個CachedRowSet實現,從http://developer.java.sun.com/developer/earlyAccess/crs/index.html中可以得到這個實現。   與CachedRowSet類不樣的是,JDBCRowSet類總是保持一個和數據源的連接。這樣,在ResultSet外圍簡單到加了一層,是基于JDBC技術的驅動看起來象是一個簡單的JavaBean組件一樣。   總結:JDBC2.0標準擴展API通過見DataSource注冊到JNDI名字服務上,將JDBC技術擴展為一個全新的概念。使應用程序的代碼更加精巧,易于控制。新的API支持了連接池,支持分布式的事務。最后,還使java應用程序可以在網絡上傳播結果集,是不可以滾動的ResultSet變成了可以滾動的RowSet。



 



 



Tomcat中配置和使用JNDI



JNDI是J2EE中一個很重要的標準,通常我們是在EJB編程中用到,  Tomcat4.0中提供了在JSP和Servelt中直接使用JNDI的方法,下面談一下在Tomcat4.0中配置和使用JNDI的方法  (以通過JNDI連接數據庫為例)  假設使用的數據庫是mysql,實驗例子在TOMCAT_HOME/webapps/DBTest目錄中  A.將mysql的JDBC連接庫mm.mysql-2.0.9-bin.jar放入TOMCAT_HOME/common/lib中  B.配置TOMCAT_HOME/conf/serer.xml文件在<Service>段中加入一個Context:  <Context path="/DBTest" docBase="DBTest"  debug="5" reloadable="true" crossContext="true">  </Context>  這是DBTest的根路徑,這是為了在DBTest中使用做準備.  C.在上面加入的<Context>段加入  <Resource name="jdbc/TestDB"  auth="Container"  type="javax.sql.DataSource"/>  <ResourceParams name="jdbc/TestDB">  <parameter>  <name>factory</name>  <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>  </parameter>  <!-- Maximum number of dB connections in pool. Make sure you  configure your mysqld max_connections large enough to handle  all of your db connections. Set to 0 for no limit.  -->  <parameter>  <name>maxActive</name>  <value>100</value>  </parameter>  <!-- Maximum number of idle dB connections to retain in pool.  Set to 0 for no limit.  -->  <parameter>  <name>maxIdle</name>  <value>30</value>  </parameter>  <!-- Maximum time to wait for a dB connection to become available  in ms, in this example 10 seconds. An Exception is thrown if  this timeout is exceeded. Set to -1 to wait indefinitely.  -->  <parameter>  <name>maxWait</name>  <value>10000</value>  </parameter>  <!-- MySQL dB username and password for dB connections -->  <parameter>  <name>username</name>  <value>test</value>  </parameter>  <parameter>  <name>password</name>  <value>test</value>  </parameter>  <!-- Class name for mm.mysql JDBC driver -->  <parameter>  <name>driverClassName</name>  <value>org.gjt.mm.mysql.Driver</value>  </parameter>  <!-- The JDBC connection url for connecting to your MySQL dB.-->  <parameter>  <name>url</name>  <value>jdbc:mysql://localhost:3306/test</value>  </parameter>  </ResourceParams>  這里每一個小段都有英文注解,是Tomcat提供的,我們可以將按照Sample加入,主要修改的是driverClassName,  url,和用戶帳號;需要強調的是"jdbc/TestDB"就是JDNI要查找的Name.  D. 在JSPh或servlet中使用JNDI查找服務  下面是在JSP文件中關于JNDI使用的代碼(文件名記為UserHandleDB.jsp)  需要注意的是JNDI NAME要在前面加上"java:comp/env/"  <%@ page language="java"%>  <%@ page import="java.util.*" %>  <%@ page import="java.sql.*" %>  <%@ page import="javax.sql.*" %>  <%@ page import="javax.naming.*" %>  <%  String jndi_name="java:comp/env/jdbc/TestDB";  String select_user_sql="select userid,name,birthday, email from emp";  String colnames[][]={{"User ID","Name","Birth day","EMail"},  {"userid","name","birthday","email"}};  Vector userSet=new Vector();  Vector columnSet=new Vector();  for(int i=0;i<colnames[0].length;i++){  columnSet.add(colnames[0][i]);  }  userSet.add(columnSet);  Context ctx = new InitialContext();  if(ctx == null )  throw new Exception("No Context");  DataSource ds = (DataSource)ctx.lookup(jndi_name);  Connection conn = ds.getConnection();  try {  PreparedStatement psPreparedStatement=conn.prepareStatement(select_user_sql);  ResultSet resultSet = psPreparedStatement.executeQuery();  while(resultSet.next()){  columnSet=new Vector();  for(int i=0;i<colnames[1].length;i++){  columnSet.add(resultSet.getString(colnames[1][i]));  }  userSet.add(columnSet);  }  }catch(SQLException e) {  e.printStackTrace();  }finally {  conn.close();  %>  E. 引用UserHandleDB.jsp(記為ViewTable.jsp)  <html>  <head>  <title>Test Database </title>  <body >  <%@ include file="UserHandleDB.jsp" %>  <table border="1" >  <%  for(int i=0;i<userSet.size();i++){  Vector colSet=(Vector)userSet.get(i);  out.print("<tr>");  for(int j=0;j<colSet.size();j++){  String col=(String)colSet.get(j);  out.print("<td>"+col+"</td>");  }  out.print("</tr>");  }  %>  </table>  </body>  </html>  F. 在web.xml中加入  <resource-ref>  <description>DB Connection</description>  <res-ref-name>jdbc/TestDB</res-ref-name>  <res-type>javax.sql.DataSource</res-type>  <res-auth>Container</res-auth>  </resource-ref>  這里的jdbc/TestDb要和C中Resource段的name匹配  G. 觀察結果  首先確定數據庫已經啟動,接著啟動Tomcat,如果Tomcat啟動異常,可能的原因是數據庫的JDBC庫沒有加載  最后打開瀏覽器,訪問 http://localhost:8080/DBTest/ViewTable.jsp就可以看到結果

原文轉自:http://www.anti-gravitydesign.com

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97