Junky's IT Notebook

          統(tǒng)計(jì)

          留言簿(8)

          積分與排名

          WebSphere Studio

          閱讀排行榜

          評(píng)論排行榜

          HIBERNATE學(xué)習(xí)筆記(轉(zhuǎn))

          Hibernate 學(xué)習(xí)筆記

          一 hibernate配置
          1.下載所需包
          下載hibernate2.13, hibernate-extension2.13,Middlegen(已裝了jdk和ant)
          2.創(chuàng)建數(shù)據(jù)庫(kù)(例子:student;course,stu_cou)
          Student(id,name)
          Course(id,name)
          Stu_cou(stu_id,cou_id)(分別是student表和course表的外健)
          3.使用MiddleGen(見附錄)

          二 hibernate映射關(guān)系(many-to-many)
          1. 分析inverse參數(shù)(student.hbm.xml course.hbm.xml)
          inverse該參數(shù)用來負(fù)責(zé)映射之間的關(guān)系,設(shè)置為false的一方可以對(duì)他們的關(guān)系進(jìn)行維護(hù)
          設(shè)置inverse = false的實(shí)體,表示在映射中是它是主動(dòng)關(guān)系,由它來維戶關(guān)系中的數(shù)據(jù)
          設(shè)置inverse = true 的實(shí)體,表示在映射中是它是被動(dòng)關(guān)系,它不維護(hù)關(guān)系中的數(shù)據(jù)
          1) inverse=false的情況
          a) 添加記錄的情況
          student.hbm.xml是主動(dòng)方,由它來決定stu_cou表中的記錄,故inverse=false
          當(dāng)向stu_cou中寫入記錄時(shí)候,
          /*
          * 測(cè)試目的:在stu_cou中添加一組對(duì)應(yīng)關(guān)系(student,course)
          * 測(cè)試結(jié)果:當(dāng)執(zhí)行完該段代碼后
          * 如stu_cou中沒有(student,course)時(shí),自動(dòng)加入(student,course)
          * 如stu_cou中存在(student,course)時(shí),什么都不作,不會(huì)存在主健沖突
          Student student=(Student)session.load(Student.class,student2.getId())
          Course course=(Course)session.load(Course.class,course2.getId());
          student.getCourses().add(course);
          session.save(student);
          執(zhí)行完后,hibenrate成功顯示
          Hibernate: select course0_.id as id0_, course0_.name as name0_ from course course0_ where course0_.id=?
          Hibernate: select student0_.id as id0_, student0_.name as name0_ from student student0_ where student0_.id=?
          Hibernate: select courses0_.cid as cid__, courses0_.sid as sid__ from stu_cou courses0_ where courses0_.sid=?
          Hibernate: insert into stu_cou (sid, cid) values (?, ?)
          b) 刪除記錄的情況
          Student student=(Student)session.load(Student.class,student2.getId())
          Course course=(Course)session.load(Course.class,course2.getId());
          student.getCourses().讓remove(course);
          session.save(student);
          代碼執(zhí)行完后,可以成功執(zhí)行,hibernate顯示:
          Hibernate: select course0_.id as id0_, course0_.name as name0_ from course course0_ where course0_.id=?
          Hibernate: select student0_.id as id0_, student0_.name as name0_ from student student0_ where student0_.id=?
          Hibernate: select courses0_.cid as cid__, courses0_.sid as sid__ from stu_cou courses0_ where courses0_.sid=?
          Hibernate: delete from stu_cou where sid=?

          2) inverse=true的情況
          student.hbm.xml是被動(dòng)方,設(shè)置它的inverse=true
          a) 添加記錄情況
          * 測(cè)試目的:在stu_cou中添加一組對(duì)應(yīng)關(guān)系(student,course)
          * 測(cè)試結(jié)果:當(dāng)執(zhí)行完該段代碼后
          * 如stu_cou中沒有(student,course)時(shí),自動(dòng)加入(student,course)
          * 如stu_cou中存在(student,course)時(shí),什么都不作,不會(huì)存在主健沖突
          Student tudent=(Student)session.load(Student.class,student2.getId());
          Course course=(Course)session.load(Course.class,course2.getId());
          student.getCourses().add(course);
          session.save(student);
          代碼執(zhí)行完后,hibernate顯示,沒有插入記錄
          Hibernate: select course0_.id as id0_, course0_.name as name0_ from course course0_ where course0_.id=?
          Hibernate: select student0_.id as id0_, student0_.name as name0_ from student student0_ where student0_.id=?
          Hibernate: select courses0_.cid as cid__, courses0_.sid as sid__ from stu_cou courses0_ where courses0_.sid=?

          b) 刪除記錄情況
          當(dāng)向stu_cou中刪除記錄時(shí)候,
          Student student=(Student)session.load(Student.class,student2.getId())
          Course course= (Course)session.load(Course.class,course2.getId());
          student.getCourses().remove(course);
          session.save(student);
          執(zhí)行完,hibernate顯示如下,證明沒有刪除記錄
          Hibernate: select course0_.id as id0_, course0_.name as name0_ from course course0_ where course0_.id=?
          Hibernate: select student0_.id as id0_, student0_.name as name0_ from student student0_ where student0_.id=?
          Hibernate: select courses0_.cid as cid__, courses0_.sid as sid__ from stu_cou courses0_ where courses0_.sid=?
          Hibernate: select course0_.id as id0_, course0_.name as name0_ from course course0_ where course0_.id=?
          Hibernate: select course0_.id as id0_, course0_.name as name0_ from course course0_ where course0_.id=?

          2. 分析cascade參數(shù)(student.hbm.xml course.hbm.xml)
          只有設(shè)置了inverse=false才可以操縱stu_cou的數(shù)據(jù)
          當(dāng)inverse=true的時(shí)候,下列情況1中b)提示錯(cuò)誤
          原因: stu_cou中存在外健約束,你無法直接刪除student表中的數(shù)據(jù)
          1) cascade=save-update的情況
          a)添加記錄情況
          Set set=new HashSet();
          set.add(course1);
          set.add(course2);
          set.add(course3);
          student3.setCourses(set);
          session.save(student3);
          執(zhí)行后hibernate提示:
          Hibernate: insert into student (name) values (?)
          Hibernate: insert into course (name) values (?)
          Hibernate: insert into course (name) values (?)
          Hibernate: insert into course (name) values (?)
          Hibernate: insert into stu_cou (sid, cid) values (?, ?)
          可見,插入了student,course,和stu_cou三個(gè)表

          b)刪除記錄情況
          Student student=(Student)session.load(Student.class,new Integer(22));
          session.delete(student);
          成功執(zhí)行后,hibernate提示:
          Hibernate: select student0_.id as id0_, student0_.name as name0_ from student student0_ where student0_.id=?
          Hibernate: delete from stu_cou where sid=?
          Hibernate: delete from student where

          2) cascade=all的情況
          a) 添加記錄情況
          Set set=new HashSet();
          set.add(course1);
          set.add(course2);
          set.add(course3);
          student3.setCourses(set);
          session.save(student3);
          執(zhí)行后hibernate提示:成功添加級(jí)聯(lián)關(guān)系
          Hibernate: insert into student (name) values (?)
          Hibernate: insert into course (name) values (?)
          Hibernate: insert into course (name) values (?)
          Hibernate: insert into course (name) values (?)
          Hibernate: insert into stu_cou (sid, cid) values (?, ?)
          b) 刪除記錄情況
          Student student=(Student)session.load(Student.class,new Integer(22));
          session.delete(student);
          測(cè)試結(jié)果(所有和student(22)相關(guān)的記錄均被刪除)
          刪除student表中的student(22)記錄
          刪除stu_cou表中的student(22)的記錄
          刪除course表中的student(22)對(duì)應(yīng)的course的記錄

          2) cascade=none情況
          a) 添加記錄情況
          Set set=new HashSet();
          set.add(course1);
          set.add(course2);
          set.add(course3);
          student3.setCourses(set);
          session.save(student3);
          失敗,因?yàn)闆]有級(jí)聯(lián)關(guān)系,所以course記錄添加不進(jìn)去,造成外健失敗

          b) 刪除記錄情況
          Student student=(Student)session.load(Student.class,new Integer(22));
          session.delete(student);
          正常,刪除了student表中的記錄student(22),同時(shí)刪除了stu_cou中對(duì)應(yīng)的student(22)的記錄

           

          附錄
          1.MiddleGen的使用
          1環(huán)境變量設(shè)置
          %Hibernate_Home%/lib/*.jar到%MiddleGen%/lib下
          %Hibernate_Home%/hibernate2.jar到%MiddleGen%/lib下
          %Hibernate-Extension_Home%/tools/lib/*.jar到%MiddleGen%/lib下
          %Hibernate-Extension_Home%/tools/hibernate-tools.jar到%MiddleGen%/lib下

          2 MiddleGen的配置
          配置目標(biāo)數(shù)據(jù)庫(kù)參數(shù)
          進(jìn)入MiddleGen 目錄下的\config\database 子目錄,根據(jù)我們實(shí)際采用的數(shù)據(jù)庫(kù)打開對(duì)應(yīng)的配置文件。如這里我用的是mysql數(shù)據(jù)庫(kù),對(duì)應(yīng)的就是mysql.xml文件。
          <property
          name="database.script.file" value="${src.dir}/sql/${name}-mysql.sql"/>
          <property
          name="database.driver.file" value="${lib.dir}/mysql.jar"/>
          <property
          name="database.driver.classpath" value="${database.driver.file}"/>
          <property
          name="database.driver" value="org.gjt.mm.mysql.Driver"/>
          <property
          name="database.url" value="jdbc:mysql://localhost/sample"/>
          <property
          name="database.userid" value="user"/>
          <property
          name="database.password" value="mypass"/>
          <property
          name="database.schema" value=""/>
          <property
          name="database.catalog" value=""/>
          <property
          name="jboss.datasource.mapping" value="mySQL"/>
          其中下劃線標(biāo)準(zhǔn)的部分是我們進(jìn)行配置的內(nèi)容,分別是數(shù)據(jù)url以及數(shù)據(jù)庫(kù)用
          戶名和密碼。

          1) 修改Build.xml
          修改MiddleGen 根目錄下的build.xml 文件,此文件是Middlegen-Hibernate 的Ant構(gòu)建配置。Middlegen-Hibernate將根據(jù)build.xml文件中的具體參數(shù)生成數(shù)據(jù)庫(kù)表映射文件。可配置的項(xiàng)目包括:

          a) 目標(biāo)數(shù)據(jù)庫(kù)配置文件地址
          查找關(guān)鍵字 ”!ENTITY”,得到:
          <!DOCTYPE project [
          <!ENTITY database SYSTEM
          "file:./config/database/hsqldb.xml">
          ]>
          默認(rèn)情況下,MiddleGen 采用的是hsqldb.xml,
          將其修改為我們所用的數(shù)據(jù)庫(kù)配置文件(mysql.xml):
          <!DOCTYPE project [
          <!ENTITY database SYSTEM
          "file:./config/database/mysql.xml">
          ]>

          b) Application name
          查找:
          <property value="airline"/>
          “aireline”是MiddleGen原始配置中默認(rèn)的 Application Name,將其修改為我們
          所希望的名稱,如“HibernateSample”:
          <property value="HibernateSample"/>

          c) 輸出目錄
          查找關(guān)鍵字“name="build.gen-src.dir"”,得到:
          <property
          value="${build.dir}/gen-src"/>
          修改value="${build.dir}/gen-src"使其指向我們所期望的輸出目錄,
          這里我們修改為:<property
          value="C:\sample"/>
          d) 對(duì)應(yīng)代碼的Package name
          查找關(guān)鍵字“destination”,得到:
          <hibernate
          destination="${build.gen-src.dir}"
          package="${name}.hibernate"
          genXDocletTags="false"
          genIntergratedCompositeKeys="false"
          javaTypeMapper=
          "middlegen.plugins.hibernate.HibernateJavaTypeMapper"
          />
          可以看到,hibernate 節(jié)點(diǎn)package 屬性的默認(rèn)設(shè)置實(shí)際上是由前面的
          Application Name (${name})和“.hibernate”組合而成,根據(jù)我們的需要,
          這里還有一個(gè)屬性genXDocletTags,如果設(shè)置為true,則生成的代碼將包含
          xdoclet tag,這為以后在開發(fā)過程中借助xdoclet進(jìn)行映射調(diào)整提供了幫助。注意,如果使用的數(shù)據(jù)庫(kù)為SQLServer,需要將build.xml部分刪除(參見夏?^的文檔),否則Middlegen會(huì)報(bào)出找不到表的錯(cuò)誤。
          至此為止,MiddleGen 已經(jīng)配置完畢,在MiddleGen 根目錄下運(yùn)行ant,就將出現(xiàn)
          MiddleGen的界面:
          2 *.xml到.java
          在得到.xml后,使用ant hbm2java 即可得到相應(yīng)的java文件
          總結(jié):
          我第一次運(yùn)行成功,但是后來則出現(xiàn)如下類似錯(cuò)誤,檢查發(fā)現(xiàn)在MiddleGen的lib目錄下存在多個(gè)類似的jar包
          (velocity.jar,velocity1-0.8.jar),刪除舊的jar包后,問題解決
          [middlegen] java.lang.IncompatibleClassChangeError
          [middlegen] at [middlegen] at org.apache.velocity.Template.process(Template.java:136)


          2.(評(píng)論)關(guān)于Many-to-Many需要注意的問題
          比如group/user,user/role,group/role,都是多對(duì)多的關(guān)系。
          所以有必要搞搞清楚。以group/user為例
          (1)group.getUsers() & user.getGroups()雙向映射。在這里,考慮到user.setGroups()是不會(huì)放出來的。所以在user端加入inverse=true,就是說,讓Group端來維護(hù)兩者的關(guān)系表。
          (2)于是,添加的時(shí)候,要把user加入到group的user set中,保存,才有意義!
          (3)如果要?jiǎng)h除group_user的關(guān)系,而不是group/user本身,那么,需要在group端設(shè)定casade=save-update。否則,group.getUsers().remove(user)不會(huì)起作用!
          (4)由于有了FK保護(hù),你是無法單獨(dú)刪除User的。同時(shí),由于你指定了inverse=true,所以無法光光的設(shè)置user.getGroups().clear就能夠搞定一切。你必須首先在每個(gè)Group.getUsers中刪除這個(gè)user,才能最后刪除。所以,UserManagerImpl代碼可能看起來像這樣:
          public void delUser(User user) {
          if (user == null) {
          logger.info("Got a null user object!");
          return;
          }
          Session session = null;
          Transaction trans = null;
          boolean bSuccess = false;
          try {
          String username = new String(user.getName());
          session = PLUtils.getSession();
          trans = session.beginTransaction();
          session.update(user);

          Set groups = ((UserEntity)user).getGroups();
          for(Iterator i = groups.iterator();i.hasNext();){
          GroupEntity g = (GroupEntity)i.next();
          session.update(g);
          g.getUsers().remove(user);
          session.update(g);
          }

          // ((UserEntity)user).getGroups().clear();
          session.delete(user);
          bSuccess = true;
          logger.debug("User " + username + " deleted ok!");
          }
          catch (ObjectNotFoundException onfe) {
          logger.info("user not found!", onfe);
          }
          catch (Exception e) {
          logger.error("failed!", e);
          }
          finally {
          try {
          if (bSuccess)
          trans.commit();
          else
          trans.rollback();
          session.close();
          }
          catch (Exception ex) {
          }
          }
          }

          posted on 2007-04-19 15:58 junky 閱讀(787) 評(píng)論(0)  編輯  收藏 所屬分類: hibernate

          主站蜘蛛池模板: 江口县| 拉萨市| 中宁县| 牙克石市| 尖扎县| 康保县| 简阳市| 吴堡县| 南川市| 临澧县| 台山市| 东山县| 彭水| 贺兰县| 山东省| 遵义县| 达拉特旗| 陈巴尔虎旗| 马公市| 鄱阳县| 桃源县| 宁蒗| 郯城县| 吉木乃县| 治县。| 礼泉县| 吴桥县| 四平市| 信丰县| 鹤壁市| 乐业县| 施甸县| 贵州省| 通渭县| 勐海县| 峨眉山市| 布拖县| 宕昌县| 黑水县| 建宁县| 舒城县|