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

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

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

    隨筆-28  評(píng)論-15  文章-81  trackbacks-0

    前言
     本文根據(jù)實(shí)例詳細(xì)介紹了如何在tomcat中配置數(shù)據(jù)源。網(wǎng)上此類文章很多,但是基本都是雷同的,而且對(duì)一些特殊問題以及原理并未詳細(xì)闡述,所以想根據(jù)自己的實(shí)際經(jīng)驗(yàn),并結(jié)合例子寫一篇詳細(xì)的文章。
     本文是偶的一些拙見,有不正確的地方請(qǐng)大家多多評(píng)論指正。
    開發(fā)環(huán)境
      本文的環(huán)境:JDK1.4.2,TOMCAT5.0.28,Oracle9i
    JDBC簡介
      提到數(shù)據(jù)源,那就不能不說JDBC。JDBC是Java Database Connectivity的縮寫。在java.sql包中提供了JDBC API,定義了訪問數(shù)據(jù)庫的接口和類。但是JDBC API不能直接訪問數(shù)據(jù)庫,必須依賴于數(shù)據(jù)庫廠商提供的JDBC驅(qū)動(dòng)程序,即JDBC DRIVER。
    Java.sql中常用的接口和類如下:
           Driver接口和DriverManager類
           Connection
           Statement
          PreparedSataement
          ResultSet
    1     Driver接口和DriverManager類
           DriverManager類用來建立和數(shù)據(jù)庫的連接以及管理JDBC驅(qū)動(dòng)程序,常用方法如下:
    方法 描述
    registerDriver(Driver driver) 在DriverManager中注冊(cè)JDBC驅(qū)動(dòng)程序
    getConnection(String url,String user,String pwd) 建立和數(shù)據(jù)庫的連接,返回Connection對(duì)象
    setLoginTimeOut(int seconds) 設(shè)定等待數(shù)據(jù)庫連接的最長時(shí)間
    setLogWriter(PrintWriter out) 設(shè)定輸入數(shù)據(jù)庫日至的PrintWriter對(duì)象
     
    2     Connection
           Connection代表和數(shù)據(jù)庫的連接,其常用方法如下:
    方法 描述
    getMetaData() 返回?cái)?shù)據(jù)庫的MetaData數(shù)據(jù)。MetaData數(shù)據(jù)包含了數(shù)據(jù)庫的相關(guān)信息,例如當(dāng)前數(shù)據(jù)庫連接的用戶名、使用的JDBC驅(qū)動(dòng)程序、數(shù)據(jù)庫允許的最大連接數(shù)、數(shù)據(jù)庫的版本等等。
    createStatement() 創(chuàng)建并返回Statement對(duì)象
    PrepareStatement(String sql) 創(chuàng)建并返回prepareStatement對(duì)象
    3     Statement
           Statement用來執(zhí)行靜態(tài)sql語句。例如,對(duì)于insert、update、delete語句,調(diào)用executeUpdate(String sql)方法,而select語句可以調(diào)用executeQuery(String sql)方法,executeQuery(String sql)方法返回ResultSet對(duì)象。
    4     PrepareStatement
       PrepareStatement用于執(zhí)行動(dòng)態(tài)的sql語句,即允許sql語句中包含參數(shù)。使用方法為:
       String sql = “select col1 from tablename where col2=? And col3=?”;
       PrepareStatement perpStmt = conn.preparestatement(sql);
       perpStmt.setstring(1,col2Value);
          perpStmt.setFloat(2,col3Value);
          ResultSet rs = perpStmt.executeQuery();
    5     ResultSet
     ResultSet用來表示select語句查詢得到的記錄集,一個(gè)StateMent對(duì)象在同一時(shí)刻只能打開一個(gè)ResultSet對(duì)象。通過ResultSet的getXXX()方法來得到字段值。ResultSet提供了getString()、getFloat()、getInt()等方法。可以通過字段的序號(hào)或者字段的名字來制定獲取某個(gè)字段的值。例如:在上例中g(shù)etString(0),getString(col1)都可以獲得字段col1的值。
    事務(wù)處理
     在實(shí)際應(yīng)用中,我們會(huì)遇到同時(shí)提交多個(gè)sql語句,這些sql語句要么全部成功,要么全部失敗,如果其中一條提交失敗,則必須撤銷整個(gè)事務(wù)。為此,Connection類提供了3個(gè)控制事務(wù)的方法:


    方法 描述
    setAutoCommit(boolen autoCommit) 設(shè)置是否自動(dòng)提交事務(wù),默認(rèn)為自動(dòng)提交。
    commit() 提交事務(wù)
    rollback() 撤銷事務(wù)
    參考例子:
    try{


    conn.SetautoCommit(false);


    stmt = conn.createstatement();
    stmt.executeUpdate(“delete form table1 where col1=1”);
    stmt.eecuteUpdate(“delete from table2 where col2=1”);


    conn.comm.it();


    }catch(Exception e){


    e.printStackTrace;


    try{

    conn.rollback();


    } catch(Exception e1){


    e1.printStackTrace;


    }


    }
    通過一個(gè)JSP例子來訪問oracle數(shù)據(jù)庫:
    <%@ page import="java.util.*">


    <%@ page import="java.sql.*">


    <%


    try{


    Connection conn = null;


    Statement stmt = null;


    ResultSet rs = null;


    //加載oracle驅(qū)動(dòng)程序


    Class.forName("oracle.jdbc.driver.OracleDriver.");


    //注冊(cè)oracle驅(qū)動(dòng)程序


    DriverManager.regidterDriver(new
    oracle.jdbc.driver.OracleDriver());


    //建立數(shù)據(jù)庫連接


    conn=DriverManager.getConnection("jdbc:oracle:thin:@your
    db ip:your db port:sid",dbuser,dbpassword);


    stmt = conn.createStatement();


    rs = stmt.executeQuery("select * from
    tablename");


    while(rs.next){

    out.print(rs.getstring("colname"));


    }


    }catch(Exception e){


    }


    finally{


    rs.close();


    stmt.close();


    conn.close();


    }

    %>
     
    數(shù)據(jù)源簡介
     JDBC2.0提供了javax.sql.DataSource的接口,負(fù)責(zé)與數(shù)據(jù)庫建立連接,實(shí)際應(yīng)用時(shí)不需要編寫連接數(shù)據(jù)庫代碼,直接從數(shù)據(jù)源獲得數(shù)據(jù)庫的連接。Dataource中事先建立了多個(gè)數(shù)據(jù)庫連接,這些數(shù)據(jù)庫連接保持在數(shù)據(jù)庫連接池中,當(dāng)程序訪問數(shù)據(jù)庫時(shí),只需要從連接池從取出空閑的連接,訪問數(shù)據(jù)庫結(jié)束,在將這些連接歸還給連接池。DataSource對(duì)象由容器(Tomcat)提供,不能使用創(chuàng)建實(shí)例的方法來生成DataSource對(duì)象,要采用JAVA的JNDI(Java Nameing and Directory Interface,java命名和目錄接口)來獲得DataSource對(duì)象的引用。(另有一種說法:“其實(shí)從技術(shù)上來說,數(shù)據(jù)源連接方式是不需要目錄服務(wù)的,我們同樣可以通過序列化數(shù)據(jù)源對(duì)象直接訪問文件系統(tǒng)。這點(diǎn)是需要明確的。”感興趣的朋友可以試試。)JNDI是一種將對(duì)象和名字綁定的技術(shù),對(duì)象工廠負(fù)責(zé)生產(chǎn)出對(duì)象,這些對(duì)象都和唯一的名字相綁定。程序中可以通過這個(gè)名字來獲得對(duì)象的引用。Tomcat把DataSource作為一種可配置的JNDI資源來處理,生成DataSource對(duì)象的工廠為org.apache.comm.ons.dbcp.BasicDataSourceFactory。
    配置數(shù)據(jù)源
     配置數(shù)據(jù)源其實(shí)相當(dāng)簡單:
     首先在server.xml中加入<Resource>元素,打開server.xml,在<Context>中加入以下代碼(以oracle為例):
    <Resource name="jdbc/ JNDI名字" auth="Container" type="javax.sql.DataSource"/>

    <ResourceParams name="jdbc/JNDI名字">

    <parameter>

    <name>factory</name>
     
    <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>

    </parameter>

    <parameter>

    <name>maxActive</name>

    <value>100</value>

    </parameter>

    <parameter>
     
    <name>maxIdle</name>
     
    <value>30</value>

    </parameter>

    <parameter>

    <name>maxWait</name>
     
    <value>10000</value>

    </parameter>

    <parameter>
     
    <name>username</name>

    <value>用戶名</value>

    </parameter>

    <parameter>

    <name>password</name>

    <value>密碼</value>

    </parameter>

    <parameter>

    <name>driverClassName</name>

    <value>oracle.jdbc.driver.OracleDriver</value>

    </parameter>

    <parameter>

    <name>url</name>
     
    <value>jdbc:oracle:thin:@ip:端口:sid </value>

    </parameter>

    </ResourceParams>
    <Resource>元素的屬性如下:
    屬性 描述
    name 指定Resource的JNDI的名字
    auth 指定管理Resource的Manager,由兩個(gè)可選值:Container和Application。Container表示由容器來創(chuàng)建和管理Resource,Application表示由WEB應(yīng)用來創(chuàng)建和管理Resource。如果在web application deployment descriptor中使用<resource-ref>,這個(gè)屬性是必需的,如果使用<resource-env-ref>,這個(gè)屬性是可選的。
    type 指定Resource所屬的java類名
    <ResourceParams>元素的屬性如下:
    屬性 描述
    name 指定ResourceParams的JNDI的名字,必須和Resource的name保持一致
    factory 指定生成DataSource對(duì)象的factory的類名
    maxActive 指定數(shù)據(jù)庫連接池中處于活動(dòng)狀態(tài)的數(shù)據(jù)庫連接最大數(shù)目,0表示不受限制
    maxIdle 指定數(shù)據(jù)庫連接池中處于空閑狀態(tài)的數(shù)據(jù)庫連接的最大數(shù)目,0表示不受限制
    maxWait 指定數(shù)據(jù)庫連接池中的數(shù)據(jù)庫連接處于空閑狀態(tài)的最長時(shí)間(單位為毫秒),超過這一事件,將會(huì)拋出異常。-1表示可以無限期等待。
    username 指定連接數(shù)據(jù)庫的用戶名
    password 指定連接數(shù)據(jù)庫的密碼
    driverClassName 指定連接數(shù)據(jù)庫的JDBC驅(qū)動(dòng)程序
    url 指定連接數(shù)據(jù)庫的URL
     
    其他文章說以上配置就OK了,對(duì)于web.xml的配置可有可無,其實(shí)不是這樣子的。如果在web應(yīng)用中訪問了由Servlet容器管理的某個(gè)JNDI Resource,則必須在web.xml中聲明對(duì)這個(gè)JNDI Resource的引用。表示資源引用的元素為<resource-ref>,該元素加在<wepapp></ wepapp >中。

    <resource-ref>

    <descryiption>DB Connection</descryiption>

    <res-ref-name>jdbc/JNDI名字 </res-ref-name>

    <res-type>javax.sql.DataSource </res- type>

    <res-auth>Container </res-auth>

    </resource-ref>
    <resource-ref>元素的屬性如下:
    屬性 描述
    description 對(duì)所引用的資源的說明
    res-ref-name 指定所引用資源的JNDI名字,與<Resource>元素中的name屬性保持一致
    res-type 指定所引用資源的類名字,與<Resource>元素中的type屬性保持一致
    res-auth 指定所引用資源的Manager,與<Resource>元素中的auth屬性保持一致
     到這里,數(shù)據(jù)源就已經(jīng)配置成功了。但是我在測試的時(shí)候除了一點(diǎn)小麻煩,主要原因是對(duì)DataSource的概念沒搞清楚。我是這么測試的,寫一個(gè)測試類,然后在eclipse中進(jìn)行junit測試,捕獲的異常為:
     javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial。
     同樣的代碼在JSP文件中正常運(yùn)行,后來翻了一些資料,終于找到了問題的所在了。原來DataSource是由容器(TOMCAT)提供的,所以我的測試會(huì)拋出異常。為了再次驗(yàn)證想法是否正確,在jsp文件中import剛才拋出異常的類,在進(jìn)行連接數(shù)據(jù)庫,結(jié)果一切正常。
     下面的例子是實(shí)際應(yīng)用中使用DataSource,在jsp文件中連接oracle。
    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

    <%@ page import="java.sql.*"%>

    <%@ page import="javax.naming.*"%>

    <%@ page import="javax.sql.*"%>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD
    HTML 4.01 Transitional//EN">

    <html>

    <head>

    </head>

    <body>

    <%
    Context initContext = new InitialContext();

    Context envContext = (Context) initContext.lookup("java:/comp/env");


    DataSource db = (DataSource)envContext.lookup("jdbc/javablogorl");


    //javablogorl為<Resource>元素中name屬性的值

    Connection conn = db.getConnection( );

    Statement stmt = conn.createStatement();


    ResultSet rs = stmt.executeQuery("SELECT * FROM blog_systemadmin");

    while(rs.next()){

    out.print(rs.getString("admin_name")+" ");

    out.print(rs.getString("admin_password")+"<br>");

    }

    rs.close();

    stmt.close();

    conn.close();
    %>

    </body>

    </html>
    另:tomcat5.5的配制方法為:
    <Resource name="jdbc/JNDI名字" auth="Container" type="javax.sql.DataSource"
                   maxActive="100" maxIdle="30" maxWait="10000"
                   username="用戶名" password="密碼" driverClassName="oracle.jdbc.driver.OracleDriver"
                   url="jdbc:oracle:thin:@ip:端口:sid"/>

    posted on 2008-01-09 23:24 譚明 閱讀(464) 評(píng)論(0)  編輯  收藏 所屬分類: Java
    主站蜘蛛池模板: 亚洲自偷自偷在线制服 | 亚洲一线产区二线产区区| 亚洲精品视频免费| 日韩中文字幕精品免费一区| 国产99精品一区二区三区免费| 日韩亚洲国产高清免费视频| 久久久久久a亚洲欧洲AV| 亚洲精品成人久久| 亚洲国产日韩成人综合天堂| 免费能直接在线观看黄的视频| 你是我的城池营垒免费看| 在线亚洲精品视频| 亚洲人成网站在线在线观看| 亚洲熟妇av一区| 亚洲男人都懂得羞羞网站| 亚洲综合伊人久久大杳蕉| 亚洲成a人片在线观看老师| 最近中文字幕免费mv视频7| 噼里啪啦电影在线观看免费高清| 亚洲欧洲AV无码专区| 久久亚洲春色中文字幕久久久| 亚洲无人区一区二区三区| 亚洲日韩在线观看| www.亚洲色图.com| 亚洲高清视频一视频二视频三| 国产精品麻豆免费版| 日本牲交大片免费观看| 午夜免费福利影院| 暖暖免费高清日本中文| 免费毛片在线播放| 成年女人永久免费观看片| 免费看AV毛片一区二区三区| 成人一a毛片免费视频| 国产精品成人免费视频网站京东| 美女视频黄免费亚洲| 韩国免费一级成人毛片| 成视频年人黄网站免费视频| 无人在线观看免费高清视频| 中文字幕av无码无卡免费| 成年男女男精品免费视频网站| 成人免费无码视频在线网站|