<struts-config>
??? <form-beans>
??????? <form-bean name="loginForm" type="com.allanlxf.action.LoginForm"/>
??????? <form-bean name="userForm" type="org.apache.struts.action.DynaActionForm">
??????????? <form-property name="userName" type="java.lang.String" />
??????????? <form-property name="password" type="java.lang.String" />
??????? </form-bean>
??? </form-beans>
???
??? <action-mappings>
???
??????? <action?? path="/core/login"? type="com.allanlxf.action.LoginAction"
?????????????????? name="loginForm" input="/core/login.jsp" validate="true" scope="request">
????????? <exception key="errors.root"
?????????????????????? path="/core/error.jsp"
?????????????????????? type="com.allanlxf.biz.IllegalUserException" />
????????? <forward name="success" path="/core/success.jsp" redirect="true"/>
????????? <forward name="fail" path="/core/fail.jsp" />
??????? </action>
???????
??????? <action?? path="/dispatch"? type="com.allanlxf.struts.actions.UserAction" parameter="method">
????????? <forward name="login" path="/actions/pages/login_next.jsp" />
????????? <forward name="find" path="/actions/pages/find_next.jsp" />
????????? <forward name="findById" path="/actions/pages/findById_next.jsp" />
????????? <forward name="remove" path="/actions/pages/remove_next.jsp" />
????????? <forward name="modify" path="/actions/pages/modify_next.jsp" />
????????? <forward name="register" path="/actions/pages/register_next.jsp" />
??????? </action>
???????
??????? <action?? path="/mapping/login"? type="com.allanlxf.struts.actions.UserMappingAction" parameter="login">
????????? <forward name="next" path="/actions/pages/login_next.jsp" />
??????? </action>
???????
??????? <action?? path="/mapping/find"? type="com.allanlxf.struts.actions.UserMappingAction"? parameter="find">
????????? <forward name="next" path="/actions/pages/find_next.jsp" />
??????? </action>
???????
??????? <action?? path="/mapping/findById"? type="com.allanlxf.struts.actions.UserMappingAction"? parameter="findById">
????????? <forward name="next" path="/actions/pages/findById_next.jsp" />
??????? </action>
???????
??????? <action?? path="/mapping/remove"? type="com.allanlxf.struts.actions.UserMappingAction"? parameter="remove">
????????? <forward name="next" path="/actions/pages/remove_next.jsp" />
??????? </action>
???????
??????? <action?? path="/mapping/modify"? type="com.allanlxf.struts.actions.UserMappingAction"? parameter="modify">
????????? <forward name="next" path="/actions/pages/modify_next.jsp" />
??????? </action>
???????
??????? <action?? path="/mapping/register"? type="com.allanlxf.struts.actions.UserMappingAction"? parameter="register">
????????? <forward name="next" path="/actions/pages/register_next.jsp" />
??????? </action>
???????
??????? <action?? path="/lookup"? type="com.allanlxf.struts.actions.UserLookupAction" parameter="method">
????????? <forward name="login" path="/actions/pages/login_next.jsp" />
????????? <forward name="find" path="/actions/pages/find_next.jsp" />
????????? <forward name="findById" path="/actions/pages/findById_next.jsp" />
????????? <forward name="remove" path="/actions/pages/remove_next.jsp" />
????????? <forward name="modify" path="/actions/pages/modify_next.jsp" />
????????? <forward name="register" path="/actions/pages/register_next.jsp" />
??????? </action>
???????
??????? <action?? path="/dyna/register"? type="com.allanlxf.action.RegisterAction"
?????????????????? name="userForm">
????????? <forward name="success" path="/dyna/success.jsp"/>
??????? </action>
???????
??? </action-mappings>
???
??? <message-resources parameter="com.allanlxf.MessageResources" />
?????????????????
</struts-config>
posted @
2007-04-25 16:12 sunny 閱讀(654) |
評論 (0) |
編輯 收藏
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public abstract class HttpFilter implements Filter
{
??? private FilterConfig config;
???
??? //////////////////////////////////
??? public void init(FilterConfig config) throws ServletException
??? {
??????? this.config = config;
??????? init();
??? }
???
??? public void init() throws ServletException
??? {
??? }
??? ///////////////////////////////
??? public FilterConfig getFilterConfig()
??? {
??????? return config;
??? }
???
??? public String getInitParameter(String name)
??? {
??????? return config.getInitParameter(name);
??? }
???
??? public ServletContext getServletContext()
??? {
??????? return config.getServletContext();
??? }
???
??? public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
??????????????????????????????????????????????? throws IOException, ServletException
??? {
??????? doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);
??? }
???
??? public abstract void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
??????????????????????????????????????????????? throws IOException, ServletException;
???
??? public void destroy()
??? {
??? }
}
posted @
2007-04-06 16:31 sunny 閱讀(306) |
評論 (0) |
編輯 收藏
import java.io.*;
import java.util.*;
import java.sql.*;
import javax.naming.*;
import javax.sql.*;
public class ConnectionFactory
{
/**
oracle?? 分頁
select * from (
select a.*, ROWNUM rn from ( select * from user_info )? a
where ROWNUM<=40 )
where rn >=21
?
*/
??? private static Properties config = new Properties();
???
??? static
??? {
??????? try
??????? {
??????????? InputStream in = ConnectionFactory.class.getClassLoader().getResourceAsStream("dbconfig.properties");
??????????? config.load(in);
??????????? in.close();
??????? }catch(IOException e)
??????? {
??????????? e.printStackTrace();
??????????? throw new ExceptionInInitializerError(e.getMessage());
??????? }
??? }
???
??? public static Connection getConnection()
??? {
??????? if(config.getProperty("jndi-name") != null)
??????? {
??????????? return getJndiConnection();
??????? }
???????
??????? return getDirectConnection();
??? }
???
??? public static Connection getJndiConnection()
??? {
??????? Connection con = null;
??????? try
??????? {
/**context.xml
數據源的配置
<Context>
????? <Resource name="jdbc/oracle" auth="Container" type="javax.sql.DataSource" maxActive="2" maxIdle="1" maxWait="-1"
????? username="openlab" password="open123" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@192.168.0.20:1521:tarena"/>
</Context?
*/
??????????? Context ctx = new InitialContext();
??????????? DataSource ds = (DataSource)ctx.lookup("java:comp/env/" + config.getProperty("jndi-name"));
??????????? con = ds.getConnection();
??????? }catch(Exception e)
??????? {
??????????? e.printStackTrace();
??????? }
??????? return con;
??? }
???
??? public static Connection getDirectConnection()
??? {
??????? Connection con = null;
??????? try
??????? {
??????????? Class.forName(config.getProperty("driver"));
??????????? con = DriverManager.getConnection(config.getProperty("dburl") ,config.getProperty("user"), config.getProperty("password"));
??????? }catch(ClassNotFoundException cne)
??????? {
??????????? cne.printStackTrace();
??????? }catch(SQLException sqle)
??????? {
??????????? sqle.printStackTrace();
??????? }
???????
??????? return con;
??? }
???
??? public static void close(ResultSet rs, Statement st, Connection con)
??? {
??????? try
??????? {
??????????? rs.close();
??????? }catch(Exception e)
??????? {
??????? }
???????
??????? try
??????? {
??????????? st.close();
??????? }catch(Exception e)
??????? {
??????? }
???????
??????? try
??????? {
??????????? con.close();
??????? }catch(Exception e)
??????? {
??????? }
??? }
???
??? public static void main(String[] args) throws Exception
??? {
??????? Connection con = ConnectionFactory.getConnection();
??????? System.out.println(con);
??????? con.close();
??? }
}
posted @
2007-04-05 15:30 sunny 閱讀(152) |
評論 (0) |
編輯 收藏
上午:
一.JDBC原理概述
?
1,JDBC是一套協議,是JAVA開發人員和數據庫廠商達成的協議,也就是由Sun定義一組接口,由數據庫廠商來實現,并規定了JAVA開發人員訪問數據庫所使用的方法的調用規范。
?
2,JDBC的實現是由數據庫廠商提供,以驅動程序形式提供。
?
3,JDBC在使用前要先加載驅動。
JDBC對于使用者要有一致性,對不同的數據庫其使用方法都是相同的。
?
驅動開發必須要實現Driver接口。
數據庫驅動的實現方式
JDBC-ODBC橋接式
JDBC網絡驅動,這種方式是通過中間服務器的協議轉換來實現的
JDBC+本地驅動,這種方式的安全性比較差。
JDBC驅動,由數據庫廠商實現。
?
二.JDBC的API
?
java.sql包和javax.sql包
Driver接口(驅動),在加載某一 Driver 類時,它應該創建自己的實例并向 DriverManager 注冊該實例。這意味著用戶可以通過調用以下程序加載和注冊一個驅動程序
Class.forName("oracle.jdbc.driver.OracleDriver")
DriverManager類(驅動管理器),它可以創建連接,它本身就是一個創建Connection的工廠(Factory)。
Connection接口,會根據不同的驅動產生不同的連接
Statement接口,發送sql語句
ResultSet接口(結果集),是用來接收select語句返回的查詢結果的。其實質類似于集合。
?
下午:
三.JDBC應用步驟
1,注冊加載一個driver驅動
2,創建數據庫連接(Connection)
3,創建一個Statement(發送sql)
4,執行sql語句
5,處理sql結果(select語句)
6,關閉Statement
7,關閉連接Connection。
?
注意:6,7兩個步驟勢必須要做的,因為這些資源是不會自動釋放的,必須要自己關閉
?
訪問Oracle的數據庫的驅動名字叫ojdbc14.jar,要使用這個驅動程序,要先將他加到環境變量CLASSPATH中。
?
??? 注冊加載驅動driver,也就是強制類加載
??? Class.forName(Driver包名.Driver類名)。
?
??? Driver d=new Driver類();//注意:這個方法不能用參數來構造
??? DriverManager.registerDriver(d);
?
?
??? Oracle的Driver的全名oracle.jdbc.driver.OracleDriver
??? mysql的Driver的全名com.mysql.jdbc.Driver
??? SQLServer的Driver的全名com.microsoft.jdbc.sqlserver.SQLServerDriver
?
??? 創建連接
??? DriverManager.getConnection(String url,String username,String password);
??? Connection連接是通過DriverManager的靜態方法getConnection(.....)來得到的,這個方法的實質是把參數傳到實際的Driver中的connect()方法中來獲得數據庫連接的。
??? Oracle的URL值是由連接數據庫的協議和數據庫的IP地址及端口號還有要連接的數據庫的庫名(DatebaseName)
??? Oracle URL的格式
??? jdbc:oracle:thin:(協議)@XXX.XXX.X.XXX:XXXX(IP地址及端口號):XXXXXXX(所使用的庫名)
??? 例:jdbc:oracle:thin:@192.168.0.20:1521:tarenadb
??? MySql URL的寫法
??? 例: jdbc:mysql://localhost:3306/tarena
??? SQLServer URL的寫法
??? 例:jdbc:microsoft:sqlserver://localhost:1433/test
?
??? java -Djdbc.drivers=驅動的完整類名
?
??? 使用虛擬機參數,加載驅動 -D表示為虛擬機參數賦值
??? java -Djdbc.drivers=oracle.jdbc.driver.OracleDriver:com.mysql.jdbc.Driver
??
四.JDBC基本方法
??? DriverManager:如果有多個驅動可用的話,DriverManager會選擇其中一個.?
???
??? Driver:可以選擇固定的驅動
??? Driver driver = new oracle.jdbc.driver.OracleDriver();
??? String user = "sd0613";
?String password = "sd0613";
?Properties prop = new Properties();
?prop.setProperty("user",user);
?prop.setProperty("password",password);
??? driver.connect(url,properties);
???
??? executeQuery(sqlString);//返回結果集
??? executeUpdate(sqlString);//返回值為該次操作影響的記錄條數,create table返回0
??? execute(sqlString);
??? //適用于不知道具體的操作是什么,返回值是boolean類型的
??? //如果返回值是true,代表執行查詢操作;否則代表執行更新操作.
???
??? ResultSet
??? next()方法:
??? 1.判斷是否存在下一條記錄
??? 2.將游標移向下一條記錄??
??? getXXX(字段名或字段序號)//注意:字段序號從1開始
???
??? 關閉問題:
??? 使用Connection對象獲得一個Statement,Statement中的executeQuery(String sql) 方法可以使用select語句查詢,并且返回一個結果集 ResultSet通過遍歷這個結果集,可以獲得select語句的查詢結果,ResultSet的next()方法會操作一個游標從第一條記錄的前邊開始讀取,直到最后一條記錄。executeUpdate(String sql) 方法用于執行DDL和DML語句,可以update,delete操作。
注意:要按先ResultSet結果集,后Statement,最后Connection的順序關閉資源,因為Statement和ResultSet是需要連接時才可以使用的,所以在使用結束之后有可能其他的Statement還需要連接,所以不能先關閉Connection。
1.回憶下昨天的一些JDBC的配置
?(1) 驅動:??
??ojdbc14.jar (Oracle)?????????????????
??mysql-connector-java-3.1.11-bin.jar(MySql)
?(2) 實現了Driver接口的驅動類(程序中要加載的類):
??jdbc.oracle.driver.OracleDriver? (Oracle)
??com.mysql.jdbc.Driver? (MySql)
?(3)連接數據庫的URL
??jdbc:oracle:thin:@192.168.0.24:1521:tarena?? (Oracle)
??jdbc:mysql://192.168.0.24:3306/test??? (MySql)
?????????
2.PreparedStatement概述
?SQL語句傳到數據庫后,數據庫會先對其編譯再執行。在使用Statement時,如果要執行一組類似的SQL操作時,這樣做效率很低,而且把不同類型的數據直接寫在SQL語句中是比較麻煩的。這時應該用PreparedStatement來代替Statement,PreparedStatement 接口繼承 Statement,并和他在兩方面有所不同:
?(1)PreparedStatement 實例包含已編譯的 SQL 語句。這就是使語句先“準備好”。包含于 PreparedStatement對象中的SQL 語句可具有一個或多個 IN 參數。IN參數的值在 SQL 語句創建時未被指定。相反的,該語句為每個 IN 參數保留一個問號(“?”)作為占位符。每個問號的值必須在該語句執行之前,通過適當的setXXX 方法來提供。
?(2)由于 PreparedStatement 對象已預編譯過,所以其執行速度要快于 Statement 對象。因此,多次執行的 SQL 語句經常創建為 PreparedStatement 對象,以提高效率。
??
?作為 Statement 的子類,PreparedStatement 繼承了 Statement 的所有功能。另外它還添加了一整套方法,用于設置發送給數據庫以取代 IN 參數占位符的值。同時,三種方法 execute()、 executeQuery() 和 executeUpdate() 已被更改以使之不再需要參數。這些方法的 Statement 形式(接受 SQL 語句參數的形式)不應該用于 PreparedStatement 對象。
3.創建 PreparedStatement 對象
?以下的代碼段(其中 con 是 Connection 對象)創建包含帶兩個 IN 參數占位符的 SQL 語句的 PreparedStatement 對象:
?PreparedStatement pstmt = con.prepareStatement("UPDATE table4 SET m = ? WHERE x = ?");
?pstmt 對象包含語句 "UPDATE table4 SET m = ? WHERE x = ?",它已發送給DBMS,并編譯好為執行作好了準備。
?
4.傳遞 IN 參數
?在執行 PreparedStatement 對象之前,必須設置每個 ? 參數的值。這可通過調用 setXXX 方法來完成,其中 XXX 是與該參數相應的類型。例如,如果參數具有Java 類型 long,則使用的方法就是 setLong。setXXX 方法的第一個參數是要設置的參數的序數位置(從1開始),第二個參數是設置給該參數的值。例如,以下代碼將第一個參數設為 123456789,第二個參數設為 100000000:
?pstmt.setLong(1, 123456789);
?pstmt.setLong(2, 100000000);
5.ResultSetMetaData
?元數據是用來描述數據的數據,ResultSetMetaData就是來描述結果集的列的類型和屬性信息,比如可以通過它得到結果集的列數,列名等。具體可在API中查閱java.sql.ResultSetMetaData。
?ResultSetMetaData對象可以通過ResultSet對象的getMetaData()來得到。
?ResultSetMetaData對象有以下三個方法比較常用:
?getColumnCount():獲得實際列數
?getColumnName(int colnum):獲得指定列的列名
?getColumnType(int colnum):獲得指定列的數據類型(Types里面的類型,存放的是整數)
?
6.JDBC是持久層的技術,是JAVA連接數據庫目前最通用的手段。其他的持久層技術,比如接下來我們要學的Hibernate,底層也是由JDBC實現的。持久層是與業務無關的,具體的業務由業務層完成,當業務層需要和數據庫進行交互時,就需要通過持久層來操作。
7.BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
?由于System.in是字節流,我們需要把他轉成字符流。并用BufferedReader包裝后方便我們的操作。
?
8.為了區分表中不同的數據,我們要給放入表中持久化的每個對象都加上一個唯一的標識,這就是ID,ID是與業務無關的。ID的生成方法有很多,在Oracle數據庫中我們一半利用Sequence來生成。
9.讀取配置文件時,我們采用Properties對象。它是HashTable的子類,它有個load(InputStream inStream) 的方法可以直接從輸入流中讀取屬性列表(鍵值對)。getProperty(String key) 方法用指定的鍵在此屬性列表中搜索值。
1.Registering a driver
2.Establishing a connection to the datebase
3.Creating a statement
4.Executing a SQL
5.Processing the results
6.Closing down JDBC objects
JDBC第三天
上午:
一.事務(Transaction)
原子操作:不可再分的操作,一個操作不能再分成比它更細小的操作.
事務是針對原子操作的,要求原子操作不可再分,并且必須同時成功同時失敗。
事務就是把一些非原子操作,變成原子操作,由應用服務器來提出要求,由數據庫服務器來執行操作.
在JDBC中默認是自動提交的,如果要想使用事務,需要按以下步驟執行:
1.要調用con.setAutoCommite(false)方法(打開事務邊界),把自動提交(commit)置為false。
2.進行正常的數據庫操作
3.如果操作成功了可以選擇con.commit(),或者操作失敗時選擇con.roolback()------
?? (回滾:數據恢復到之前的情況)
? 注意:打開事務就要關閉自動提交,當不需要再使用事務的時候調用
setAutoCommite(true).
事務性資源(監控完整性)
?
二.事務并發產生的問題
??? 三種并發產生的后果:
1,臟讀:一個事務讀取到了另外一個事務沒有提交的數據。(Dirty Read)
2,重復讀:一個事務讀取到了另外一個事務提交的數據。它是要保持在同一時間點上讀取到的數據相同,希望在一段時間內的數據是不變的。
3,幻讀:一個事務讀取到了另外一個事務提交的數據。用同樣的操作讀取兩次,得到的記錄數不相同。
三.事務隔離級別
??? 五種控制級別:
TRANSACTION_NONE不使用事務。
TRANSACTION_READ_UNCOMMITTED 允許臟讀。
TRANSACTION_READ_COMMITTED防止臟讀,最常用的隔離級別,并且是大多數數據庫的默認隔離級別----------------------
TRANSACTION_REPEATABLE_READ可以防止臟讀和不可重復讀,
TRANSACTION_SERIALIZABLE可以防止臟讀,不可重復讀取和幻讀,(事務串行化)會降低數據庫的效率
以上的五個事務隔離級別都是在Connection類中定義的靜態常量,使用setTransactionIsolation(int level) 方法可以設置事務隔離級別。
如:con.setTransactionIsolation(Connection.REPEATABLE_READ);
下午:
四.JDBC2.0新特性
1.可滾動特性和可更新特性
JDBC1.0中是指游標的移動的方向和方式是單向,單步(相對)移動,功能比較簡單.
JDBC2.0中游標可以雙向,相對或者絕對移動.
可滾動結果集:這種結果集不但可以雙向滾動,相對定位,絕對定位,并且還可以修改數據信息。
1)滾動特性
定位函數:aaa
boolean absolute(int row),定位到指定的記錄位置。定位成功返回true,不成功返回false。
void afterLast() ,把游標移動到最后一條記錄的后面(邏輯位置)。 一定會有的
void beforeFirst() ,把游標移動到第一條記錄的前面(邏輯位置)。
//由于第一條記錄的前面和最后一條記錄的后面這兩個位置肯定存在,所以無需判斷是否存在,返回值設為void.
boolean first(),把游標定位到第一條記錄,相對定位;
boolean last(),把游標定位到最后一條記錄?? 也是相對的概念。
//當結果集為空的時候,這兩個方法會返回false.
boolean next(),此方法是使游標向下一條記錄移動。
boolean previous() ,此方法可以使游標向上一條記錄移動,前提是前面還有記錄。
boolean relative(int rows) ,相對定位方法,參數值可正可負,參數為正,游標從當前位置向后移動指定值條記錄,參數為負,游標從當前位置向前移動指定值條記錄。
判斷函數:
ifBeforeFirst()判斷是否在在第一條記錄之前.
ifAfterLast()判斷是否在在最后一條記錄之后.
ifFirst()判斷是否為第一條記錄.
ifLast()判斷是否為最后一條記錄.
要使用可滾動結果集時,需要一次設置更新特性與滾動特性,不能分開.
1.更新特性常量:
CONCUR_READ_ONLY 只讀結果集???? (默認的)
CONCUR_UPDATABLE 可更新結果集
2.滾動特性常量:
TYPE_FORWARD_ONLY ,該常量表示指針只能向前移動的 ResultSet 對象的類型。(默認)
雙向滾動:
?不敏感:TYPE_SCROLL_INSENSITIVE ,該常量指示可滾動但通常不受其他更改影響的 ResultSet 對象的類型。
?敏感的:TYPE_SCROLL_SENSITIVE ,該常量指示可滾動并且通常受其他更改影響的 ResultSet 對象的類型。
//敏感:數據庫改變,結果集改變.
語法:????????
Statement st=null;
st=con.createStatement(ReusltSet.TYPE_SCROLL_INSENSITIVE,ResuleSet.CONCUR_UPDATABLE)
在創建Statement的時候就要指定這兩個參數,使用Statement,第一個參數代表滾動特性常量,第二個代表更新特性常量
----------------------------------------
2)可更新特性
a.moveToInsertRow();記錄當前游標位置,將游標移到和結果集結構類似的緩沖區;
b.使用updateXxx(int column,columnType value)方法來更新指定列數據;
c.使用insertRow() 方法插入記錄,加信結果集,更新
d.將游標指回原位,moveToCurrentRow() 。
?2,3步,可循環
-----------------------------------------------------
能否使用JDBC2.0 ResultSet的新特性,要看使用的數據庫驅動是否支持.
還有只能用于單表且表中有主鍵字段(可能會是聯合主鍵),不能夠有表連接,會取
可更新操作必須滿足以下條件:
a.查詢只能引用一張表.
b.不能包含任何連接操作.
c.必須把完整的主鍵查到結果集里面;
d.保證所有字段為非空字段并且沒有默認值。
五.數據庫元數據:
DatabaseMetaData dbmd = con.getMetaData();//得到數據庫元數據
dbmd.supportsResultSetConcurrency(ResultSet.TYPE_FORWARD_ONLY,
??????????????????? ResultSet.CONCUR_UPDATABLE);//判斷是否支持可更新操作
六.批量更新
優勢:
1.節省傳遞時間
2.并發處理
PreparedStatement:
1.addBatch() 將一組參數添加到 PreparedStatement對象內部
2.executeBatch() 將一批參數提交給數據庫來執行,如果全部命令執行成功,則返回更新計數組成的數組。
Statement:
addBatch(String sql)方法會在批處理緩存中加入一條sql語句
executeBatch()執行批處理緩存中的所有sql語句。
注意:PreparedStatement中使用批量更新時,要先設置好參數后再使用addBatch()方法加入緩存。
批量更新中只能使用更新或插入語句
//
Statement stm=con.createStatement(int resultSetType,int resultSetConcurrency);創建的時候就要指明要什么樣的結果集。
??先可滾,后可更新
boolean absolute (int row)絕對定位,
afterLast()定位到最后一條記錄的后面
?
?
?
?
?
?
?
?
?
?
?
?