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

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

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

    xskow's road.

    做好自己,做好一切。
    數(shù)據(jù)加載中……
    華南理工大學(xué)校運(yùn)會計(jì)分系統(tǒng)項(xiàng)目總結(jié)(一)
            這么一個(gè)項(xiàng)目,確實(shí),用了我很多時(shí)間,原因是自己在項(xiàng)目開始時(shí)可以說對SSH只有一知半解,就堅(jiān)決地要采用這三個(gè)優(yōu)秀框架來搭建服務(wù)。不過,學(xué)到的確實(shí)不少啊,起碼對于這樣的應(yīng)用還是有一定底子了,呵呵。。。
            在這個(gè)項(xiàng)目當(dāng)中,有什么值得寫在我的小博客上面呢?有的。本項(xiàng)目分層也是采用經(jīng)典的貧血模式。由底向上共四層,model-->dao-->service-->action。其中model采用Hibernate,底層數(shù)據(jù)庫用MySQL5,在Hibernate方面,我用了比較新的annotations,而不是平常的*.hbm.xml。確實(shí),annotations用起來比較方便,但是和POJO的耦合度就大多了。記得有些配錯(cuò)的時(shí)候要一個(gè)一個(gè)getter去找annotation,呵呵。。。
            在Hibernate annotation方面,還是有些東西值得總結(jié)一下,首先就是annotation寫在是什么地方,最方便的方法是寫在各個(gè)field的getter上面,這樣就不用額外的annotation,也建議大家采用此方法,另一種也就是寫在field聲明上面,這樣的話需要在類上方添加其他annotation,我當(dāng)時(shí)是沒成功,呵呵。其次是級聯(lián)操作,也就是cascade,需要注意的是當(dāng)兩個(gè)實(shí)體關(guān)系是一對多和多對多的時(shí)候,比如班級與學(xué)生,學(xué)生與課程,明顯班級與學(xué)生是一對多,學(xué)生與課程是多對多關(guān)系,那么當(dāng)我們需要設(shè)置級聯(lián)時(shí)候怎么辦呢?在hibernate中,cascade分有4種,分別是CascadeType.PERSIST,CascadeType.MERGE,CascadeType.REFRESH,CascadeType.REMOVE。比如是persist,如果在剛才的例子來說,應(yīng)該這樣配置:
     1//班級實(shí)體
     2@Entity
     3@Table(name="T_CLASS")
     4public class Clazz{
     5  
     6  private Set<Student> students;
     7  
     8  
     9  @OneToMany
    10  (cascade={CascadeType.REMOVE,CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.LAZY, mappedBy="clazz")
    11  public Set<Student> getStudents(){
    12    return students;
    13  }
     
    14}

    15

     1//學(xué)生實(shí)體
     2@Entity
     3@Table(name="T_STUDENT")
     4
     5public class Student{
     6  
     7  private Clazz clazz;
             private Set<Course> courses;
     8  
     9  @ManyToOne
    10  @JoinColumn(name="CLAZZ_ID")
    11  public Clazz getClazz(){
    12    return clazz;
    13  }

    14  
              @ManyToMany
              @JoinTable(name="T_STUDENT_COURSE")
              public Set<Course> getCourses(){
                    return courses;
             } 
    15}

     1//課程實(shí)體
     2public class Course{
     3  
     4  private Set<Student> students;
     5  
     6  @ManyToMany(mappedBy="courses" cascade={CascadeType.PERSIST, CascadeType.REMOVE})
     7  public Set<Student> getStudents(){
     8    return students;
     9  }

    10}

    在Clazz的OneToMany和Course的ManyToMany中,我們都可以看到有CascadeType.PERSIST和CascadeType.REMOVE。具體到底是什么意思呢?persist是指當(dāng)持久化實(shí)體的時(shí)候,如果有關(guān)聯(lián)的集合,并且設(shè)成persist時(shí),連集合也一并存入數(shù)據(jù)庫當(dāng)中。但是如果真正寫一下,然后使用的話,我們會發(fā)現(xiàn):OneToMany設(shè)置這個(gè)根本不起作用。比如我新建一個(gè)班級,并直接賦予60個(gè)學(xué)生的一個(gè)集合,然后調(diào)用dao的save方法,看看數(shù)據(jù)庫,怎么回事,怎么只有班級持久化了,關(guān)聯(lián)學(xué)生一個(gè)沒存到數(shù)據(jù)庫?然后試試新建課程,并且選上要修這門課的學(xué)生,然后持久化課程,看看數(shù)據(jù)庫,怎么搞的,這次雙方都持久化了,即中間表已經(jīng)插入了相關(guān)的記錄。造成OneToMany用persist是什么原因?個(gè)人理解:學(xué)生屬于一個(gè)實(shí)體,其持久化應(yīng)當(dāng)依靠自己相應(yīng)的dao,一個(gè)一個(gè)student的存儲。就好比student和course的中間表,我們上面假設(shè)中間表只有STUDENT_ID和COURSE_ID,并且分別連向student表和course表的主鍵,如果你有特殊需求,比如是要一個(gè)score列(課程成績),那么這時(shí)候你還想用ManyToMany配置的話,會出現(xiàn)好多問題,除非你允許成績是空的,但是即使成績可以為空,如果你需要修改成績怎么辦呢?先取出這個(gè)學(xué)生,然后遍歷其課程集合,找到這個(gè)課程然后再持久化不行?應(yīng)該可以吧,但是是不是指需要先刪除這個(gè)學(xué)生選的課程,然后再將這些再次持久化一次?這個(gè)方法絕對可以,不過我沒人會這樣。。。呵呵。。。當(dāng)中間表有其他與兩方表都沒有關(guān)系的列時(shí),你應(yīng)當(dāng)為中間表也映射一個(gè)實(shí)體,用這個(gè)實(shí)體的相應(yīng)dao修改相應(yīng)的記錄。在這種情況下用ManyToMany還有另一個(gè)問題,如果你的hibernate session還沒有關(guān)閉,你會發(fā)現(xiàn)提錯(cuò),說你打算刪除即將再次持久化的記錄。使用OpenSessionInViewFilter的時(shí)候你就會發(fā)現(xiàn)這個(gè)問題了。呵呵。。。
            還有一個(gè),Hibernate官方不推薦使用聯(lián)合主鍵,原來的我就不相信用聯(lián)合主鍵會怎樣,還不行嗎?要不行那還不是你框架太爛?實(shí)踐過之后,我改變了我的看法。。。假如你是普通的一個(gè)表,使用聯(lián)合主鍵沒有任何問題,但是假如你的表是一個(gè)中間表,并且有和兩個(gè)關(guān)聯(lián)表無關(guān)的列,就像T_STUDENT_COURSE,我們在設(shè)計(jì)數(shù)據(jù)庫的時(shí)候,很容易想到用STUDENT_ID和COURSE_ID來作為主鍵,不錯(cuò),但是如果你用hibernate映射實(shí)體的時(shí)候你知道有什么麻煩嗎?首先這兩個(gè)都是外鍵,在hibernate中就是需要有兩個(gè)關(guān)聯(lián)實(shí)體的對象引用,那么這兩個(gè)作為@Id是吧?可以啊!但是當(dāng)你持久化的時(shí)候,會提示student在T_STUDENT_COURSE中無法找到。為什么?因?yàn)槟銛?shù)據(jù)庫就一個(gè)ID呀,而你這里配的可是一個(gè)實(shí)體引用呀!其實(shí)這也是可以解決了,就是解決辦法迂回一點(diǎn)點(diǎn),在hibernate外鍵關(guān)聯(lián)的時(shí)候可以指定實(shí)體引用,就是說比如你StudentCourse實(shí)體,有一個(gè)student的引用,可以定義這樣一個(gè)column:studentId,這個(gè)Id可以關(guān)聯(lián)student引用,具體寫法我就不寫出來了,在hibernate官方文檔寫得相當(dāng)詳細(xì),很容易驗(yàn)證。看,就一個(gè)外鍵都這樣了,多個(gè)外鍵還得了?當(dāng)然,如果普通的單外鍵引用不會產(chǎn)生這樣的問題,直接配一個(gè)實(shí)體引用就可以解決問題。問題是可以解決的,關(guān)鍵是以后維護(hù)起來是否方便?我做過就知道,一點(diǎn)不簡單,所以后來還是改了。。。不推薦大家使用聯(lián)合主鍵。

    posted on 2008-11-10 20:39 xskow! 閱讀(860) 評論(1)  編輯  收藏 所屬分類: SSH探索

    評論

    # re: 華南理工大學(xué)校運(yùn)會計(jì)分系統(tǒng)項(xiàng)目總結(jié)(一) 2008-12-17 22:28 ytl

    不錯(cuò),想你學(xué)習(xí)啦。可和你成為朋友不??我的QQ號是:543893878 Email:ytl_zlq@163.com
      回復(fù)  更多評論    
    links:
    主站蜘蛛池模板: 亚洲乱码在线观看| 无码毛片一区二区三区视频免费播放| 无码国产精品一区二区免费虚拟VR| 国产成+人+综合+亚洲专| 国产成人免费a在线资源| 男人天堂免费视频| 精品亚洲AV无码一区二区| 亚洲国产精品视频| 成人福利免费视频| 精品久久久久久国产免费了 | 亚洲国产一成人久久精品| 无码国产精品一区二区免费虚拟VR| 日韩在线视频免费| 亚洲精品亚洲人成在线观看麻豆| 又粗又硬免费毛片| 免费在线观看h片| 波霸在线精品视频免费观看| 亚洲成a人片在线观看精品| 国产日产亚洲系列| 日本无卡码免费一区二区三区| 免费91麻豆精品国产自产在线观看 | 亚洲毛片基地日韩毛片基地| 亚洲国产精品丝袜在线观看| 国内精自视频品线六区免费 | 久久一区二区三区免费播放| 99亚洲精品卡2卡三卡4卡2卡| 亚洲一区二区三区高清| 亚洲福利精品电影在线观看| 免费无码A片一区二三区| 国产婷婷成人久久Av免费高清| 九九精品国产亚洲AV日韩| 亚洲另类图片另类电影| 亚洲av永久无码精品网站 | 国产午夜无码视频免费网站 | 在线a亚洲v天堂网2018| 两个人的视频高清在线观看免费 | 日本高清免费不卡视频| 久久www免费人成看片| 国产一区二区免费| h在线看免费视频网站男男| 美女视频黄免费亚洲|