session是通過在客戶端生成一個cookie,所有請求會帶上這個cookie。一個cookie的NAME、Domain和Path屬性值均相同,則會覆蓋,若未設置Domain域,則域為ip(不包括端口),因此應用A的session被應用B的session覆蓋了。
經測試:tomcat、weblogic、websphere的session默認都是JSESSIONID 為key來識別的,因此在沒有特別設置下,同一個域下的多個應用session會互相覆蓋。
解決辦法:
設置各個應用使用不同的cookie-name,或者將JSESSIONID的path路徑設置為不同。
1)WebLogic的Cookie相關配置:weblogic.xml
屬性名 |
默認值 | 值 |
cookie-name | JSESSIONID | 如未設置,默認為“JSESSIONID” |
cookie-path | NULL | 如未設置,默認為“/” |
cookie-domain | NULL | 如未設置,默認為發放cookie的服務器的域 |
1. <session-descriptor> 2. <session-param> 3. <param-name>CookieName</param-name> 4. <param-value>HADFCookie</param-value> 5. </session-param> 6. </session-descriptor>
2)websphere的設置(設置不同JSESSIONID的path)
應用程序->企業應用程序-> [Application Server] ->
會話管理->1.覆蓋會話管理(需打鉤).
會話管理->2.啟用 cookie(需打鉤)->修改'Cookie路徑'
3)Tomcat的設置(設置不同JSESSIONID的path)
修改tomcat/conf/server.xml:
1.tomcat5修改方法
在啟動項中增加org.apache.catalina.SESSION_COOKIE_NAME參數
linux
JAVA_OPTS=’-Dorg.apache.catalina.SESSION_COOKIE_NAME=yousessionname‘win
set JAVA_OPTS=”-Dorg.apache.catalina.SESSION_COOKIE_NAME=yousessionname“
2.tomcat6和tomcat7修改方法相同
在Context容器標簽上增加sessionCookieName參數
<Context path=”/” docBase=”webapp” reloadable=”false” sessionCookieName=”yoursessionname”></Context>
還可以加上sessionCookiePath
<Context ... sessionCookiePath="/" > ... </Context>
延伸閱讀:tomcat修改jsessionid在cookie中的名稱 http://blog.shilimin.com/338.htm
公司名稱:北京豐帆佳宇運輸有限公司
公司簡介:渣土消納證辦理,大型支護土方深度開挖,礦山暗挖,基坑開挖,建筑垃圾清運,渣土清運,砂石料配送,工程機械租賃業務
公司網址:www.bjffjy.com
正如,圖片上的說明:在IE6(沒有測試IE7或更高版本)li標簽的第一條“聯系我們”,沒有前面的:點。看一下我的demo代碼啊吧~
要觸發這個BUG有不少“要點”啊!第一 、.news-list ol{ padding:10px 10px 10px 10px;} 這條樣式必須要有,更確切的說是第一個“10px”必須有,當然你可以換成其他像素值,零除外!當改成0之后這個bug就沒有了~,這也就是我為什么把這個分開寫,沒直接寫成:.news-list ol{ padding:10px ;},這樣的原因。
第二點、 .news-list li{ height:20px; list-style:disc inside;},這個里面也有一個必要的:高度。當你把這個高度去掉的時候,你會發現這個bug也會消失。
有上面這兩個“苛刻”的條件,估計也就是為什么很少有人碰到的原因吧!知道了原因解決當然不是問題。從上面的兩點就可以很好的解決這bug了。
方法一、當然就是準對第一個條件的,如果可以去掉padding。
方法二、當然也是在不影響布局的情況下:去掉 height
方法三、任然還是去掉:.news-list ol{ padding:10px 10px 10px 10px;} 這條樣式,同時在ol標簽的父標簽(這里的父標簽就是<div class=”news-list”>了,當然你還可以在這個中間加入一個div)中加入這條樣式。這樣既不會影響布局,又能很好的解決這個bug,下面是我的第三種解決方法代碼:
NDC和MDC是log4j用于存儲應用程序的上下文信息(context infomation),從而便于在log中使用這些上下文信息。
NDC采用了一個類似棧的機制來push存儲上下文信息,每一個線程都獨立地儲存上下文信息。比如說一個servlet就可以針對每一個request創建對應的NDC,儲存客戶端地址等等信息。相關的信息使用NDC.push(message);
在log的時候將信息輸出。在相應的PatternLayout中使用”%x”來輸出存儲的上下文信息
例如:String remoteAddr = request.getRemoteAddr();
NDC.push(remoteAddr);
在log4j.properties文件中作如下的配置即可
log4j.appender.console.layout.ConversionPattern=%-d{yyyy/MM/dd HH:mm:ss,SSS} [%X] -[%c]-[%p] %m%n
MDC內部使用了類似map的機制來存儲信息,相對應的方法,MDC.put(key,value);在配置PatternLayout的時候使用:%x{key}來輸出對應的value
例如:String remoteAddr = request.getRemoteAddr();
MDC.put("ip", remoteAddr);
在log4j.properties文件中作如下的配置即可
log4j.appender.console.layout.ConversionPattern=%-d{yyyy/MM/dd HH:mm:ss,SSS} [%X{ip}] -[%c]-[%p] %m%n
總:如果在項目中有過濾器或者模板Action,你可以把獲取公共的屬性方法直接定義在里面,然后在配置文件中配置獲取顯示
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在請求應用時,struts2將會截獲所有請求,對于servlet請求將不能夠正常相應,是struts2把servlet當成act
解決方法目前有四種:
方法1:統一在servlet后面加上.servlet(包括web.xml配置文件中和頁面上使用servlet的地方)
方法2:繼承StrutsPrepareAndExecuteF
public void init(FilterConfig filterConfig) throws
ServletException {
..............................
}
public void doFilter(ServletRequest request,
ServletResponse response,
IOException, ServletException {
if(url.contain("servlet")){
((HttpServletResponse) response).sendRedirect(redirectUrl);
}
super.doFilter(request, response, chain);
}
方法3:修改攔截頁面配置
原:
<filter>
/* </url-pattern>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.act
<filter-name>struts2</filter-name>
<url-pattern>*.jsp</url-pattern>
<filter-name>struts2</filter-name>
<url-pattern>/user/*</url-pattern>
servlet的請求路徑不必改變
方法4:在struts.xml文件中修改
……
1. 框架技術(Struts2.3.4+Srping3.2+Mybatis3.2)
i. 添加框架Struts2.3.4
Ø 清理lib
二、框架的使用
public class log4jlistener implements ServletContextListener {
public static final String log4jdirkey = "log4jdir";
public void contextDestroyed(ServletContextEvent servletcontextevent) {
System.getProperties().remove(log4jdirkey);
}
public void contextInitialized(ServletContextEvent servletcontextevent) {
String log4jdir = servletcontextevent.getServletContext().getRealPath("/");
//System.out.println("log4jdir:"+log4jdir);
System.setProperty(log4jdirkey, log4jdir);
}
}
web.xml配置:
安裝步驟:
1、下載aptana3.2 Eclipse Plugin插件.
下載地址:http://update1.aptana.org/studio/3.2/024747/index.html
2、解壓出features與plugins文件夾,COPY到
D:\Program Files\MyEclipse Blue Edition\MyPlugins\aptana3.2
3、在D:\Program Files\MyEclipse Blue Edition\MyEclipse Blue Edition 9.0 M2\dropins在新建文件aptana.link, 內容是
path=D:\\Program Files\\MyEclipse Blue Edition\\MyPlugins\\aptana3.2 (注意斜線的方向,反了不行!Myeclipse會找不到路徑!)
4、刪除D:\Program Files\MyEclipse Blue Edition\MyEclipse Blue Edition 9.0 M2\configuration文件夾中org.eclipse.update文件夾
5、重啟 Myeclipse,看到了界面
2. 配置:
配置 Code Assist,對我來說很重要,Javascript學的不咋地啊
配置 File Association,文件關聯,主要有 htm,html,xml,javascript,css(這個沒找到) 【貌似不支持使用Aptana Editor 來打開JSP文件】
再配置一些設置之后,重啟Myeclipse,試試看,打開一個 html,呵呵,js有代碼提示幫助,Enjoy it!
FORALL語句
FORALL語句的一個關鍵性改進,它可大大簡化代碼,并且對于那些要在PL/SQL程序中更新很多行數據的程序來說,它可顯著提高其性能。
1:
用FORALL來增強DML的處理能力
Oracle為Oracle8i中的PL/SQL引入了兩個新的數據操縱語言(DML)語句:BULK COLLECT和FORALL。這兩個語句在PL/SQL內部進行一種數組處理
;BULK COLLECT提供對數據的高速檢索,FORALL可大大改進INSERT、UPDATE和DELETE操作的性能。Oracle數據庫使用這些語句大大減少了
PL/SQL與SQL語句執行引擎的環境切換次數,從而使其性能有了顯著提高。
使用BULK COLLECT,你可以將多個行引入一個或多個集合中,而不是單獨變量或記錄中。下面這個BULK COLLECT的實例是將標題中包含
有"PL/SQL"的所有書籍檢索出來并置于記錄的一個關聯數組中,它們都位于通向該數據庫的單一通道中。
DECLARE
TYPE books_aat
IS TABLE OF book%ROWTYPE
INDEX BY PLS_INTEGER;
books books_aat;
BEGIN
SELECT *
BULK COLLECT INTO book
FROM books
WHERE title LIKE '%PL/SQL%';
...
END;
類似地,FORALL將數據從一個PL/SQL集合傳送給指定的使用集合的表。下面的代碼實例給出一個過程,即接收書籍信息的一個嵌套表,并將該
集合(綁定數組)的全部內容插入該書籍表中。注意,這個例子還利用了Oracle9i的FORALL的增強功能,可以將一條記錄直接插入到表中。
BULK COLLECT和FORALL都非常有用,它們不僅提高了性能,而且還簡化了為PL/SQL中的SQL操作所編寫的代碼。下面的多行FORALL INSERT相當
清楚地說明了為什么PL/SQL被認為是Oracle數據庫的最佳編程語言。
CREATE TYPE books_nt
IS TABLE OF book%ROWTYPE;
/
CREATE OR REPLACE PROCEDURE add_books (
books_in IN books_nt)
IS
BEGIN
FORALL book_index
IN books_in.FIRST .. books_in.LAST
INSERT INTO book
VALUES books_in(book_index);
...
END;
不過在Oracle數據庫10g之前,以FORAll方式使用集合有一個重要的限制:該數據庫從IN范圍子句中的第一行到最后一行,依次讀取集合的內容
。如果在該范圍內遇到一個未定義的行,Oracle數據庫將引發ORA-22160異常事件:
ORA-22160: element at index [N] does not exist
對于FORALL的簡單應用,這一規則不會引起任何麻煩。但是,如果想盡可能地充分利用FORALL,那么要求任意FORALL驅動數組都要依次填充可
能會增加程序的復雜性并降低性能。
在Oracle數據庫10g中,PL/SQL現在在FORALL語句中提供了兩個新子句:INDICES OF與VALUES OF,它們使你能夠仔細選擇驅動數組中該由擴展
DML語句來處理的行。
當綁定數組為稀疏數組或者包含有間隙時,INDICES OF會非常有用。該語句的語法結構為:
FORALL indx IN INDICES
OF sparse_collection
INSERT INTO my_table
VALUES sparse_collection (indx);
VALUES OF用于一種不同的情況:綁定數組可以是稀疏數組,也可以不是,但我只想使用該數組中元素的一個子集。那么我就可以使用VALUES
OF來指向我希望在DML操作中使用的值。該語句的語法結構為:
FORALL indx IN VALUES OF pointer_array
INSERT INTO my_table
VALUES binding_array (indx);
不用FOR循環而改用FORALL
假定我需要編寫一個程序,對合格員工(由comp_analysis.is_eligible函數確定)加薪,編寫關于不符合加薪條件的員工的報告并寫入
employee_history表。我在一個非常大的公司工作;我們的員工非常非常多。
對于一位PL/SQL開發人員來說,這并不是一項十分困難的工作。我甚至不需要使用BULK COLLECT或FORALL就可以完成這項工作,如清單 1所示
,我使用一個CURSOR FOR循環和單獨的INSERT及UPDATE語句。這樣的代碼簡潔明了;不幸地是,我花了10分鐘來運行此代碼,我的"老式"方法
要運行30分鐘或更長時間。
清單 1:
CREATE OR REPLACE PROCEDURE give_raises_in_department (
dept_in IN employee.department_id%TYPE
, newsal IN employee.salary%TYPE
)
IS
CURSOR emp_cur
IS
SELECT employee_id, salary, hire_date
FROM employee
WHERE department_id = dept_in;
BEGIN
FOR emp_rec IN emp_cur
LOOP
IF comp_analysis.is_eligible (emp_rec.employee_id)
THEN
UPDATE employee
SET salary = newsal
WHERE employee_id = emp_rec.employee_id;
ELSE
INSERT INTO employee_history
(employee_id, salary
, hire_date, activity
)
VALUES (emp_rec.employee_id, emp_rec.salary
, emp_rec.hire_date, 'RAISE DENIED'
);
END IF;
END LOOP;
END give_raises_in_department;
好在我公司的數據庫升級到了Oracle9i,而且更幸運的是,在最近的Oracle研討會上(以及Oracle技術網站提供的非常不錯的演示中)我了解
到了批量處理方法。所以我決定使用集合與批量處理方法重新編寫程序。寫好的程序如清單 2所示。
清單 2:
1 CREATE OR REPLACE PROCEDURE give_raises_in_department (
2 dept_in IN employee.department_id%TYPE
3 , newsal IN employee.salary%TYPE
4 )
5 IS
6 TYPE employee_aat IS TABLE OF employee.employee_id%TYPE
7 INDEX BY PLS_INTEGER;
8 TYPE salary_aat IS TABLE OF employee.salary%TYPE
9 INDEX BY PLS_INTEGER;
10 TYPE hire_date_aat IS TABLE OF employee.hire_date%TYPE
11 INDEX BY PLS_INTEGER;
12
13 employee_ids employee_aat;
14 salaries salary_aat;
15 hire_dates hire_date_aat;
16
17 approved_employee_ids employee_aat;
18
19 denied_employee_ids employee_aat;
20 denied_salaries salary_aat;
21 denied_hire_dates hire_date_aat;
22
23 PROCEDURE retrieve_employee_info
24 IS
25 BEGIN
26 SELECT employee_id, salary, hire_date
27 BULK COLLECT INTO employee_ids, salaries, hire_dates
28 FROM employee
29 WHERE department_id = dept_in;
30 END;
31
32 PROCEDURE partition_by_eligibility
33 IS
34 BEGIN
35 FOR indx IN employee_ids.FIRST .. employee_ids.LAST
36 LOOP
37 IF comp_analysis.is_eligible (employee_ids (indx))
38 THEN
39 approved_employee_ids (indx) := employee_ids (indx);
40 ELSE
41 denied_employee_ids (indx) := employee_ids (indx);
42 denied_salaries (indx) := salaries (indx);
43 denied_hire_dates (indx) := hire_dates (indx);
44 END IF;
45 END LOOP;
46 END;
47
48 PROCEDURE add_to_history
49 IS
50 BEGIN
51 FORALL indx IN denied_employee_ids.FIRST .. denied_employee_ids.LAST
52 INSERT INTO employee_history
53 (employee_id
54 , salary
55 , hire_date, activity
56 )
57 VALUES (denied_employee_ids (indx)
58 , denied_salaries (indx)
59 , denied_hire_dates (indx), 'RAISE DENIED'
60 );
61 END;
62
63 PROCEDURE give_the_raise
64 IS
65 BEGIN
66 FORALL indx IN approved_employee_ids.FIRST .. approved_employee_ids.LAST
67 UPDATE employee
68 SET salary = newsal
69 WHERE employee_id = approved_employee_ids (indx);
70 END;
71 BEGIN
72 retrieve_employee_info;
73 partition_by_eligibility;
74 add_to_history;
75 give_the_raise;
76 END give_raises_in_department;
掃一眼清單1 和清單2 就會清楚地認識到:改用集合和批量處理方法將增加代碼量和復雜性。但是,如果你需要大幅度提升性能,這還是值得
的。下面,我們不看這些代碼,我們來看一看當使用FORALL時,用什么來處理CURSOR FOR循環內的條件邏輯。
定義集合類型與集合
在清單 2中,聲明段的第一部分(第6行至第11行)定義了幾種不同的集合類型,與我將從員工表檢索出的列相對應。我更喜歡基于employee%
ROWTYPE來聲明一個集合類型,但是FORALL還不支持對某些記錄集合的操作,在這樣的記錄中,我將引用個別字段。所以,我還必須為員工ID、
薪金和雇用日期分別聲明其各自的集合。
接下來為每一列聲明所需的集合(第13行至第21行)。首先定義與所查詢列相對應的集合(第13行至第15行):
employee_ids employee_aat;
salaries salary_aat;
hire_dates hire_date_aat;
然后我需要一個新的集合,用于存放已被批準加薪的員工的ID(第17行):
approved_employee_ids employee_aat;
最后,我再為每一列聲明一個集合(第19行至第21行),用于記錄沒有加薪資格的員工:
denied_employee_ids employee_aat;
denied_salaries salary_aat;
denied_hire_dates hire_date_aat;
深入了解代碼
數據結構確定后,我們現在跳過該程序的執行部分(第72行至第75行),了解如何使用這些集合來加速進程。
retrieve_employee_info;
partition_by_eligibility;
add_to_history;
give_the_raise;
我編寫此程序使用了逐步細化法(也被稱為"自頂向下設計")。所以執行部分不是很長,也不難理解,只有四行,按名稱對過程中的每一步進
行了描述。首先檢索員工信息(指定部門的所有員工)。然后進行劃分,將要加薪和不予加薪的員工區分出來。完成之后,我就可以將那些不
予加薪的員工添加至員工歷史表中,對其他員工進行加薪。
以這種方式編寫代碼使最終結果的可讀性大大增強。因而我可以深入到該程序中對我有意義的任何部分。
有了已聲明的集合,我現在就可以使用BULK COLLECT來檢索員工信息(第23行至第30行)。這一部分有效地替代了CURSOR FOR循環。至此,數
據被加載到集合中。
劃分邏輯(第32行至第46行)要求對剛剛填充的集合中的每一行進行檢查,看其是否符合加薪條件。如果符合,我就將該員工ID從查詢填充的
集合復制到符合條件的員工的集合。如果不符合,則復制該員工ID、薪金和雇用日期,因為這些都需要插入到employee_history表中。
初始數據現在已被分為兩個集合,可以將其分別用作兩個不同的FORALL語句(分別從第51行和第66行開始)的驅動器。我將不合格員工的集合
中的數據批量插入到employee_history(add_to_history)表中,并通過give_the_raise過程,在employee表中批量更新合格員工的信息。
最后再仔細地看一看add_to_history(第48行至第61行),以此來結束對這個重新編寫的程序的分析。FORALL語句(第51行)包含一個IN子句
,它指定了要用于批量INSERT的行號范圍。在對程序進行第二次重寫的說明中,我將把用于定義范圍的集合稱為"驅動集合"。但在
add_to_history的這一版本中,我簡單地假定: 使用在denied_employee_ids中定義的所有行。在INSERT自身內部,關于不合格員工的三個集
合都會被用到;我將把這些集合稱為"數據集合"。可以看到,驅動集合與數據集合無需匹配。在學習Oracle數據庫10g的新特性時,這是一個關
鍵點。
結果,清單 2 的行數大約是清單 1行數的2倍,但是清單 2 中的代碼會在要求的時間內運行。在使用Oracle數據庫10g之前,在這種情況下,
我只會對能夠在這一時間內運行代碼并開始下一個任務這一點感到高興。
不過,有了Oracle數據庫10g中最新版的PL/SQL,現在我就可以在性能、可讀性和代碼量方面作出更多的改進。
將VALUES OF用于此過程
在Oracle數據庫10g中,可以指定FORALL語句使用的驅動集合中的行的子集。可以使用以下兩種方法之一來定義該子集:
將數據集合中的行號與驅動集合中的行號進行匹配。你需要使用INDICES OF子句。
將數據集合中的行號與驅動集合中所定義行中找到的值進行匹配。這需要使用VALUES OF子句。
在對give_raises_in_department進行第二次和最后一次改寫中我將使用VALUES OF子句。清單 3 包含這個版本的全部代碼。我將略過這一程序
中與前一版本相同的部分。
從聲明集合開始,請注意我不再另外定義集合來存放合格的和不合格的員工信息,而是在清單 3 (第17行至第21行)中聲明兩個"引導"集合:
一個用于符合加薪要求的員工,另一個用于不符合加薪要求的員工。這兩個集合的數據類型都是布爾型;不久將會看到,這些集合的數據類型
與FORALL語句毫無關系。FORALL語句只關心定義了哪些行。 在員工表中擁有50 000行信息的give_raises_in_department的三種執行方法的占
用時間 執行方法 用時
CURSOR FOR循環 00:00:38.01
Oracle數據庫10g之前的批量處理 00:00:06.09
Oracle數據庫10g的批量處理 00:00:02.06
在員工表中擁有100,000行數據的give_raises_in_department的三種執行方法的占用時間 執行方法 用時
CURSOR FOR循環 00:00:58.01
Oracle數據庫10g之前的批量處理 00:00:12.00
Oracle數據庫10g的批量處理 00:00:05.05
表1:處理50,000行和100,000行數據的用時測試結果
retrieve_employee_info子程序與前面的相同,但是對數據進行劃分的方式完全不同(第32行至第44行)。我沒有將記錄從一個集合復制到另
一個集合(這個操作相對較慢),而只是確定與員工ID集合中的行號相匹配的相應引導集合中的行(通過為其指定一個TRUE值)。
現在可以在兩個不同FORALL語句(由第49行和第65行開始)中,將approved_list和denied_list集合用作驅動集合。
為了插入到employee_history表中,我使用了如下語句:
FORALL indx IN VALUES OF denied_list
為了進行更新(給員工進行加薪),我使用這一格式:
FORALL indx IN VALUES OF approved_list
在這兩個DML語句中,數據集合是在BULK COLLECT 檢索步驟中填充的最初的集合;沒有進行過復制。利用VALUES OF,Oracle數據庫在這些數據
集合的行中進行篩選,僅使用行號與驅動集合中行號相匹配的行
利用本程序中的VALUES OF,可以避免復制對全部記錄進行復制,而是用行號的一個簡單列表來替換它們。對于大型數組,進行這些復制的開銷
是非常可觀的。為了測試Oracle數據庫10g的優越性,我裝入employee表并對50,000行和100,000行的數據運行測試。為了模擬更多的現實情況
,我將Oracle數據庫10g之前的批量處理的執行方法作了修改以進行集合內容的多次復制。然后我使用SQL*Plus SET TIMING ON來顯示運行各個
不同的執行方法所用的時間。表 1 給出了結果。
從這些時間測定得到的結論非常清楚:由單個DML語句變為批量處理將大幅縮短耗用時間,數據為50,000行時的用時由38秒減為6秒,數據為
100,000行時的用時由58秒減為12秒。而且,通過使用VALUES OF來避免復制數據,我可以將用時縮短一半左右。
即使沒有性能上的改進,VALUES OF及其同類子句--INDICES OF也提高了PL/SQL語言的靈活性,使開發人員能夠更輕松地編寫出更直觀和更容易
維護的代碼。
在產品壽命這一點上,PL/SQL是一種成熟且功能強大的語言。因而,其很多新特性都是逐漸增加和改進而成的。不過,這些新特性還是使應用
程序的性能和開發人員的開發效率有了重大改變。VALUES OF就是這種特性的一個很好的例子。
dba_開頭.....
dba_users 數據庫用戶信息
dba_segments 表段信息
dba_extents 數據區信息
dba_objects 數據庫對象信息
dba_tablespaces 數據庫表空間信息
dba_data_files 數據文件設置信息
dba_temp_files 臨時數據文件信息
dba_rollback_segs 回滾段信息
dba_ts_quotas 用戶表空間配額信息
dba_free_space 數據庫空閑空間信息
dba_profiles 數據庫用戶資源限制信息
dba_sys_privs 用戶的系統權限信息
dba_tab_privs 用戶具有的對象權限信息
dba_col_privs 用戶具有的列對象權限信息
dba_role_privs 用戶具有的角色信息
dba_audit_trail 審計跟蹤記錄信息
dba_stmt_audit_opts 審計設置信息
dba_audit_object 對象審計結果信息
dba_audit_session 會話審計結果信息
dba_indexes 用戶模式的索引信息
user_開頭
user_objects 用戶對象信息
user_source 數據庫用戶的所有資源對象信息
user_segments 用戶的表段信息
user_tables 用戶的表對象信息
user_tab_columns 用戶的表列信息
user_constraints 用戶的對象約束信息
user_sys_privs 當前用戶的系統權限信息
user_tab_privs 當前用戶的對象權限信息
user_col_privs 當前用戶的表列權限信息
user_role_privs 當前用戶的角色權限信息
user_indexes 用戶的索引信息
user_ind_columns 用戶的索引對應的表列信息
user_cons_columns 用戶的約束對應的表列信息
user_clusters 用戶的所有簇信息
user_clu_columns 用戶的簇所包含的內容信息
user_cluster_hash_expressions 散列簇的信息
v$開頭
v$database 數據庫信息
v$datafile 數據文件信息
v$controlfile 控制文件信息
v$logfile 重做日志信息
v$instance 數據庫實例信息
v$log 日志組信息
v$loghist 日志歷史信息
v$sga 數據庫SGA信息
v$parameter 初始化參數信息
v$process 數據庫服務器進程信息
v$bgprocess 數據庫后臺進程信息
v$controlfile_record_section 控制文件記載的各部分信息
v$thread 線程信息
v$datafile_header 數據文件頭所記載的信息
v$archived_log 歸檔日志信息
v$archive_dest 歸檔日志的設置信息
v$logmnr_contents 歸檔日志分析的DML DDL結果信息
v$logmnr_dictionary 日志分析的字典文件信息
v$logmnr_logs 日志分析的日志列表信息
v$tablespace 表空間信息
v$tempfile 臨時文件信息
v$filestat 數據文件的I/O統計信息
v$undostat Undo數據信息
v$rollname 在線回滾段信息
v$session 會話信息
v$transaction 事務信息
v$rollstat 回滾段統計信息
v$pwfile_users 特權用戶信息
v$sqlarea 當前查詢過的sql語句訪問過的資源及相關的信息
v$sql 與v$sqlarea基本相同的相關信息
v$sysstat 數據庫系統狀態信息
all_開頭
all_users 數據庫所有用戶的信息
all_objects 數據庫所有的對象的信息
all_def_audit_opts 所有默認的審計設置信息
all_tables 所有的表對象信息
all_indexes 所有的數據庫對象索引的信息
session_開頭
session_roles 會話的角色信息
session_privs 會話的權限信息
index_開頭
index_stats 索引的設置和存儲信息
偽表
dual 系統偽列表信息
8080端口被其他的應用占用
第一步,命令提示符號,執行命令:netstat -ano
可見,占用8080端口的進程的PID是1476
第二步
方法一:
命令提示符號,執行命令:tasklist
xxx.exe 1476 Console 0 6,464 K
可見,該占用8080端口的進程是xxx.exe
通過任務管理器,終止進程xxx.exe
方法二:寫Web頁面就像我們建設房子一樣,地基牢固,房子才不會倒。同樣的,我們制作Web頁面也一樣,一個良好的HTML結構是制作一個美麗的網站的開始,同樣的,良好的CSS只存在同樣良好的HTML中,所以一個干凈的,語義的HTML的優點很多,那么平時制作中,我們做到了這一點嗎?我們一起來看一張圖片:
上圖展示了兩段代碼,我想大家都只會喜歡第一種,我們先不說其語義,至少他的結構讓我們看上去清爽,而第二種呢?一看就是糟糕的代碼的代碼,讓人討厭的代碼。那么要怎么樣才能寫出一個好的代碼,整潔的代碼呢?下面我們就從以下十二個方面一起來學習,只要大家以后在寫代碼的時候能堅持下面的十二個原則,保準 你的代碼質量能上去,而且你寫的代碼會人見人愛。
如果我們想做好一件事情,首先要知道我們有哪些權利去做,就如“DOCTYPE”的聲明,我們沒有必要去討論是否使用HTML4.01或者XHTML1.0或者說現在的HTML5都提供了嚴格版本或者過渡版本,這些都能很好的支持我們寫的代碼:
由于我們現在的布局不需要table布局也能做出很好的布局,那么我們就可以考慮不使用過渡型而使用嚴格型的“DOCTYPE”,為了向后兼容,我建議使用HTML5的聲明模式:
<!DOCTYPE HTML> <html lang="en-US">
如果想了解更多這方面的知識,可以點擊:
在每個頁面的開始中,我們都在<head>中設置了字符集,我們這里都是使用“UTF-8”
<meta charset="UTF-8" />
而且我們在平時寫頁面中時,時常會碰到"&"這樣的符號,那么我們不應該直接在頁面這樣寫“&”:
我們應該在代碼中使用字符編碼來實現,比如說“&”我們在代碼中應該使用“&”來代替他。
如果想了解更多這方面的知識,可以點擊:
在頁面編輯中,代碼的縮進有沒有正確,他不會影響你網站的任何功能,但要是你沒有一個規范的縮進原則,讓讀你代碼的人是非常的生氣,所以說正確的代碼縮進可以增強你的代碼可讀性。標準程序的縮進應該是一個制表符(或幾個空格),形像一點的我們來看下文章開頭那張圖,或者一起來看下面展示的這張圖,你看后就知道以后自己的代碼要怎么樣書寫才讓人看了爽:
不用說,大家都喜歡下面的那種代碼吧。這只是一個人的習慣問題,不過建議從開始做好,利人利已。有關于這方面的介紹,大家還可以參考:Clean up your Web pages with HTML TIDY
頁面中寫入CSS樣式有很多種方法,有些直接將樣式放入頁面的“<head>”中,這將是一個很不好的習慣,因為這樣不僅會搞亂我們的標記,而且這些樣式只適合這一個HTML頁面。所以我們需要將CSS單獨提出,保存在外部,這樣后面的頁面也可以鏈接到這些樣式,如果你頁面需要修改,我們也只需要修改樣式文件就可以。正如下圖所示:
上面我們所說的只是樣式,其實javascript腳本也和CSS樣式是同一樣的道理。圖文并說,我最終想表達的意思是“在制作web頁面中,盡量將你的CSS樣式和javascript腳本單獨放在一個文件中,然后通過鏈接的方式引用這些文件,這樣做的最大好處是,方便你的樣式和腳本的管理與修改。”
我們在寫HTML時總是需要標簽的層級嵌套來幫我們完成HTML的書寫,但這些HTML的嵌套是有一定的規則的,如果要細說的話,我們可能要用幾個章節來描述,那么我今天這里要說的是,我們在寫HTML時不應該犯以下這樣的超級錯誤:
上圖的結構我們是常見的,比如說首頁的標題,那么我們就應該注意了,不能把“<h1>”放在“<a>”標簽中,換句話說,就是不能么塊元素和在行內元素中。上面只是一個例子,只是希望大家在平時的制作中不應該犯這樣的超級錯誤。
首先我們一起來看一個實例的截圖:
上圖明顯是一個導航菜單的制作,在上圖的實例中:有一個“div#topNav”包住了列表“ul#bigBarNavigation”,而“div”和“ul”列表都是塊元素,加上“div”此處用來包“ul”根本就沒有起到任何作用。雖然“div”的出現給我們制作web頁面帶來了極大的好處,但我們也沒有必要到處這樣的亂用,不知道大家平時有沒有注意這樣的細節呢?我是犯這樣的錯誤,如果你也有過這樣的經歷,那么從今天開始,從現在開始,我們一起努力來改正這樣的錯誤。
有關于如何正確的使用標簽,大家感興趣的話可以點擊:Divitis: what it is, and how to cure it.
這里所說的命名就是給你的頁面中相關元素定義類名或者是ID名,很多同學都有這栗的習慣,比如說有一個元素字體是紅色的,給他加上“red”,甚至布局都寫“left-sidebar”等,但是你有沒有想過,如果這個元素定義了“red”后,過幾天客戶要求使用“藍色”呢?或者又說,那時的“left-sidebar”邊欄此時不想放在左邊了,而是想放在右邊,那么這樣一來我們前面的命名可以說是一點意義都沒有了,正如下面的一個圖所示:
那么定義一個好的名就很得要了,不但自己能看懂你的代碼,而且別人也能輕松讀懂你的代碼,比如說一個好的類名和ID名“mainNav”、“subNav”、“footer”等,他能描述所包含的事情。不好的呢,比如前面所說的。
如果想了解更多這方面的知識,可以點擊:
我們在設計菜單時,有時要求所有菜單選項的文本全部大寫,大家平時是不是直接在HTML標簽中就將他們設置成大寫狀態呢?如果是的話,我覺得不好,如果為了將來具有更好的擴展性,我們不應該在HTML就將他們設置為全部大寫,更好的解決方法是通過CSS來實現:
大家平時制作web頁面時不知道有沒有碰到這樣的問題,就是整站下來,使用了相同的布局和結構,換句話說,你在頁面的布局上使用了相同的結構,相同的類名,但是突然你的上級主管說應客戶的需求,有一個頁面的布局需要邊欄和主內容對換一下。此時你又不想為了改變一下布局而修改整個頁面的結構,此時有一個很好的解決辦法,就是在你的這個頁面中的“<body>”中定義一個特殊的類名或ID名,這樣來你就可以輕松的達到你所要的需求。這樣的使用,不知道大家使用過沒有:
給“<body>”定義獨特的類和ID名稱是非常強大的,不僅僅是為了像上面一樣幫你改變布局,最主要的是有時他能幫你實現頁面中的某一部分達到特殊效果,而又不影響其它頁面的效果。為什么有這樣的功能,不用我說我想大家都是知道的。因為每個頁面的內容都是“<body>”的后代元素。
如果想了解更多這方面的知識,可以點擊:
人不免會出錯,我們編寫代碼的時候也是一樣的,你有時候總會小寫或多寫,比如說忘了關閉你的元素標簽,不記得寫上元素必須的屬性,雖然有一些錯誤不會給你帶來什么災難性的后果,但也不免會給你帶來你無法意估的錯誤。所以建議您寫完代碼的時候去驗證你一下你的代碼。驗證后的代碼總是比不驗證的代碼強:
為一有效的驗證你的代碼,我們可以使用相關的工具或者瀏覽器的插件來幫助我們完成。如果你的代碼沒有任何錯誤,W3C驗證工具會在你們面前呈現綠色的文字,這樣讓你是無比的激動人心,因為再次證明了你寫的代碼經得起W3C的標準。
如果想了解更多這方面的知識,可以點擊:
這是一個很少見的錯誤情況,因為我想大家寫頁面都不會把邏輯順序打亂,換句話說,如果可能的話,讓你的網站具有一個先后邏輯順序是最好的,比如說先寫頁頭,在寫頁體,最后寫頁腳。當然有時也會碰到特殊情況,如何頁腳部分在于我們代碼的邊欄以上,這可能是因為它最適合你的網站設計需求,這樣或許是可以理解的,但是如果你有別的方式實現,我們都應該把頁腳是放在一個頁面的最后,然后在通過特定的技術讓它達到你的設計需求:
上面我們一起討論了多個如何讓你開始寫一個整潔的HTML代碼。從一個項目的開始,這一切都是非常容易的,但是如果需要你去修復一個現有的代碼,那多少都會有一定的難度。上面說這么多主要是告訴您將要如何學習編寫一個良好的、整潔的HTML代碼,并且一直堅持這樣的編寫。希望讀完這篇文章垢,在你的下一個項目中,你能從頭開始,堅持寫一個整潔的HTML代碼。希望大家喜歡這樣的教程。最后在結束此教程之前,讓我們大家一起來感謝Chris Coyier給我們帶來這么好的經驗之談——《12 Principles For Keeping Your Code Clean》如果你有什么好的經驗,希望與我們一起分享。