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

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

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

    如何學(xué)好java

    如何學(xué)好java,其實(shí)很簡(jiǎn)單,只要用心體會(huì),慢慢積累!
    posts - 106, comments - 7, trackbacks - 0, articles - 3
      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

    1.列出至少有一個(gè)員工的所有部門。(兩個(gè)表聯(lián)合查詢,及group by...having的用法)
    select dname from dept where deptno in(select deptno from emp group by deptno having count(*)>1);

    2.列出薪金比“SMITH”多的所有員工。(經(jīng)典的自連接查詢)
    select ename from emp where sal>(select sal from emp where ename like'SMITH');

    3.列出所有員工的姓名及其直接上級(jí)的姓名。(多次對(duì)自己查詢,為表的取個(gè)別名,內(nèi)部查詢可以像對(duì)象一樣引用外部的對(duì)象的字段,這里引用與編程中的作用域相似,即與{}類比)

    select ename,(select ename from emp where empno in(a.mgr)) from emp a ;

    4.列出受雇日期早于其直接上級(jí)的所有員工。(同上,日期可直接拿來比較)

    select ename from emp a where HIREDATE<(select HIREDATE from emp where empno in(a.mgr));

    5.列出部門名稱和這些部門的員工信息,同時(shí)列出那些沒有員工的部門(以emp表為主,左連接查詢)

    select dname,emp.* from dept left join emp on dept.deptno=emp.deptno;

    6.列出所有“CLERK”(辦事員)的姓名及其部門名稱。(域,注意())

    select ename,(select dname from dept where deptno in(a.deptno)) as dname from emp a where JOB like'CLERK';

    7.列出最低薪金大于1500的各種工作。
    select job from emp where sal>1500;

    8.列出在部門“SALES”(銷售部)工作的員工的姓名,假定不知道銷售部的部門編號(hào)。(經(jīng)典的兩個(gè)表連接)

    select ename from emp where deptno=(select deptno from dept where dname like'SALES');

    9.列出薪金高于公司平均薪金的所有員工。(反復(fù)查自己)

    select ename from emp where sal>( select avg( sal) from emp);

    10.列出與“SCOTT”從事相同工作的所有員工。(排除自己)

    select ename from emp where job in(select job from emp where ename like'SCOTT') and ename!='SCOTT' ;

    11.列出薪金等于部門30中員工的薪金的所有員工的姓名和薪金。(any的用法,且排擠)

    select ename,sal from emp where sal=any(select sal from emp wheredeptno=30) and deptno!=30;

    12.列出薪金高于在部門30工作的所有員工的薪金的員工姓名和薪金。(max的用法)

    select sal,ename from emp where sal>(select max(sal) from emp where deptno=30);


    13.列出在每個(gè)(每個(gè)是關(guān)鍵字,對(duì)此group by)部門工作的員工數(shù)量、平均工資和平均服務(wù)期限。(經(jīng)典的group by用法)

    select deptno,count(*),avg(a.sal),avg(sysdate-HIREDATE) from emp a group by deptno;

    14.列出所有員工的姓名、部門名稱和工資.(經(jīng)典的兩個(gè)表的連接查詢,用具體的名稱替換一個(gè)表中的主鍵的id (解決很多人在實(shí)際運(yùn)用中會(huì)遇到的不能綁定多列的問題),也可用where來查詢 ,與題5比較)

    select ename,sal,(select dname from dept a where a.deptno=b.deptno)as dname from emp b;

    15.列出所有部門的詳細(xì)信息和部門人數(shù)。(因?yàn)槭?,將顯示dept和后面臨時(shí)表b的全部字段(注意:不只是dept的字段,注意*號(hào)))

    select * from dept a left join (select deptno,count(*) from emp group by deptno) b on a.deptno=b.deptno ;

    16.列出各種(與每個(gè)同義(參看題13))工作的最低工資。

    select job,min(sal) from emp group by job ;


    17.列出各個(gè)部門的MANAGER(經(jīng)理,經(jīng)理唯一,不用group by)的最低薪金。

    select min(sal) from emp where job like'MANAGER';(因?yàn)镸ANAGER是值不是字段,所以不能用小寫)

    18.列出所有員工的年工資,按年薪從低到高排序。(nvl:空轉(zhuǎn)化函數(shù))

    select ename,sal+nvl(comm,0) as sal from emp order by sal ;

    posted @ 2011-05-28 16:33 哈希 閱讀(173) | 評(píng)論 (0)編輯 收藏

    簡(jiǎn)單的說:

    struts 控制用的

    hibernate 操作數(shù)據(jù)庫的

    spring 用解耦的

    詳細(xì)的說:

    STRUTS 在 SSH 框架中起控制的作用 , 其核心是 Controller, 即 ActionServlet, 而 ActionServlet 的核心就是 Struts-confi g.xml. 主要控制邏輯關(guān)系的處理 .

    hibernate 是數(shù)據(jù)持久化層 , 是一種新的對(duì)象、關(guān)系的映射工具 , 提供了從 Java 類到數(shù)據(jù)表的映射,也提供了數(shù)據(jù)查詢和恢復(fù)等機(jī)制 , 大大減少數(shù)據(jù)訪問的復(fù)雜度。把對(duì)數(shù)據(jù)庫的直接操作 , 轉(zhuǎn)換為對(duì)持久對(duì)象的操作 .

    SPRING 是一個(gè)輕量級(jí)的控制反轉(zhuǎn) (IoC) 和面向切面 (AOP) 的容器框架 , 面向接口的編程 , 由容器控制程序之間的(依賴)關(guān)系,而非傳統(tǒng)實(shí)現(xiàn)中,由程序代碼直接操控。這也就是所謂 “ 控制反轉(zhuǎn) ” 的概念所在:(依賴)控制權(quán)由應(yīng)用代碼中轉(zhuǎn)到了外部容器,控制權(quán)的轉(zhuǎn)移,是所謂反轉(zhuǎn)。依賴注入,即組件之間的依賴關(guān)系由容器在運(yùn)行期決定,形象的來說,即由容器動(dòng)態(tài)的將某種依賴關(guān)系注入到組件之中

    起到的主要作用是解耦

    Struts 、 spring 、 Hibernate 在各層的作用

    1 ) struts 負(fù)責(zé) web 層 .

    ActionFormBean 接收網(wǎng)頁中表單提交的數(shù)據(jù),然后通過 Action 進(jìn)行處理,再 Forward 到對(duì)應(yīng)的網(wǎng)頁。

    在 struts-config.xml 中定義 <action-mapping>, ActionServlet 會(huì)加載。

    2 ) spring 負(fù)責(zé)業(yè)務(wù)層管理,即 Service (或 Manager).

    1 . service 為 action 提供統(tǒng)計(jì)的調(diào)用接口,封裝持久層的 DAO.

    2 .可以寫一些自己的業(yè)務(wù)方法。

    3 .統(tǒng)一的 javabean 管理方法

    4 .聲明式事務(wù)管理(http://www.cnblogs.com/rushoooooo/archive/2011/08/28/2155960.html

    5. 集成 Hiberante

    3 ) Hiberante ,負(fù)責(zé)持久化層,完成數(shù)據(jù)庫的 crud 操作

    hibernate 為持久層,提供 OR/Mapping 。

    它有一組 .hbm.xml 文件和 POJO, 是跟數(shù)據(jù)庫中的表相對(duì)應(yīng)的。然后定義 DAO ,這些是跟數(shù)據(jù)庫打交道的類,它們會(huì)使用 PO 。

    在 struts+spring+hibernate 的系統(tǒng)中,

    對(duì)象的調(diào)用流程是: jsp-> Action - > Service ->DAO ->Hibernate 。

    數(shù)據(jù)的流向是 ActionFormBean 接受用戶的數(shù)據(jù), Action 將數(shù)據(jù)從 ActionFromBean 中取出,封裝成 VO 或 PO,

    再調(diào)用業(yè)務(wù)層的 Bean 類,完成各種業(yè)務(wù)處理后再 forward 。而業(yè)務(wù)層 Bean 收到這個(gè) PO 對(duì)象之后,會(huì)調(diào)用 DAO 接口方法,進(jìn)行持久化操作。

     

     

     

    spring:Aop管理事務(wù)控制,IoC管理各個(gè)組件的耦合,DaoTemplate作為常規(guī)持久層的快速開發(fā)模板!

    struts:控制層Action,頁面標(biāo)簽和Model數(shù)據(jù),調(diào)用業(yè)務(wù)層

    Hibernate:負(fù)責(zé)數(shù)據(jù)庫和對(duì)象的映射,負(fù)責(zé)DAO層(Data Access Object:數(shù)據(jù)訪問)

     

    spring整合hibernate和struts,只要在配好了applicationContext.xml,在struts的action中直接調(diào)用就可以了。hibernate訪問數(shù)據(jù)庫的操作都在spring中實(shí)現(xiàn)了,spring的調(diào)用又在stuts的action中實(shí)現(xiàn)了。這個(gè)ssh框架就連到了一起……

     

     

    1 SSH在開發(fā)中的位置

    現(xiàn)在J2EE的開源框架多的數(shù)不清楚,目前(已經(jīng)、正在)比較流行的常用框架大概有struts,spring,hibernate,jsf,webwork,而 struts+spring+hibernate(SSH)這種輕量級(jí)架構(gòu)被譽(yù)為“黃金組合”。spring和hibernate更是被許多人認(rèn)為是未來五年內(nèi)不會(huì)被淘汰的技術(shù),猶如當(dāng)年的struts,今天的開發(fā)中依然被廣泛采用。

    2 為什么使用SSH  

    其實(shí),就算用Java建造一個(gè)不是很煩瑣的web應(yīng)用,也不是件輕松的事情。 在構(gòu)架的一開始就有很多事情要考慮。從高處看,擺在開發(fā)者面前有很多問題:要考慮是怎樣建立用戶接口?在哪里處理業(yè)務(wù)邏輯? 怎樣持久化的數(shù)據(jù)。 而這三層構(gòu)架中,每一層都有他們要仔細(xì)考慮的。 各個(gè)層該使用什么技術(shù)?怎樣的設(shè)計(jì)能松散耦合還能靈活改變? 怎樣替換某個(gè)層而不影響整體構(gòu)架?應(yīng)用程序如何做各種級(jí)別的業(yè)務(wù)處理(比如事務(wù)處理)?

        構(gòu)架一個(gè)Web應(yīng)用需要弄明白好多問題。 幸運(yùn)的是,已經(jīng)有不少開發(fā)者已經(jīng)遇到過這類問題,并且建立了處理這類問題的框架。 一個(gè)好框架具備以下幾點(diǎn):減輕開發(fā)者處理復(fù)雜的問題的負(fù)擔(dān)("不重復(fù)發(fā)明輪子");內(nèi)部有良好的擴(kuò)展; 并且有一個(gè)支持它的強(qiáng)大的用戶團(tuán)體。 好的構(gòu)架一般有針對(duì)性的處理某一類問題,并且能將它做好(Do One Thing well)。 然而,你的程序中有幾個(gè)層可能需要使用特定的框架,已經(jīng)完成的UI(用戶接口) 并不代表你也可以把你的業(yè)務(wù)邏輯和持久邏輯偶合到你的UI部分。 舉個(gè)例子,你不該在一個(gè)Controller(控制器)里面寫JDBC代碼作為你的業(yè)務(wù)邏輯, 這不是控制器應(yīng)該提供的。 一個(gè)UI 控制器應(yīng)該委派給其它給在UI范圍之外的輕量級(jí)組件。 好的框架應(yīng)該能指導(dǎo)代碼如何分布。 更重要的是,框架能把開發(fā)者從編碼中解放出來,使他們能專心于應(yīng)用程序的邏輯(這對(duì)客戶來說很重要)。 

    他們里面有很我優(yōu)秀的設(shè)計(jì)理念及模式應(yīng)用。比如, struts屬于MVC框架,關(guān)鍵是要了解MVC的概念及大致原理,掌握就很容易了;而hibernate屬于orm系統(tǒng),屬于持久層的解決方案,同樣需要對(duì)ORM的概念及原理有一個(gè)總體的了解,必要時(shí)可以去查查EJB1及EJB2里面用于持久層的Entity Bean的使用。而spring屬于應(yīng)用程序框架,其核心是IOC容器以及AOP,把這兩個(gè)核心概念(也可稱為大模式)了解以后,再加上一定的內(nèi)力修為,其它就都不難了。Spring中還集成了很多適用東西(不過這些東西80%的在某一個(gè)項(xiàng)目中可能一直用不上),比如對(duì)JDBC的封裝、自己的MVC、對(duì)動(dòng)態(tài)語言的簡(jiǎn)潔訪問等,這些你根據(jù)自己的項(xiàng)目情況來選擇學(xué)習(xí),用到的時(shí)候再看看他的文檔,一個(gè)項(xiàng)目下來應(yīng)該就能把握。

    3 對(duì)于SSH的理解

    在SSH框架中,struts用來解決MVC中顯示、請(qǐng)求控制部分,spring主要負(fù)責(zé)訪問數(shù)據(jù)庫DAO類的事務(wù)控制以及它被人稱譽(yù)的IOC思想在業(yè)務(wù)類中的恰當(dāng)運(yùn)用,hibernate主要是充當(dāng)數(shù)據(jù)訪問層組件。由于spring對(duì)hibernate的良好支持,在DAO類主要由spring來完成,hibernate更多關(guān)注的應(yīng)是O/R影射文件上的配置,如級(jí)聯(lián)關(guān)系,延遲加載等如何設(shè)置才能使效率更高。見圖1 (框架組合示意圖)

    4 收獲和問題

    4.1 actionform,PO,VO三對(duì)象的運(yùn)用

    討論最多的是actionform,PO,VO三對(duì)象的運(yùn)用,本人傾向的觀點(diǎn)是:在SSH框架中,PO和VO可以不必區(qū)分,即業(yè)務(wù)層和持久層都可以使用hibernate產(chǎn)生的PO對(duì)象,我暫時(shí)把對(duì)象分成actionform和po兩種來分析,action 應(yīng)該是actionform和po的分界點(diǎn),po不能穿透業(yè)務(wù)層,突破action到達(dá)頁面顯示層,同樣actionform也不能突破action傳到后臺(tái)業(yè)務(wù)、持久層。(原因:po是持久對(duì)象,到達(dá)頁面后就脫離了session成為無狀態(tài)(暫理解為脫管態(tài))的對(duì)象,而hibernate的持久對(duì)象是有狀態(tài)(包含數(shù)據(jù)庫主鍵)的,無狀態(tài)的對(duì)象傳到后臺(tái)在調(diào)用hibernate的保存方法時(shí)會(huì)出錯(cuò),一定要把無狀態(tài)的對(duì)象先轉(zhuǎn)化成持久態(tài)對(duì)象才能保存)在action中應(yīng)該對(duì)兩對(duì)象進(jìn)行轉(zhuǎn)化,轉(zhuǎn)化的方法目前我還沒發(fā)現(xiàn)有什么非常好的方法(歡迎高手不惜賜教),最普通的就是用get(),set()方法,也可以使用struts提供的屬性復(fù)制方法BeanUtils類,但這個(gè)好象只支持單個(gè)類的轉(zhuǎn)化,對(duì)于集合對(duì)象不行,需要我們自己擴(kuò)展。

    4.2 spring事務(wù)管理

    在配置spring的事務(wù)管理中,最好把事務(wù)控制配置在業(yè)務(wù)類上,而不要配置在DAO類(需要保證多個(gè)原子事務(wù)操作同時(shí)失敗回滾時(shí)這是一種解決辦法);

    4.3 action如何獲取業(yè)務(wù)類

    action中如何獲取業(yè)務(wù)類:寫一個(gè)父類action,在父類中通過spring的webapplicationcontent獲得業(yè)務(wù)類的實(shí)例。struts中的具體action繼承該父類,通過調(diào)用父類的getService()直接獲得業(yè)務(wù)類的實(shí)例。

    4.4 理解AOP思想

    深入理解AOP思想,我暫時(shí)感覺到的就是盡量面向接口編程,不管是域?qū)ο筮€是業(yè)務(wù)類或者是DAO類都設(shè)計(jì)出接口,在各方法中我們盡量傳入對(duì)象的接口,這對(duì)我們重用這些方法,擴(kuò)展是很有好處的。

    4.5 分頁處理 level

    5 系統(tǒng)包劃分

    posted @ 2011-05-20 17:00 哈希 閱讀(314) | 評(píng)論 (0)編輯 收藏

         摘要: Eclipse快速上手Hibernate--1. 入門實(shí)例 < language="javascript" type="text/javascript">document.title="Eclipse快速上手Hibernate--1. 入門實(shí)例 - "+document.title     這篇文章主要談?wù)凥ibernate的入門開發(fā),例子很簡(jiǎn)單,就是...  閱讀全文

    posted @ 2011-05-20 15:30 哈希 閱讀(158) | 評(píng)論 (0)編輯 收藏

         摘要: 這篇文章將教你快速地上手使用 Spring 框架. 如果你手上有一本《Spring in Action》, 那么你最好從第三部分"Spring 在 Web 層的應(yīng)用--建立 Web 層"開始看, 否則那將是一場(chǎng)惡夢(mèng)! 首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 應(yīng)用程序接收到 http://localhost:8080/...  閱讀全文

    posted @ 2011-05-17 22:23 哈希 閱讀(247) | 評(píng)論 (0)編輯 收藏

    所用數(shù)據(jù):
    SELECT a.deptno, a.employename, a.salary
      FROM t_salary a

    000001         李可                              1000
    000001         李強(qiáng)                              2000
    000001         楊彥軍                            4000
    000002         童家道                            3000
    000002         姜文                              3000
    000002         羅文                              3000
    000003         窨嫡                              3000
    000003         童家道                            3000
    000003         童家道                            3000
    000004         于名                              4000
    SELECT A.deptno, A.employename,A.salary,
    --1 按照名稱進(jìn)行分區(qū),同時(shí)按照名稱進(jìn)行合計(jì) 
    SUM(A.salary)OVER(PARTITION BY A.employename) AS SUM_INC_ONLY,
    --2 按照名稱進(jìn)行累計(jì) 
    SUM(A.salary)OVER(ORDER BY A.employename) AS SUM_INC,
    --3   和 1 效果相同 
    SUM(A.salary)OVER(PARTITION BY A.employename ORDER BY A.employename) AS SUM_INC_NAME,
    --4 按照部門分組,部門內(nèi)進(jìn)行合計(jì)。名稱相同時(shí)進(jìn)行累計(jì) 
    SUM(A.salary)OVER(PARTITION BY A.deptno ORDER BY A.employename) AS SUM_INC_DEP,
    --5 按照部門,名稱分組,部門名稱相同時(shí)進(jìn)行合計(jì) 
    SUM(A.salary)OVER(PARTITION BY A.deptno,A.employename ) AS SUM_INC_DEP_NAM
    FROM t_salary A


    所得結(jié)果:
    DEPTNO     EMPLOYENAME     SALARY     SUM_INC_ONLY     SUM_INC     SUM_INC_NAME     SUM_INC_DEP     SUM_INC_DEP_NAM
    000002     姜文    3000    3000    3000    3000    3000    3000
    000001     李可    1000    1000    4000    1000    1000    1000
    000001     李強(qiáng)    2000    2000    6000    2000    3000    2000
    000002     羅文    3000    3000    9000    3000    6000    3000
    000002     童家道    3000    9000    18000    9000    9000    3000
    000003     童家道    3000    9000    18000    9000    6000    6000
    000003     童家道    3000    9000    18000    9000    6000    6000
    000001     楊彥軍    4000    4000    22000    4000    7000    4000
    000004     于名    4000    4000    26000    4000    4000    4000
    000003     窨嫡    3000    3000    29000    3000    9000    3000

    posted @ 2011-05-13 17:01 哈希 閱讀(172) | 評(píng)論 (0)編輯 收藏

    緩存是位于應(yīng)用程序與物理數(shù)據(jù)源之間,用于臨時(shí)存放復(fù)制數(shù)據(jù)的內(nèi)存區(qū)域,目的是為了減少應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源訪問的次數(shù),從而提高應(yīng)用程序的運(yùn)行性能.
      Hibernate在查詢數(shù)據(jù)時(shí),首先到緩存中去查找,如果找到就直接使用,找不到的時(shí)候就會(huì)從物理數(shù)據(jù)源中檢索,所以,把頻繁使用的數(shù)據(jù)加載到緩存區(qū)后,就可以大大減少應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源的訪問,使得程序的運(yùn)行性能明顯的提升.

     
    Hibernate緩存分類:

    Session緩存,一級(jí)緩存.

    SessionFactory的緩存分為內(nèi)置緩存和外置緩存.內(nèi)置緩存中存放的是SessionFactory對(duì)象的一些集合屬性包含的數(shù)據(jù)(映射元素?fù)?jù) 及預(yù)定義SQL語句等),對(duì)于應(yīng)用程序來說,它是只讀的.外置緩存中存放的是數(shù)據(jù)庫數(shù)據(jù)的副本,其作用和一級(jí)緩存類似.二級(jí)緩存除了以內(nèi)存作為存儲(chǔ)介質(zhì) 外,還可以選用硬盤等外部存儲(chǔ)設(shè)備.

    Hibernate的緩存范圍

    Hibernate的一級(jí)緩存和二級(jí)緩存都位于均位于持久層,且均用于存放數(shù)據(jù)庫數(shù)據(jù)的副本,最大的區(qū)別就是緩存的范圍各不一樣.

    緩存的范圍分為3類:

    1.事務(wù)范圍
       事務(wù)范圍的緩存只能被當(dāng)前事務(wù)訪問,每個(gè)事務(wù)都有各自的緩存,緩存內(nèi)的數(shù)據(jù)通常采用相互關(guān)聯(lián)的對(duì)象形式.緩存的生命周期依賴于事務(wù)的生命周期,只有當(dāng)事務(wù)結(jié)束時(shí),緩存的生命周期才會(huì)結(jié)束.事務(wù)范圍的緩存使用內(nèi)存作為存儲(chǔ)介質(zhì),一級(jí)緩存就屬于事務(wù)范圍.
    2.應(yīng)用范圍
       應(yīng)用程序的緩存可以被應(yīng)用范圍內(nèi)的所有事務(wù)共享訪問.緩存的生命周期依賴于應(yīng)用的生命周期,只有當(dāng)應(yīng)用結(jié)束時(shí),緩存的生命周期才會(huì)結(jié)束.應(yīng)用范圍的緩存可以使用內(nèi)存或硬盤作為存儲(chǔ)介質(zhì),二級(jí)緩存就屬于應(yīng)用范圍.
    3.集群范圍
       在集群環(huán)境中,緩存被一個(gè)機(jī)器或多個(gè)機(jī)器的進(jìn)程共享,緩存中的數(shù)據(jù)被復(fù)制到集群環(huán)境中的每個(gè)進(jìn)程節(jié)點(diǎn),進(jìn)程間通過遠(yuǎn)程通信來保證緩存中的數(shù)據(jù)的一致,緩存中的數(shù)據(jù)通常采用對(duì)象的松散數(shù)據(jù)形式.

      Hibernate的緩存管理

    一級(jí)緩存的管理:

      evit(Object obj)  將指定的持久化對(duì)象從一級(jí)緩存中清除,釋放對(duì)象所占用的內(nèi)存資源,指定對(duì)象從持久化狀態(tài)變?yōu)槊摴軤顟B(tài),從而成為游離對(duì)象.
      clear()  將一級(jí)緩存中的所有持久化對(duì)象清除,釋放其占用的內(nèi)存資源
      contains(Object obj) 判斷指定的對(duì)象是否存在于一級(jí)緩存中.
      flush() 刷新一級(jí)緩存區(qū)的內(nèi)容,使之與數(shù)據(jù)庫數(shù)據(jù)保持同步.

      二級(jí)緩存的管理:
      
       evict(Class arg0, Serializable arg1)  將某個(gè)類的指定ID的持久化對(duì)象從二級(jí)緩存中清除,釋放對(duì)象所占用的資源.
      
    Java代碼  收藏代碼
    1. sessionFactory.evict(Customer.class, new Integer(1));  

       evict(Class arg0)  將指定類的所有持久化對(duì)象從二級(jí)緩存中清除,釋放其占用的內(nèi)存資源.
      
    Java代碼  收藏代碼
    1. sessionFactory.evict(Customer.class);  

       evictCollection(String arg0)  將指定類的所有持久化對(duì)象的指定集合從二級(jí)緩存中清除,釋放其占用的內(nèi)存資源.
      
    Java代碼  收藏代碼
    1. sessionFactory.evictCollection("Customer.orders");  


    Hibernate的二級(jí)緩存的配置

    首先,不是所有的數(shù)據(jù)都適合放在二級(jí)緩存中,看一下,什么樣的數(shù)據(jù)適合放在二級(jí)緩存中來?什么樣的數(shù)據(jù)不適合放在二級(jí)緩存中來?
      下面這幾種情況就不適合加載到二級(jí)緩存中:
      1.經(jīng)常被修改的數(shù)據(jù)
      2.絕對(duì)不允許出現(xiàn)并發(fā)訪問的數(shù)據(jù)
      3.與其他應(yīng)用共享的數(shù)據(jù)
      下面這己種情況合適加載到二級(jí)緩存中:
      1.數(shù)據(jù)更新頻率低
      2.允許偶爾出現(xiàn)并發(fā)問題的非重要數(shù)據(jù)
      3.不會(huì)被并發(fā)訪問的數(shù)據(jù)
      4.常量數(shù)據(jù)
      5.不會(huì)被第三方修改的數(shù)據(jù)

    Hibernate的二級(jí)緩存功能是靠配置二級(jí)緩存插件來實(shí)現(xiàn)的,Hibernate為了集成這些插件,Hibernate提供了org.hibernate.cache.CacheProvider借口,它充當(dāng)緩存插件與Hibernate之間的適配器 .

    常用的二級(jí)緩存插件
    EHCache  org.hibernate.cache.EhCacheProvider
    OSCache  org.hibernate.cache.OSCacheProvider
    SwarmCahe  org.hibernate.cache.SwarmCacheProvider
    JBossCache  org.hibernate.cache.TreeCacheProvider

    簡(jiǎn)單介紹一下EHCache的配置
    hibernate.cfg.xml
    Xml代碼  收藏代碼
    1. <hibernate-configuration>  
    2.    <session-factory>  
    3.       <!-- 設(shè)置二級(jí)緩存插件EHCache的Provider類-->  
    4.       <property name="hibernate.cache.provider_class">  
    5.          org.hibernate.cache.EhCacheProvider  
    6.       </property>  
    7.       <!-- 啟動(dòng)"查詢緩存" -->  
    8.       <property name="hibernate.cache.use_query_cache">  
    9.          true  
    10.       </property>  
    11.    </session-factory>  
    12.  </hibernate-configuration>  


    ehcache.xml

    Xml代碼  收藏代碼
    1. <ehcache>  
    2.   <!-- maxElementsInMemory為緩存對(duì)象的最大數(shù)目, eternal設(shè)置是否永遠(yuǎn)不過期,timeToIdleSeconds對(duì)象處于空閑狀態(tài)的最多秒數(shù),timeToLiveSeconds對(duì)象處于緩存狀態(tài)的最多秒數(shù) -->  
    3.   <diskStore path="java.io.tmpdir"/>  
    4.     <defaultCache maxElementsInMemory="10000" eternal="false"  timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true"/>  
    5. </ehcache>  


    ****.hbm.xml

    Xml代碼  收藏代碼
    1. <?xml version="1.0" encoding='UTF-8'?>  
    2. <!DOCTYPE hibernate-mapping PUBLIC  
    3.                             "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    4.                             "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >  
    5.   
    6. <hibernate-mapping>  
    7.        
    8.    <class>  
    9.        <!-- 設(shè)置該持久化類的二級(jí)緩存并發(fā)訪問策略 read-only read-write nonstrict-read-write transactional-->  
    10.        <cache usage="read-write"/>      
    11.    </class>  
    12.   
    13. </hibernate-mapping>  


    最近用上了,看看了,有什么不妥的地方,多謝指出.

    posted @ 2011-05-10 18:03 哈希 閱讀(192) | 評(píng)論 (0)編輯 收藏

    1.關(guān)于spring ioc

    這段時(shí)間也著實(shí)好好的看了下spring的相關(guān)書籍,對(duì)其也有了大概和初步的認(rèn)識(shí)和理解,雖然之前也一直聽說spring是一個(gè)非常優(yōu)秀的開源 框架,可一直沒有機(jī)會(huì)學(xué)習(xí)和使用(是不是有點(diǎn)落伍了?呵呵),所以呢,這段時(shí)間就重點(diǎn)學(xué)習(xí)了spring(一個(gè)星期的時(shí)間當(dāng)然是入門級(jí)的啦~~)

    大家一直都說spring的IOC如何如何的強(qiáng)大,其實(shí)我倒覺得不是IOC如何的強(qiáng)大,說白了IOC其實(shí)也非常的簡(jiǎn)單。我們先從IOC說起, 這個(gè)概念其實(shí)是從我們平常new一個(gè)對(duì)象的對(duì)立面來說的,我們平常使用對(duì)象的時(shí)候,一般都是直接使用關(guān)鍵字類new一個(gè)對(duì)象,那這樣有什么壞處呢?其實(shí)很 顯然的,使用new那么就表示當(dāng)前模塊已經(jīng)不知不覺的和new的對(duì)象耦合了,而我們通常都是更高層次的抽象模塊調(diào)用底層的實(shí)現(xiàn)模塊,這樣也就產(chǎn)生了模塊依 賴于具體的實(shí)現(xiàn),這樣與我們JAVA中提倡的面向接口面向抽象編程是相沖突的,而且這樣做也帶來系統(tǒng)的模塊架構(gòu)問題。很簡(jiǎn)單的例子,我們?cè)谶M(jìn)行數(shù)據(jù)庫操作 的時(shí)候,總是業(yè)務(wù)層調(diào)用DAO層,當(dāng)然我們的DAO一般都是會(huì)采用接口開發(fā),這在一定程度上滿足了松耦合,使業(yè)務(wù)邏輯層不依賴于具體的數(shù)據(jù)庫DAO層。但 是我們?cè)谑褂玫臅r(shí)候還是會(huì)new一個(gè)特定數(shù)據(jù)庫的DAO層,這無形中也與特定的數(shù)據(jù)庫綁定了,雖然我們可以使用抽象工廠模式來獲取DAO實(shí)現(xiàn)類,但除非我 們一次性把所有數(shù)據(jù)庫的DAO寫出來,否則在進(jìn)行數(shù)據(jù)庫遷移的時(shí)候我們還是得修改DAO工廠類。

    那我們使用IOC能達(dá)到什么呢?IOC,就是DAO接口的實(shí)現(xiàn)不再是業(yè)務(wù)邏輯層調(diào)用工廠類去獲取,而是通過容器(比如spring)來自動(dòng)的 為我們的業(yè)務(wù)層設(shè)置DAO的實(shí)現(xiàn)類。這樣整個(gè)過程就反過來,以前是我們業(yè)務(wù)層主動(dòng)去獲取DAO,而現(xiàn)在是DAO主動(dòng)被設(shè)置到業(yè)務(wù)邏輯層中來了,這也就是反 轉(zhuǎn)控制的由來。通過IOC,我們就可以在不修改任何代碼的情況下,無縫的實(shí)現(xiàn)數(shù)據(jù)庫的換庫遷移,當(dāng)然前提還是必須得寫一個(gè)實(shí)現(xiàn)特定數(shù)據(jù)庫的DAO。我們把 DAO普遍到更多的情況下,那么IOC就為我們帶來更大的方便性,比如一個(gè)接口的多個(gè)實(shí)現(xiàn),我們只需要配置一下就ok了,而不需要再一個(gè)個(gè)的寫工廠來來獲 取了。這就是IOC為我們帶來的模塊的松耦合和應(yīng)用的便利性。

    那為什么說IOC很簡(jiǎn)單呢?說白了其實(shí)就是由我們平常的new轉(zhuǎn)成了使用反射來獲取類的實(shí)例,相信任何人只要會(huì)用java的反射機(jī)制,那么自己寫一個(gè)IOC框架也不是不可能的。比如:

    ……
    public ObjectgetInstance(String className) throws Exception
    {
    Object obj = Class.forName(className).newInstance();
    Method[] methods = obj.getClass().getMethods();
    for (Method method : methods) {
    if (method.getName().intern() == "setString") {
    method.invoke(obj, "hello world!");
    }
    }
    }
    ……

    上面的一個(gè)方法我們就很簡(jiǎn)單的使用了反射為指定的類的setString方法來設(shè)置一個(gè)hello world!字符串。其實(shí)可以看到IOC真的很簡(jiǎn)單,當(dāng)然了IOC簡(jiǎn)單并不表示spring的IOC就簡(jiǎn)單,spring的IOC的功能強(qiáng)大就在于有一系 列非常強(qiáng)大的配置文件維護(hù)類,它們可以維護(hù)spring配置文件中的各個(gè)類的關(guān)系,這才是spring的IOC真正強(qiáng)大的地方。在spring的Bean 定義文件中,不僅可以為定義Bean設(shè)置屬性,還支持Bean之間的繼承、Bean的抽象和不同的獲取方式等等功能。

    下次俺再把spring的Bean配置的相關(guān)心得和大家一起分享下,如果說的不好,大家可以提意見哦,可千萬不要仍臭雞蛋,嘿嘿~~~~


    2.關(guān)于spring aop

    反射實(shí)現(xiàn) AOP 動(dòng)態(tài)代理模式(Spring AOP 的實(shí)現(xiàn) 原理)
    好長(zhǎng)時(shí)間沒有用過Spring了. 突然拿起書.我都發(fā)現(xiàn)自己對(duì)AOP都不熟悉了.
    其實(shí)AOP的意思就是面向切面編程.
    OO注重的是我們解決問題的方法(封裝成Method),而AOP注重的是許多解決解決問題的方法中的共同點(diǎn),是對(duì)OO思想的一種補(bǔ)充!
    還是拿人家經(jīng)常舉的一個(gè)例子講解一下吧:
    比如說,我們現(xiàn)在要開發(fā)的一個(gè)應(yīng)用里面有很多的業(yè)務(wù)方法,但是,我們現(xiàn)在要對(duì)這個(gè)方法的執(zhí)行做全面監(jiān)控,或部分監(jiān)控.也許我們就會(huì)在要一些方法前去加上一條日志記錄,
    我們寫個(gè)例子看看我們最簡(jiǎn)單的解決方案
    我們先寫一個(gè)接口IHello.java代碼如下:
    1package sinosoft.dj.aop.staticaop;
    2
    3public interface IHello {
    4    /** *//**
    5     * 假設(shè)這是一個(gè)業(yè)務(wù)方法
    6     * @param name
    7     */
    8    void sayHello(String name);
    9}
    10
    里面有個(gè)方法,用于輸入"Hello" 加傳進(jìn)來的姓名;我們?nèi)憘€(gè)類實(shí)現(xiàn)IHello接口
    package sinosoft.dj.aop.staticaop;

    public class Hello implements IHello {

        public void sayHello(String name) {
            System.out.println("Hello " + name);
        }

    }

    現(xiàn)在我們要為這個(gè)業(yè)務(wù)方法加上日志記錄的業(yè)務(wù),我們?cè)诓桓淖冊(cè)a的情況下,我們會(huì)去怎么做呢?也許,你會(huì)去寫一個(gè)類去實(shí)現(xiàn)IHello接口,并依賴Hello這個(gè)類.代碼如下:
    1package sinosoft.dj.aop.staticaop;
    2
    3public class HelloProxy implements IHello {
    4    private IHello hello;
    5
    6    public HelloProxy(IHello hello) {
    7        this.hello = hello;
    8    }
    9
    10    public void sayHello(String name) {
    11        Logger.logging(Level.DEBUGE, "sayHello method start.");
    12        hello.sayHello(name);
    13        Logger.logging(Level.INFO, "sayHello method end!");
    14
    15    }
    16
    17}
    18
    其中.Logger類和Level枚舉代碼如下:
    Logger.java
    1package sinosoft.dj.aop.staticaop;
    2
    3import java.util.Date;
    4
    5public class Logger{
    6    /** *//**
    7     * 根據(jù)等級(jí)記錄日志
    8     * @param level
    9     * @param context
    10     */
    11    public static void logging(Level level, String context) {
    12        if (level.equals(Level.INFO)) {
    13            System.out.println(new Date().toLocaleString() + " " + context);
    14        }
    15        if (level.equals(Level.DEBUGE)) {
    16            System.err.println(new Date() + " " + context);
    17        }
    18    }
    19
    20}
    21Level.java

    1package sinosoft.dj.aop.staticaop;
    2
    3public enum Level {
    4    INFO,DEBUGE;
    5}
    6那我們?nèi)憘€(gè)測(cè)試類看看,代碼如下:
    Test.java
    1package sinosoft.dj.aop.staticaop;
    2
    3public class Test {
    4    public static void main(String[] args) {
    5        IHello hello = new HelloProxy(new Hello());
    6        hello.sayHello("Doublej");
    7    }
    8}
    9運(yùn)行以上代碼我們可以得到下面結(jié)果:

    Tue Mar 04 20:57:12 CST 2008 sayHello method start.
    Hello Doublej
    2008-3-4 20:57:12 sayHello method end!
    從上面的代碼我們可以看出,hello對(duì)象是被HelloProxy這個(gè)所謂的代理態(tài)所創(chuàng)建的.這樣,如果我們以后要把日志記錄的功能去掉.那我們只要把得到hello對(duì)象的代碼改成以下:
    1package sinosoft.dj.aop.staticaop;
    2
    3public class Test {
    4    public static void main(String[] args) {
    5        IHello hello = new Hello();
    6        hello.sayHello("Doublej");
    7    }
    8}
    9
    上面代碼,可以說是AOP最簡(jiǎn)單的實(shí)現(xiàn)!
    但是我們會(huì)發(fā)現(xiàn)一個(gè)問題,如果我們像Hello這樣的類很多,那么,我們是不是要去寫很多個(gè)HelloProxy這樣的類呢.沒錯(cuò),是的.其實(shí)也 是一種很麻煩的事.在jdk1.3以后.jdk跟我們提供了一個(gè)API   java.lang.reflect.InvocationHandler的類. 這個(gè)類可以讓我們?cè)贘VM調(diào)用某個(gè)類的方法時(shí)動(dòng)態(tài)的為些方法做些什么事.讓我們把以上的代碼改一下來看看效果.
    同樣,我們寫一個(gè)IHello的接口和一個(gè)Hello的實(shí)現(xiàn)類.在接口中.我們定義兩個(gè)方法;代碼如下 :

    IHello.java
    1package sinosoft.dj.aop.proxyaop;
    2
    3public interface IHello {
    4    /** *//**
    5     * 業(yè)務(wù)處理A方法
    6     * @param name
    7     */
    8    void sayHello(String name);
    9    /** *//**
    10     * 業(yè)務(wù)處理B方法
    11     * @param name
    12     */
    13    void sayGoogBye(String name);
    14}
    15

    Hello.java

    1package sinosoft.dj.aop.proxyaop;
    2
    3public class Hello implements IHello {
    4
    5    public void sayHello(String name) {
    6        System.out.println("Hello " + name);
    7    }
    8    public void sayGoogBye(String name) {
    9        System.out.println(name+" GoodBye!");
    10    }
    11}
    12
    我們一樣的去寫一個(gè)代理類.只不過.讓這個(gè)類去實(shí)現(xiàn)java.lang.reflect.InvocationHandler接口,代碼如下:
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.InvocationHandler;
    4import java.lang.reflect.Method;
    5import java.lang.reflect.Proxy;
    6
    7public class DynaProxyHello implements InvocationHandler {
    8
    9    /** *//**
    10     * 要處理的對(duì)象(也就是我們要在方法的前后加上業(yè)務(wù)邏輯的對(duì)象,如例子中的Hello)
    11     */
    12    private Object delegate;
    13
    14    /** *//**
    15     * 動(dòng)態(tài)生成方法被處理過后的對(duì)象 (寫法固定)
    16     *
    17     * @param delegate
    18     * @param proxy
    19     * @return
    20     */
    21    public Object bind(Object delegate) {
    22        this.delegate = delegate;
    23        return Proxy.newProxyInstance(
    24                this.delegate.getClass().getClassLoader(), this.delegate
    25                        .getClass().getInterfaces(), this);
    26    }
    27    /** *//**
    28     * 要處理的對(duì)象中的每個(gè)方法會(huì)被此方法送去JVM調(diào)用,也就是說,要處理的對(duì)象的方法只能通過此方法調(diào)用
    29     * 此方法是動(dòng)態(tài)的,不是手動(dòng)調(diào)用的
    30     */
    31    public Object invoke(Object proxy, Method method, Object[] args)
    32            throws Throwable {
    33        Object result = null;
    34        try {
    35            //執(zhí)行原來的方法之前記錄日志
    36            Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
    37           
    38            //JVM通過這條語句執(zhí)行原來的方法(反射機(jī)制)
    39            result = method.invoke(this.delegate, args);
    40            //執(zhí)行原來的方法之后記錄日志
    41            Logger.logging(Level.INFO, method.getName() + " Method Start!");
    42        } catch (Exception e) {
    43            e.printStackTrace();
    44        }
    45        //返回方法返回值給調(diào)用者
    46        return result;
    47    }
    48
    49}
    50
    上面類中出現(xiàn)的Logger類和Level枚舉還是和上一上例子的實(shí)現(xiàn)是一樣的.這里就不貼出代碼了.

    讓我們寫一個(gè)Test類去測(cè)試一下.代碼如下:
    Test.java
    1package sinosoft.dj.aop.proxyaop;
    2
    3public class Test {
    4    public static void main(String[] args) {
    5        IHello hello = (IHello)new DynaProxyHello().bind(new Hello());
    6        hello.sayGoogBye("Double J");
    7        hello.sayHello("Double J");
    8       
    9    }
    10}
    11
    運(yùn)行輸出的結(jié)果如下:
    Tue Mar 04 21:24:03 CST 2008 sayGoogBye Method end .
    Double J GoodBye!
    2008-3-4 21:24:03 sayGoogBye Method Start!
    Tue Mar 04 21:24:03 CST 2008 sayHello Method end .
    Hello Double J
    2008-3-4 21:24:03 sayHello Method Start!
    由于線程的關(guān)系,第二個(gè)方法的開始出現(xiàn)在第一個(gè)方法的結(jié)束之前.這不是我們所關(guān)注的!
    從上面的例子我們看出.只要你是采用面向接口編程,那么,你的任何對(duì)象的方法執(zhí)行之前要加上記錄日志的操作都是可以的.他 (DynaPoxyHello)自動(dòng)去代理執(zhí)行被代理對(duì)象(Hello)中的每一個(gè)方法,一個(gè) java.lang.reflect.InvocationHandler接口就把我們的代理對(duì)象和被代理對(duì)象解藕了.但是,我們又發(fā)現(xiàn)還有一個(gè)問題,這 個(gè)DynaPoxyHello對(duì)象只能跟我們?nèi)ピ诜椒ㄇ昂蠹由先罩居涗浀牟僮?我們能不能把DynaPoxyHello對(duì)象和日志操作對(duì)象 (Logger)解藕呢?
    結(jié)果是肯定的.讓我們來分析一下我們的需求.
    我們要在被代理對(duì)象的方法前面或者后面去加上日志操作代碼(或者是其它操作的代碼),
    那么,我們可以抽象出一個(gè)接口,這個(gè)接口里就只有兩個(gè)方法,一個(gè)是在被代理對(duì)象要執(zhí)行方法之前執(zhí)行的方法,我們?nèi)∶麨閟tart,第二個(gè)方法就是在被代理對(duì)象執(zhí)行方法之后執(zhí)行的方法,我們?nèi)∶麨閑nd .接口定義如下 :
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.Method;
    4
    5public interface IOperation {
    6    /** *//**
    7     * 方法執(zhí)行之前的操作
    8     * @param method
    9     */
    10    void start(Method method);
    11    /** *//**
    12     * 方法執(zhí)行之后的操作
    13     * @param method
    14     */
    15    void end(Method method);
    16}
    17
    我們?nèi)懸粋€(gè)實(shí)現(xiàn)上面接口的類.我們把作他真正的操作者,如下面是日志操作者的一個(gè)類:
    LoggerOperation.java
    package sinosoft.dj.aop.proxyaop;

    import java.lang.reflect.Method;

    public class LoggerOperation implements IOperation {

        public void end(Method method) {
            Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
        }

        public void start(Method method) {
            Logger.logging(Level.INFO, method.getName() + " Method Start!");
        }

    }

    然后我們要改一下代理對(duì)象DynaProxyHello中的代碼.如下:
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.InvocationHandler;
    4import java.lang.reflect.Method;
    5import java.lang.reflect.Proxy;
    6
    7public class DynaProxyHello implements InvocationHandler {
    8    /** *//**
    9     * 操作者
    10     */
    11    private Object proxy;
    12    /** *//**
    13     * 要處理的對(duì)象(也就是我們要在方法的前后加上業(yè)務(wù)邏輯的對(duì)象,如例子中的Hello)
    14     */
    15    private Object delegate;
    16
    17    /** *//**
    18     * 動(dòng)態(tài)生成方法被處理過后的對(duì)象 (寫法固定)
    19     *
    20     * @param delegate
    21     * @param proxy
    22     * @return
    23     */
    24    public Object bind(Object delegate,Object proxy) {
    25       
    26        this.proxy = proxy;
    27        this.delegate = delegate;
    28        return Proxy.newProxyInstance(
    29                this.delegate.getClass().getClassLoader(), this.delegate
    30                        .getClass().getInterfaces(), this);
    31    }
    32    /** *//**
    33     * 要處理的對(duì)象中的每個(gè)方法會(huì)被此方法送去JVM調(diào)用,也就是說,要處理的對(duì)象的方法只能通過此方法調(diào)用
    34     * 此方法是動(dòng)態(tài)的,不是手動(dòng)調(diào)用的
    35     */
    36    public Object invoke(Object proxy, Method method, Object[] args)
    37            throws Throwable {
    38        Object result = null;
    39        try {
    40            //反射得到操作者的實(shí)例
    41            Class clazz = this.proxy.getClass();
    42            //反射得到操作者的Start方法
    43            Method start = clazz.getDeclaredMethod("start",
    44                    new Class[] { Method.class });
    45            //反射執(zhí)行start方法
    46            start.invoke(this.proxy, new Object[] { method });
    47            //執(zhí)行要處理對(duì)象的原本方法
    48            result = method.invoke(this.delegate, args);
    49//            反射得到操作者的end方法
    50            Method end = clazz.getDeclaredMethod("end",
    51                    new Class[] { Method.class });
    52//            反射執(zhí)行end方法
    53            end.invoke(this.proxy, new Object[] { method });
    54
    55        } catch (Exception e) {
    56            e.printStackTrace();
    57        }
    58        return result;
    59    }
    60
    61}
    62
    然后我們把Test.java中的代碼改一下.測(cè)試一下:
    package sinosoft.dj.aop.proxyaop;

    public class Test {
        public static void main(String[] args) {
            IHello hello = (IHello)new DynaProxyHello().bind(new Hello(),new LoggerOperation());
            hello.sayGoogBye("Double J");
            hello.sayHello("Double J");
           
        }
    }
    結(jié)果還是一樣的吧.

    如果你想在每個(gè)方法之前加上日志記錄,而不在方法后加上日志記錄.你就把LoggerOperation類改成如下:
    1package sinosoft.dj.aop.proxyaop;
    2
    3import java.lang.reflect.Method;
    4
    5public class LoggerOperation implements IOperation {
    6
    7    public void end(Method method) {
    8        //Logger.logging(Level.DEBUGE, method.getName() + " Method end .");
    9    }
    10
    11    public void start(Method method) {
    12        Logger.logging(Level.INFO, method.getName() + " Method Start!");
    13    }
    14
    15}
    16
    運(yùn)行一下.你就會(huì)發(fā)現(xiàn),每個(gè)方法之后沒有記錄日志了. 這樣,我們就把代理者和操作者解藕了!

    下面留一個(gè)問題給大家,如果我們不想讓所有方法都被日志記錄,我們應(yīng)該怎么去解藕呢.?
    我的想法是在代理對(duì)象的public Object invoke(Object proxy, Method method, Object[] args)方法里面加上個(gè)if(),對(duì)傳進(jìn)來的method的名字進(jìn)行判斷,判斷的條件存在XML里面.這樣我們就可以配置文件時(shí)行解藕了.如果有興趣的 朋友可以把操作者,被代理者,都通過配置文件進(jìn)行配置 ,那么就可以寫一個(gè)簡(jiǎn)單的SpringAOP框架了.

    posted @ 2011-05-10 17:49 哈希 閱讀(338) | 評(píng)論 (0)編輯 收藏

    首先來說一下rownum與rowid含義:

    顧名思義rownum就是行數(shù)/行號(hào),而rowid就是編碼/編號(hào)/唯一識(shí)別號(hào),所以他是類似“AAAR8gAAEAAAAErAAK”的編號(hào),注意他是沒有先后順序的,也就是說他和數(shù)據(jù)入庫時(shí)間沒有任何關(guān)系,打個(gè)比方:他就像磁盤、內(nèi)存存儲(chǔ)數(shù)據(jù)用的是16進(jìn)制的地址一樣。

    他們都是偽列,可以理解成表中的一個(gè)列只是他們并不是你創(chuàng)建的。同樣是偽列區(qū)別是什么呢?

    rowid是你錄入數(shù)據(jù)時(shí)有數(shù)據(jù)庫自動(dòng)為這條記錄添加的唯一的18位編號(hào)是一個(gè)物理編號(hào)用于找到這條記錄(順便說一句這也是為什么數(shù)據(jù)優(yōu)調(diào)的時(shí)候強(qiáng) 調(diào)盡量使用rowid的原因),他是不會(huì)隨著查詢而改變的 除非在表發(fā)生移動(dòng)(比如表空間變化,數(shù)據(jù)導(dǎo)入/導(dǎo)出以后),才會(huì)發(fā)生變化。

    rownum是根據(jù)sql查詢后得到的結(jié)果自動(dòng)加上去的,但是他卻不受到sql中order by排序的影響,因?yàn)樗蛂owid的順序一樣是系統(tǒng)按照記錄插入時(shí)的順序給記錄排的號(hào)(順序的、無跳躍)。 但是如果你想讓rownum和order by一樣的順序 那么可以使用子查詢,形如:select rownum,t.* from (select * from 表空間名 order by 字段名) t  這樣的話rownum就是根據(jù)該字段進(jìn)行排序的編號(hào)了,為什么會(huì)這樣呢,本人理解:rownum是根據(jù)表記錄輸出的行號(hào),與篩選語句、排序語句都無關(guān)所以 當(dāng)用子查詢時(shí)等于生成了一個(gè)表于是就按照這張表從1開始排序了。 同樣,也可以用下面要提得到的分析函數(shù)中的row_number() over(order by 需要排序的字段名)。

      

    值得一提的是MSSQL是沒有rownum和rowid的。

    下面說說分析函數(shù)row_number()、rank()、dense_rank()

    ROW_NUMBER():
    Row_number函數(shù)返回一個(gè)唯一的值,當(dāng)碰到相同數(shù)據(jù)時(shí),排名按照記錄集中記錄的順序依次遞增。 row_number()和rownum差不多,功能更強(qiáng)一點(diǎn)(可以在各個(gè)分組內(nèi)從1開時(shí)排序),因?yàn)閞ow_number()是分析函數(shù)而rownum是偽列所以row_number()一定要over而rownum不能over。

    RANK():
    Rank函數(shù)返回一個(gè)唯一的值,除非遇到相同的數(shù)據(jù),此時(shí)所有相同數(shù)據(jù)的排名是一樣的,同時(shí)會(huì)在最后一條相同記錄和下一條不同記錄的排名之間空出排名。rank()是跳躍排序,有兩個(gè)第二名時(shí)接下來就是第四名(同樣是在各個(gè)分組內(nèi))。

    DENSE_RANK():
    Dense_rank函數(shù)返回一個(gè)唯一的值,除非當(dāng)碰到相同數(shù)據(jù),此時(shí)所有相同數(shù)據(jù)的排名都是一樣的。
    dense_rank()是連續(xù)排序,有兩個(gè)第二名時(shí)仍然跟著第三名。他和row_number的區(qū)別在于row_number是沒有重復(fù)值的。

    一,什么是偽列RowID?

    1,首先是一種數(shù)據(jù)類型,唯一標(biāo)識(shí)一條記錄物理位置的一個(gè)id,基于64位編碼的18個(gè)字符顯示。

    2,未存儲(chǔ)在表中,可以從表中查詢,但不支持插入,更新,刪除它們的值。

    二,RowID的用途

    1,在開發(fā)中使用頻率應(yīng)該是挺多的,特別在一些update語句中使用更加頻繁。所以oracle ERP中大部份的視圖都會(huì)加入rowid這個(gè)字段。

       在一些cursor定義時(shí)也少不了加入rowid。但往往我們?cè)陂_發(fā)過程中,由于連接的表很多,再加上程序的復(fù)制,有時(shí)忽略了rowid對(duì)應(yīng)的是那一個(gè)表中rowid,所以有時(shí)過程出錯(cuò),

       往往發(fā)上很多時(shí)間去查錯(cuò),最后查出來既然是update時(shí)帶的rowid并非此表的rowid,所以在發(fā)現(xiàn)很多次的錯(cuò)誤時(shí),重視r(shí)owid起來了,開發(fā)中一定要注意rowid的匹配

    2,能以做快的方式訪問表中的一行。

    3,能顯示表的行是如何存儲(chǔ)的。

    4,作為表中唯一標(biāo)識(shí)。

    三,RowID的組成

    rowid確定了每條記錄是在Oracle中的哪一個(gè)數(shù)據(jù)對(duì)象,數(shù)據(jù)文件、塊、行上。

    ROWID 的格式如下:

       數(shù)據(jù)對(duì)象編號(hào)        文件編號(hào)        塊編號(hào)            行編號(hào)

       OOOOOO             FFF                BBBBBB    RRR

       由 data_object_id# + rfile# + block# + row#   組成,占用10個(gè)bytes的空間,

        32bit的 data_object_id#,

        10 bit 的 rfile#,

        22bit 的 block#,

        16 bit 的 row#.

       所以每個(gè)表空間不能超過1023個(gè) 數(shù)據(jù)文件。

    四,RowID的應(yīng)用

    1,查找和刪除重復(fù)記錄

       當(dāng)試圖對(duì)庫表中的某一列或幾列創(chuàng)建唯一索引時(shí),

       系統(tǒng)提示 ORA-01452 :不能創(chuàng)建唯一索引,發(fā)現(xiàn)重復(fù)記錄。

        /*conn scott/tiger

        Create table empa as select * from emp;

        插入重復(fù)記錄

        insert into empa select * from emp where empno = 7369;

        insert into empa select * from emp where empno = 7839;

        insert into empa select * from emp where empno = 7934;

        */

       查找重復(fù)記錄的幾種方法:

        查找大量重復(fù)記錄

        select empno from empa group by empno having count(*) >1;

        Select * From empa Where ROWID Not In(Select Min(ROWID) From empa Group By empno);

        查找少量重復(fù)記錄

        select * from empa a where rowid<>(select max(rowid) from empa where empno=a.empno );

       刪除重復(fù)記錄的幾種方法:

        (1).適用于有大量重復(fù)記錄的情況(列上建有索引的時(shí)候,用以下語句效率會(huì)很高):

        Delete empa Where empno In (Select empno From empa Group By empno Having Count(*) > 1)

        And ROWID Not In (Select Min(ROWID) From empa Group By empno Having Count(*) > 1);

      

        Delete empa Where ROWID Not In(Select Min(ROWID) From empa Group By empno);

      

        (2).適用于有少量重復(fù)記錄的情況(注意,對(duì)于有大量重復(fù)記錄的情況,用以下語句效率會(huì)很低):

        Delete empa a where rowid<>(select max(rowid) from empa where empno=a.empno );

    ---------------------------------------------------------------------------------------------------------------------------------------------------

    注意:rownum從1開始;

               rownum按照記錄插入時(shí)的順序給記錄排序,所以有order by的子句時(shí)一定要注意啊!

               使用時(shí)rownum,order by字段是否為主鍵有什么影響?

               子查詢中rownum rn,而rn用到外查詢中到底是怎樣的序列?

                若id主鍵是按照從小到大的順序插入的,select語句沒有g(shù)roup by 和order by的子句時(shí),rownum的順序和id順序基本一致。

    對(duì)于 Oracle 的 rownum 問題,很多資料都說不支持>,>=,=,between...and,只能用以上符號(hào)(<、<=、!=),并非說用>,& gt;=,=,between..and 時(shí)會(huì)提示SQL語法錯(cuò)誤,而是經(jīng)常是查不出一條記錄來,還會(huì)出現(xiàn)似乎是莫名其妙的結(jié)果來,其實(shí)您只要理解好了這個(gè) rownum 偽列的意義就不應(yīng)該感到驚奇,同樣是偽列,rownum 與 rowid 可有些不一樣,下面以例子說明

    假設(shè)某個(gè)表 t1(c1) 有 20 條記錄

    如果用 select rownum,c1 from t1 where rownum < 10, 只要是用小于號(hào),查出來的結(jié)果很容易地與一般理解在概念上能達(dá)成一致,應(yīng)該不會(huì)有任何疑問的。

    可如果用 select rownum,c1 from t1 where rownum > 10 (如果寫下這樣的查詢語句,這時(shí)候在您的頭腦中應(yīng)該是想得到表中后面10條記錄),你就會(huì)發(fā)現(xiàn),顯示出來的結(jié)果要讓您失望了,也許您還會(huì)懷疑是不誰刪了一 些記錄,然后查看記錄數(shù),仍然是 20 條?。磕菃栴}是出在哪呢?

    先好好理解 rownum 的意義吧。因?yàn)镽OWNUM是對(duì)結(jié)果集加的一個(gè)偽列,即先查到結(jié)果集之后再加上去的一個(gè)列 (強(qiáng)調(diào):先要有結(jié)果集)。簡(jiǎn)單的說 rownum 是對(duì)符合條件結(jié)果的序列號(hào)。它總是從1開始排起的。所以你選出的結(jié)果不可能沒有1,而有其他大于1的值。所以您沒辦法期望得到下面的結(jié)果集:

    11 aaaaaaaa

    12 bbbbbbb

    13 ccccccc

    .................

    rownum >10 沒有記錄,因?yàn)榈谝粭l不滿足去掉的話,第二條的ROWNUM又成了1,所以永遠(yuǎn)沒有滿足條件的記錄。或者可以這樣理解:

    ROWNUM是一個(gè)序列,是oracle數(shù)據(jù)庫從數(shù)據(jù)文件或緩沖區(qū)中讀取數(shù)據(jù)的順序。它取得第 一條記錄則rownum值為1,第二條為2,依次類推。如果你用>,>=,=,between...and這些條件,因?yàn)閺木彌_區(qū)或數(shù)據(jù)文件 中得到的第一條記錄的rownum為1,則被刪除,接著取下條,可是它的rownum還是1,又被刪除,依次類推,便沒有了數(shù)據(jù)。

    有了以上從不同方面建立起來的對(duì) rownum 的概念,那我們可以來認(rèn)識(shí)使用 rownum 的幾種現(xiàn)像

    1. select rownum,c1 from t1 where rownum != 10 為何是返回前9條數(shù)據(jù)呢?它與 select rownum,c1 from tablename where rownum < 10 返回的結(jié)果集是一樣的呢?

          因?yàn)槭窃诓樵兊浇Y(jié)果集后,顯示完第 9 條記錄后,之后的記錄也都是 != 10,或者 >=10,所以只顯示前面9條記錄。也可以這樣理解,rownum 為9后的記錄的 rownum為10,因條件為 !=10,所以去掉,其后記錄補(bǔ)上,rownum又是10,也去掉,如果下去也就只會(huì)顯示前面9條記錄了。

    2. 為什么 rownum >1 時(shí)查不到一條記錄,而 rownum >0 或 rownum >=1 卻總顯示所有的記錄?

          因?yàn)?rownum 是在查詢到的結(jié)果集后加上去的,它總是從1開始。

    3. 為什么 between 1 and 10 或者 between 0 and 10 能查到結(jié)果,而用 between 2 and 10 卻得不到結(jié)果?

           原因同上一樣,因?yàn)?rownum 總是從 1 開始。從上可以看出,任何時(shí)候想把 rownum = 1 這條記錄拋棄是不對(duì)的,它在結(jié)果集中是不可或缺的,少了rownum=1 就像空中樓閣一般不能存在,所以你的 rownum 條件要包含到 1 。

    但如果就是想要用 rownum > 10 這種條件的話話就要用嵌套語句,把 rownum 先生成,然后對(duì)他進(jìn)行查詢。

    select *

    from (selet rownum as rn,t1.* from a where ...)

    where rn >10

    一般代碼中對(duì)結(jié)果集進(jìn)行分頁就是這么干的。

    另外:rowid 與 rownum 雖都被稱為偽列,但它們的存在方式是不一樣的,rowid 可以說是物理存在的,表示記錄在表空間中的唯一位置ID,在DB中唯一。只要記錄沒被搬動(dòng)過,rowid是不變的。rowid 相對(duì)于表來說又像表中的一般列,所以以 rowid 為條件就不會(huì)有 rownum那些情況發(fā)生。

    另外還要注意:rownum不能以任何基表的名稱作為前綴。

    對(duì)于rownum來說它是oracle系統(tǒng)順序分配為從查詢返回的行的編號(hào),返回的第一行分配的是1,第二行是2,依此類推,這個(gè)偽字段可以用于限制查詢返回的總行數(shù),且rownum不能以任何表的名稱作為前綴。

    (1) rownum 對(duì)于等于某值的查詢條件

    如果希望找到學(xué)生表中第一條學(xué)生的信息,可以使用rownum=1作為條件。但是想找到學(xué)生表 中第二條學(xué)生的信息,使用rownum=2結(jié)果查不到數(shù)據(jù)。因?yàn)閞ownum都是從1開始,但是1以上的自然數(shù)在rownum做等于判斷是時(shí)認(rèn)為都是 false條件,所以無法查到rownum = n(n>1的自然數(shù))。

    SQL> select rownum,id,name from student where rownum=1;(可以用在限制返回記錄條數(shù)的地方,保證不出錯(cuò),如:隱式游標(biāo))

    SQL> select rownum,id,name from student where rownum =2;

        ROWNUM ID     NAME

    (2)rownum對(duì)于大于某值的查詢條件

       如果想找到從第二行記錄以后的記錄,當(dāng)使用rownum>2是查不出記錄的,原因是由于rownum是一個(gè)總是從1開始的偽列,Oracle 認(rèn)為rownum> n(n>1的自然數(shù))這種條件依舊不成立,所以查不到記錄。

    查找到第二行以后的記錄可使用以下的子查詢方法來解決。注意子查詢中的rownum必須要有別名,否則還是不會(huì)查出記錄來,這是因?yàn)閞ownum不是某個(gè)表的列,如果不起別名的話,無法知道rownum是子查詢的列還是主查詢的列。

    SQL>select * from(select rownum no ,id,name from student) where no>2;

            NO ID     NAME

    ---------- ------ ---------------------------------------------------

             3 200003 李三

             4 200004 趙四

    (3)rownum對(duì)于小于某值的查詢條件

    rownum對(duì)于rownum<n((n>1的自然數(shù))的條件認(rèn)為是成立的,所以可以找到記錄。

    SQL> select rownum,id,name from student where rownum <3;

        ROWNUM ID     NAME

    ---------- ------ ---------------------------------------------------

            1 200001 張一

            2 200002 王二

    查詢r(jià)ownum在某區(qū)間的數(shù)據(jù),必須使用子查詢。例如要查詢r(jià)ownum在第二行到第三行之 間的數(shù)據(jù),包括第二行和第三行數(shù)據(jù),那么我們只能寫以下語句,先讓它返回小于等于三的記錄行,然后在主查詢中判斷新的rownum的別名列大于等于二的記 錄行。但是這樣的操作會(huì)在大數(shù)據(jù)集中影響速度。

    SQL> select * from (select rownum no,id,name from student where rownum<=3 ) where no >=2;

            NO ID     NAME

    ---------- ------ ---------------------------------------------------

             2 200002 王二

             3 200003 李三

    (4)rownum和排序  

    Oracle中的rownum的是在取數(shù)據(jù)的時(shí)候產(chǎn)生的序號(hào),所以想對(duì)指定排序的數(shù)據(jù)去指定的rowmun行數(shù)據(jù)就必須注意了。

    SQL> select rownum ,id,name from student order by name;

        ROWNUM ID     NAME

    ---------- ------ ---------------------------------------------------

             3 200003 李三

             2 200002 王二

             1 200001 張一

             4 200004 趙四

    可以看出,rownum并不是按照name列來生成的序號(hào)。系統(tǒng)是按照記錄插入時(shí)的順序給記錄排的號(hào),rowid也是順序分配的。為了解決這個(gè)問題,必須使用子查詢;

    SQL> select rownum ,id,name from (select * from student order by name);

        ROWNUM ID     NAME

    ---------- ------ ---------------------------------------------------

             1 200003 李三

             2 200002 王二

             3 200001 張一

             4 200004 趙四

    這樣就成了按name排序,并且用rownum標(biāo)出正確序號(hào)(有小到大)

    筆者在工作中有一上百萬條記錄的表,在jsp頁面中需對(duì)該表進(jìn)行分頁顯示,便考慮用rownum來作,下面是具體方法(每頁顯示20條):

    “select * from tabname where rownum<20 order by name" 但卻發(fā)現(xiàn)oracle卻不能按自己的意愿來執(zhí)行,而是先隨便取20條記錄,然后再order by,后經(jīng)咨詢oracle,說rownum確實(shí)就這樣,想用的話,只能用子查詢來實(shí)現(xiàn)先排序,后rownum,方法如下:

    "select * from (select * from tabname order by name) where rownum<20",但這樣一來,效率會(huì)低很多。

    后經(jīng)筆者試驗(yàn),只需在order by 的字段上加主鍵或索引即可讓oracle先按該字段排序,然后再rownum;方法不變:    “select * from tabname where rownum<20 order by name"

    取得某列中第N大的行

    select column_name from

    (select table_name.*,dense_rank() over (order by column desc) rank from table_name)

    where rank = &N;

    假如要返回前5條記錄:

    select * from tablename where rownum<6;(或是rownum <= 5 或是rownum != 6)

    假如要返回第5-9條記錄:

    select * from tablename

    where …

    and rownum<10

    minus

    select * from tablename

    where …

    and rownum<5

    order by name

    選出結(jié)果后用name排序顯示結(jié)果。(先選再排序)

    注意:只能用以上符號(hào)(<、<=、!=)。

    select * from tablename where rownum != 10;返回的是前9條記錄。

    不能用:>,>=,=,Between...and。由于rownum是一個(gè)總是從1開始的偽列,Oracle 認(rèn)為這種條件不成立。

    另外,這個(gè)方法更快:

    select * from (

    select rownum r,a from yourtable

    where rownum <= 20

    order by name )

    where r > 10

    這樣取出第11-20條記錄!(先選再排序再選)

    要先排序再選則須用select嵌套:內(nèi)層排序外層選。

    rownum是隨著結(jié)果集生成的,一旦生成,就不會(huì)變化了;同時(shí),生成的結(jié)果是依次遞加的,沒有1就永遠(yuǎn)不會(huì)有2!

    rownum 是在查詢集合產(chǎn)生的過程中產(chǎn)生的偽列,并且如果where條件中存在 rownum 條件的話,則:

    1: 假如判定條件是常量,則:

    只能 rownum = 1, <= 大于1 的自然數(shù), = 大于1 的數(shù)是沒有結(jié)果的;大于一個(gè)數(shù)也是沒有結(jié)果的

    即 當(dāng)出現(xiàn)一個(gè) rownum 不滿足條件的時(shí)候則 查詢結(jié)束 this is stop key(一個(gè)不滿足,系統(tǒng)將該記錄過濾掉,則下一條記錄的rownum還是這個(gè),所以后面的就不再有滿足記錄,this is stop key);

    2: 假如判定值不是常量,則:

    若條件是 = var , 則只有當(dāng) var 為1 的時(shí)候才滿足條件,這個(gè)時(shí)候不存在 stop key ,必須進(jìn)行full scan ,對(duì)每個(gè)滿足其他where條件的數(shù)據(jù)進(jìn)行判定,選出一行后才能去選rownum=2的行……

    以下摘自《中國(guó)IT實(shí)驗(yàn)室》

    1.在oracle中實(shí)現(xiàn)select top n

       由于oracle不支持select top語句,所以在oracle中經(jīng)常是用order by跟rownum的組合來實(shí)現(xiàn)select top n的查詢。

    簡(jiǎn)單地說,實(shí)現(xiàn)方法如下所示:

    select 列名1...列名n from   

    (select 列名1...列名n from 表名 order by 列名1...列名n)

    where rownum<=n(抽出記錄數(shù))

    order by rownum asc

       下面舉個(gè)例子簡(jiǎn)單說明一下。

    顧客表customer(id,name)有如下數(shù)據(jù):

    ID NAME

       01 first

       02 Second

       03 third

       04 forth

       05 fifth

       06 sixth

       07 seventh

       08 eighth

       09 ninth

       10 last

       則按NAME的字母順抽出前三個(gè)顧客的SQL語句如下所示:

    select * from

       (select * from customer order by name)

       where rownum<=3

       order by rownum asc

       輸出結(jié)果為:

       ID NAME

       08 eighth

       05 fifth

       01 first

    posted @ 2011-05-10 17:32 哈希 閱讀(468) | 評(píng)論 (0)編輯 收藏

    一、String,StringBuffer, StringBuilder 的區(qū)別是什么?String為什么是不可變的?
    二、VECTOR,ARRAYLIST, LINKEDLIST的區(qū)別是什么?
    三、HASHTABLE, HASGMAQ,TreeMap區(qū)別
    四、ConcurrentMap和HashMap的區(qū)別
    五、Tomcat,apache,jboss的區(qū)別
    六、GET POST區(qū)別
    七、SESSION, COOKIE區(qū)別
    八、Servlet的生命周期
    九、HTTP 報(bào)文包含內(nèi)容
    十、Statement與PreparedStatement的區(qū)別,什么是SQL注入,如何防止SQL注入
    十一、redirect, foward區(qū)別
    十二、關(guān)于JAVA內(nèi)存模型,一個(gè)對(duì)象(兩個(gè)屬性,四個(gè)方法)實(shí)例化100次,現(xiàn)在內(nèi)存中的存儲(chǔ)狀態(tài),
    幾個(gè)對(duì)象,幾個(gè)屬性,幾個(gè)方法。
    十三、談?wù)凥ibernate的理解,一級(jí)和二級(jí)緩存的作用,在項(xiàng)目中Hibernate都是怎么使用緩存的
    十四、反射講一講,主要是概念,都在哪需要反射機(jī)制,反射的性能,如何優(yōu)化
    十五、談?wù)凥ibernate與Ibatis的區(qū)別,哪個(gè)性能會(huì)更高一些
    十六、對(duì)Spring的理解,項(xiàng)目中都用什么?怎么用的?對(duì)IOC、和AOP的理解及實(shí)現(xiàn)原理
    十七、線程同步,并發(fā)操作怎么控制
    十八、描述struts的工作流程。
    十九、Tomcat的session處理,如果讓你實(shí)現(xiàn)一個(gè)tomcatserver,如何實(shí)現(xiàn)session機(jī)制
    二十、關(guān)于Cache(Ehcache,Memcached)
    二一、sql的優(yōu)化相關(guān)問題
    二二、oracle中 rownum與rowid的理解,一千條記錄我查200到300的記錄怎么查?
    二三、如何分析ORACLE的執(zhí)行計(jì)劃?
    二四、 DB中索引原理,種類,使用索引的好處和問題是什么?
    二五、JVM垃圾回收實(shí)現(xiàn)原理。垃圾回收的線程優(yōu)先級(jí)。
    二六、jvm 最大內(nèi)存設(shè)置。設(shè)置的原理。結(jié)合垃圾回收講講。


    1、了解j2EE規(guī)范,選擇幾點(diǎn)進(jìn)行重點(diǎn)消化。
    2、異常分類,一般性異常和運(yùn)行期異常,異常捕獲。
    3、了解spring mvc框架,和struts mvc框架的區(qū)別。
    4、要對(duì)spring和ibatis非常熟悉,必須,熟知。
    5、應(yīng)適當(dāng)關(guān)注需求分析和產(chǎn)品方面的知識(shí)。
    6、了解多線程相關(guān)知識(shí)
    7、了解java5以及java6新特性
    8、熟悉linux相關(guān)命令操作。
    9、工廠模式,簡(jiǎn)單工廠、抽象工廠的區(qū)別
    10、動(dòng)態(tài)代理模式
    11、

    一、String,StringBuffer, StringBuilder 的區(qū)別是什么?String為什么是不可變的?
    二、VECTOR,ARRAYLIST, LINKEDLIST的區(qū)別是什么?
    三、HASHTABLE, HASGMAQ,TreeMap區(qū)別
    四、ConcurrentMap和HashMap的區(qū)別
    五、Tomcat,apache,jboss的區(qū)別
    六、GET POST區(qū)別
    七、SESSION, COOKIE區(qū)別
    八、Servlet的生命周期
    九、HTTP 報(bào)文包含內(nèi)容
    十、Statement與PreparedStatement的區(qū)別,什么是SQL注入,如何防止SQL注入
    十一、redirect, foward區(qū)別
    十二、關(guān)于JAVA內(nèi)存模型,一個(gè)對(duì)象(兩個(gè)屬性,四個(gè)方法)實(shí)例化100次,現(xiàn)在內(nèi)存中的存儲(chǔ)狀態(tài),
    幾個(gè)對(duì)象,幾個(gè)屬性,幾個(gè)方法。
    十三、談?wù)凥ibernate的理解,一級(jí)和二級(jí)緩存的作用,在項(xiàng)目中Hibernate都是怎么使用緩存的
    十四、反射講一講,主要是概念,都在哪需要反射機(jī)制,反射的性能,如何優(yōu)化
    十五、談?wù)凥ibernate與Ibatis的區(qū)別,哪個(gè)性能會(huì)更高一些
    十六、對(duì)Spring的理解,項(xiàng)目中都用什么?怎么用的?對(duì)IOC、和AOP的理解及實(shí)現(xiàn)原理
    十七、線程同步,并發(fā)操作怎么控制
    十八、描述struts的工作流程。
    十九、Tomcat的session處理,如果讓你實(shí)現(xiàn)一個(gè)tomcatserver,如何實(shí)現(xiàn)session機(jī)制
    二十、關(guān)于Cache(Ehcache,Memcached)
    二一、sql的優(yōu)化相關(guān)問題
    二二、oracle中 rownum與rowid的理解,一千條記錄我查200到300的記錄怎么查?
    二三、如何分析ORACLE的執(zhí)行計(jì)劃?
    二四、 DB中索引原理,種類,使用索引的好處和問題是什么?
    二五、JVM垃圾回收實(shí)現(xiàn)原理。垃圾回收的線程優(yōu)先級(jí)。
    二六、jvm 最大內(nèi)存設(shè)置。設(shè)置的原理。結(jié)合垃圾回收講講。


    廣州java開發(fā)工程師,昨天下午1,2面,今天3,4面,感覺效率挺高的,就等通知了
    簡(jiǎn)單說一下流程吧
      1面,一個(gè)挺帥氣的面試官,不斷地問一個(gè)算法題,一個(gè)基礎(chǔ)知識(shí)問題,一個(gè)項(xiàng)目問題,循環(huán)地進(jìn)行,
    一共5,6輪吧,中間還問了一題情景題,大概一個(gè)小時(shí),算法題不難,比如找出亂序數(shù)組中的相同元素,整數(shù)求二進(jìn)制的1的個(gè)數(shù)等,
    感覺考的是你寫程序的習(xí)慣和思維是否周密,基礎(chǔ)題就是jdk,gc,jvm之類的問題,考的很細(xì)。最后的問題是內(nèi)存里一個(gè)hashmap
    和一個(gè)文本里的內(nèi)容同步的實(shí)現(xiàn)方法,當(dāng)時(shí)答不上來,面試就結(jié)束了,后來回學(xué)校才想到一個(gè)方法。
      2面,兩個(gè)男的面試官輪流問我問題,同樣是問技術(shù)的,spring里一些核心原理,jdk1.5的新類庫,分布式系統(tǒng),數(shù)據(jù)庫,linux(這個(gè)不懂...)等等,
    感覺是車輪戰(zhàn),看你的知識(shí)廣度和反應(yīng)力....
      3面, 產(chǎn)品經(jīng)理的面試,更多的是針對(duì)我項(xiàng)目里的問題提問,會(huì)問深入的問題,比如spring的aop是如何用java實(shí)現(xiàn)的....
      4面,hr面,比較輕松吧,拉拉家常,隨便談?wù)劊瑔枂栁业奈餮b,身高之類的

    感覺我自己盡力了,會(huì)的都答上,現(xiàn)在就看淘寶發(fā)不發(fā)offer給我了,后來還去了阿里巴巴b2b面試,考的內(nèi)容基本差不多,而且更注重你是如何學(xué)習(xí)的
    一直覺得java的面經(jīng)很少,希望這可以幫到大家

    posted @ 2011-05-10 17:31 哈希 閱讀(4088) | 評(píng)論 (0)編輯 收藏

    1.觸發(fā)器的作用?
     答:觸發(fā)器是一中特殊的存儲(chǔ)過程,主要是通過事件來觸發(fā)而被執(zhí)行的。它可以強(qiáng)化約束,來維護(hù)數(shù)據(jù)的完整性和一致性,可以跟蹤數(shù)據(jù)庫內(nèi)的操作從而不允許未經(jīng)許可的更新和變化。可以聯(lián)級(jí)運(yùn)算。如,某表上的觸發(fā)器上包含對(duì)另一個(gè)表的數(shù)據(jù)操作,而該操作又會(huì)導(dǎo)致該表觸發(fā)器被觸發(fā)。
    2。什么是存儲(chǔ)過程?用什么來調(diào)用?
    答:存儲(chǔ)過程是一個(gè)預(yù)編譯的SQL語句,優(yōu)點(diǎn)是允許模塊化的設(shè)計(jì),就是說只需創(chuàng)建一次,以后在該程序中就可以調(diào)用多次。如果某次操作需要執(zhí)行多次SQL,使用存儲(chǔ)過程比單純SQL語句執(zhí)行要快??梢杂靡粋€(gè)命令對(duì)象來調(diào)用存儲(chǔ)過程。
    3。索引的作用?和它的優(yōu)點(diǎn)缺點(diǎn)是什么?
    答:索引就一種特殊的查詢表,數(shù)據(jù)庫的搜索引擎可以利用它加速對(duì)數(shù)據(jù)的檢索。它很類似與現(xiàn)實(shí)生活中書的目錄,不需要查詢整本書內(nèi)容就可以找到想要的數(shù)據(jù)。索引可以是唯一的,創(chuàng)建索引允許指定單個(gè)列或者是多個(gè)列。缺點(diǎn)是它減慢了數(shù)據(jù)錄入的速度,同時(shí)也增加了數(shù)據(jù)庫的尺寸大小。
    3。什么是內(nèi)存泄漏?
    答:一般我們所說的內(nèi)存泄漏指的是堆內(nèi)存的泄漏。堆內(nèi)存是程序從堆中為其分配的,大小任意的,使用完后要顯示釋放內(nèi)存。當(dāng)應(yīng)用程序用關(guān)鍵字new等創(chuàng)建對(duì)象時(shí),就從堆中為它分配一塊內(nèi)存,使用完后程序調(diào)用free或者delete釋放該內(nèi)存,否則就說該內(nèi)存就不能被使用,我們就說該內(nèi)存被泄漏了。
    4。維護(hù)數(shù)據(jù)庫的完整性和一致性,你喜歡用觸發(fā)器還是自寫業(yè)務(wù)邏輯?為什么?
    答:我是這樣做的,盡可能使用約束,如check,主鍵,外鍵,非空字段等來約束,這樣做效率最高,也最方便。其次是使用觸發(fā)器,這種方法可以保證,無論什么業(yè)務(wù)系統(tǒng)訪問數(shù)據(jù)庫都可以保證數(shù)據(jù)的完整新和一致性。最后考慮的是自寫業(yè)務(wù)邏輯,但這樣做麻煩,編程復(fù)雜,效率低下。
    5。什么是事務(wù)?什么是鎖?
    答:事務(wù)就是被綁定在一起作為一個(gè)邏輯工作單元的SQL語句分組,如果任何一個(gè)語句操作失敗那么整個(gè)操作就被失敗,以后操作就會(huì)回滾到操作前狀態(tài),或者是上有個(gè)節(jié)點(diǎn)。為了確保要么執(zhí)行,要么不執(zhí)行,就可以使用事務(wù)。要將有組語句作為事務(wù)考慮,就需要通過ACID測(cè)試,即原子性,一致性,隔離性和持久性。
     鎖:在所以的DBMS中,鎖是實(shí)現(xiàn)事務(wù)的關(guān)鍵,鎖可以保證事務(wù)的完整性和并發(fā)性。與現(xiàn)實(shí)生活中鎖一樣,它可以使某些數(shù)據(jù)的擁有者,在某段時(shí)間內(nèi)不能使用某些數(shù)據(jù)或數(shù)據(jù)結(jié)構(gòu)。當(dāng)然鎖還分級(jí)別的。
    6。什么叫視圖?游標(biāo)是什么?
    答:視圖是一種虛擬的表,具有和物理表相同的功能。可以對(duì)視圖進(jìn)行增,改,查,操作,試圖通常是有一個(gè)表或者多個(gè)表的行或列的子集。對(duì)視圖的修改不影響基本表。它使得我們獲取數(shù)據(jù)更容易,相比多表查詢。
     游標(biāo):是對(duì)查詢出來的結(jié)果集作為一個(gè)單元來有效的處理。游標(biāo)可以定在該單元中的特定行,從結(jié)果集的當(dāng)前行檢索一行或多行。可以對(duì)結(jié)果集當(dāng)前行做修改。一般不使用游標(biāo),但是需要逐條處理數(shù)據(jù)的時(shí)候,游標(biāo)顯得十分重要。
    7。為管理業(yè)務(wù)培訓(xùn)信息,建立3個(gè)表:

        S(S#,SN,SD,SA)S#,SN,SD,SA分別代表學(xué)號(hào),學(xué)員姓名,所屬單位,學(xué)員年齡

        C(C#,CN)C#,CN分別代表課程編號(hào),課程名稱

         SC(S#,C#,G) S#,C#,G分別代表學(xué)號(hào),所選的課程編號(hào),學(xué)習(xí)成績(jī)

       (1)使用標(biāo)準(zhǔn)SQL嵌套語句查詢選修課程名稱為’稅收基礎(chǔ)’的學(xué)員學(xué)號(hào)和姓名?

             答案:select s# ,sn from s where S# in(select S# from c,sc where c.c#=sc.c# and cn=’稅收基礎(chǔ)’)

         (2) 使用標(biāo)準(zhǔn)SQL嵌套語句查詢選修課程編號(hào)為’C2’的學(xué)員姓名和所屬單位?

    答:select sn,sd from s,sc where s.s#=sc.s# and sc.c#=’c2’

         (3) 使用標(biāo)準(zhǔn)SQL嵌套語句查詢不選修課程編號(hào)為’C5’的學(xué)員姓名和所屬單位?

    答:select sn,sd from s where s# not in(select s# from sc where c#=’c5’)

          (4)查詢選修了課程的學(xué)員人數(shù)

    答:select 學(xué)員人數(shù)=count(distinct s#) from sc

          (5) 查詢選修課程超過5門的學(xué)員學(xué)號(hào)和所屬單位?

    答:select sn,sd from s where s# in(select s# from sc group by s# having count(distinct c#)>5)


    posted @ 2011-05-08 08:28 哈希 閱讀(226) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共11頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 Last 
    主站蜘蛛池模板: AV在线播放日韩亚洲欧| 激情五月亚洲色图| 免费中文字幕在线| 3d成人免费动漫在线观看| 国产精品永久免费| 欧洲乱码伦视频免费国产| 亚洲精品无码一区二区| 亚洲精品GV天堂无码男同| 亚洲人成欧美中文字幕| 国产三级在线免费观看| 一级A毛片免费观看久久精品 | 亚洲性色AV日韩在线观看| 亚洲国产美女精品久久| 亚洲色图.com| 亚洲国产成人片在线观看| 亚洲国产精品无码久久一区二区| 在线A亚洲老鸭窝天堂| 亚洲日韩中文无码久久| 国产亚洲人成A在线V网站| 久久精品亚洲福利| xxx毛茸茸的亚洲| 国产精品久久久久久亚洲影视| 亚洲VA成无码人在线观看天堂| 国产精品jizz在线观看免费| 日本高清免费不卡在线| 免费va在线观看| 亚洲性一级理论片在线观看| 中文毛片无遮挡高清免费| 日韩精品免费在线视频| 日韩插啊免费视频在线观看| 91精品成人免费国产片| 成人毛片免费视频| 国产又长又粗又爽免费视频| 亚洲精品电影在线| 亚洲av成人一区二区三区在线播放 | 四虎影在线永久免费观看| 自拍偷自拍亚洲精品第1页| 亚洲丰满熟女一区二区哦| 四虎在线视频免费观看视频| 亚洲一区无码中文字幕 | 亚洲视频一区在线播放|