Java綠地(~ming~)

          Java 草地

          常用鏈接

          統(tǒng)計

          最新評論

          Hibernate關系映射和HQL

          Hibernate

          .關系映射

          1.單表映射:a. public class User { private Integer id;   
          private String name; get/set}



          b.xml: <class name="User" table="user">

           <id name="id" column="id" type="integer">//配置主鍵的生成方式

          <generator class="identity"></generator>    </id>

                  <property name="name" column="name" type="string"></property>  </class>



          c. hibernate.cfg.xml
          配置相應數(shù)據(jù)庫和映射, show_sql=true;使consolesql語句可見

           


          d.
          采取junit進行測試:一般通過junitsetUp方法初始化,通過tearDown釋放資源,自動加載


          public class Client extends TestCase { protected Session session;

              public Client(String name) {        super(name);    }

              protected void setUp() throws Exception {

          Configuration config=new Configuration().configure();//創(chuàng)建Hibernate配置管理類,默認加載cfg.xml,若改名則用configure(new File(“src/hib.cfg.xml”));加上路徑

          SessionFactory sessionFactory =config.buildSessionFactory();

          session= sessionFactory.openSession(); }  //applicationHibernate交互接口

             


          protected void tearDown() throws Exception {if(session!=null) session.close();}

              public void testCreate(){User user=new User();user.setName("hello");//自動加載

              Transaction tr=null;//改變數(shù)據(jù)庫數(shù)據(jù)的操作都要開啟一個事物

              try{    tr=session.beginTransaction(); session.save(user);  tr.commit();    }

          catch(HibernateException e) {       //將自由狀態(tài)變成持久狀態(tài)

          e.printStackTrace();   }    if(tr!=null) tr.rollback(); }

              public void testRetrieve(){

                  User user=(User)session.get(User.class, 122);//得到xml中的主鍵對應的對象

                  assertEquals("hello", user.getName());}//使用斷言精確判斷,防止空格等因素



          public static Test suite(){  //junit
          的靜態(tài)測試方法

                  TestSuite ts=new TestSuite();     Client cl=new Client("testCreate");

                  ts.addTest(cl);     return ts;  } }

          e.sessionloadget方法的區(qū)別:1.對象存在時,load返回實體代理類類型,get返回實體類

                                          2.對象不存在時:load拋出異常,get返回null(用于判斷)

           



          f.
          實體對象的生命周期

            1Transient自由狀態(tài):與Hibernate和數(shù)據(jù)庫沒有任何關系

            2Persistent持久狀態(tài):納入了HibernateSession實體對象管理的容器,session會復制實體對象的引用進行臟數(shù)據(jù)檢查,實體對象任何狀態(tài)的改變最終都會同步到數(shù)據(jù)庫。例如:Transaction trx=null;

              trx=session.beginTransaction(); User user=(User)session.load(User.class, 1);

              user.setName("nihao");      trx.commit();

          //  session.update(user);就不需要了

            3Detached游離狀態(tài):(session.close()),Hibernate和數(shù)據(jù)庫沒有任何關系,但是實體對象對應數(shù)據(jù)庫的一條紀錄。如:trx=session.beginTransaction();

          User user=new User();   user.setId(61);只要一個主鍵與數(shù)據(jù)庫唯一標識

               session.delete(user);//進行臟數(shù)據(jù)檢查 trx.commit();  //真正執(zhí)行



          2
          Generator的主鍵產(chǎn)生方式:

             a. <generator class="assigned"></generator>由應用邏輯產(chǎn)生:***.setId(number);

             b.hilo:通過hi/lo(hign/low)算法產(chǎn)生

             c.seqhilo:適合oracle沒有自動增長只有序列,主鍵歷史狀態(tài)保存在sequence

             d.increment:按照數(shù)值順序增長,Hibernate維護,效率很高

             e.identity:采用數(shù)據(jù)庫提供的主鍵生成機制,并發(fā)性不好

             f.sequence:支持oracle這種數(shù)據(jù)庫

             g.native:根據(jù)數(shù)據(jù)庫適配器自動采用identity,hilo,sequence中的一種

             h.uuid:Hibernate基于128位唯一算法生成32位字符串作為主鍵,適合所有數(shù)據(jù)庫,并發(fā)好

             i:foreign:使用外部表的字段作為主鍵





          3.
          一對一通過主鍵關聯(lián)(one to one)(數(shù)據(jù)庫中將兩個表id為主鍵并建立外聯(lián),只一表自動增長)

            a. public class User1 {   private Integer id; private String name;

               private Passport passport; ...getter/setter}  //passport最為成員屬性

            b. public class Passport {  private Integer id;  private String serial;

               private User1 user; ...getter/setter}    //user作為成員屬性

            c. <hibernate-mapping package="OneToOne">  <class name="User1" table="user1">

               <id name="id" column="id" type="integer"> <generator class="identity"/></id>

               <property name="name" column="name"></property>   // type可以省略,Hib匹配

               <one-to-one name="passport" cascade="all" fetch="join"></one-to-one> </class>

          </hibernate-mapping>//cascade主控方設置級聯(lián)同步更新,delete,sava-update,none

            d. <hibernate-mapping package="OneToOne">  <class name="Passport" table="passport">

              <id name="id" column="id">  <generator class="foreign">  //主鍵有外表產(chǎn)生

                <param name="property">user</param> </generator> </id>  //值來自user成員屬性

            <property name="serial" column="serial"></property>

            <one-to-one name="user" class=”更好> </one-to-one></class> </hibernate-mapping>

            e.要想實現(xiàn)級聯(lián)操作,要讓級聯(lián)雙發(fā)都知道對方的存在:

          passport.setUser(user);    user.setPassport(passport);

          tr=session.beginTransaction();session.save(user);  tr.commit();//才會起作用

           



          4.
          通過外鍵關聯(lián):many to one(環(huán)境:很多個人在一個組中且fk:user.group_id-àgroup.id)

            a. public class Group {    private Integer id; private String name;  }

          b. public class User2 { private Integer id;   private String name;

          private Group group;  ...getter/setter;}

           c. <hibernate-mapping package="ManyToOne">

              <class name="Group" table="group">   <id name="id" column="id">

              <generator class="identity"></generator>   </id>

              <property name="name" column="name"></property>  </class> </hibernate-mapping>

          d. <hibernate-mapping package="ManyToOne">  <class name="User2" table="user2">

            <id name="id" column="id">     <generator class="identity"/>   </id>

             <property name="name" column="name"></property>

            <many-to-one name="group" column="group_id" fetch="join"></many-to-one>

            </class> </hibernate-mapping>  //關系由many端進行維護

           e.關聯(lián)雙方:Group group=new Group();    group.setId(1);  User2 user=new User2(); user.setName("hello");    user.setGroup(group);   //session.save()才行



          5.ont to many:(
          環(huán)境:一個人有多個地址,fk:address.user_idàuser.id)

           a. public class MyUser {  private Integer id;  private String name;

             private Set<Address> addresses;  } //對應多個值采用集合形式

           b. public class Address { private Integer id;  private String address;

          private MyUser user; }

           c. <hibernate-mapping package="ManyToOne"> <class name="MyUser" table="myuser">

              <id name="id" column="id">  <generator class="identity"/>    </id>

                 <property name="name" column="name"></property>

              <set name="addresses" cascade="all" inverse="true" order-by="address asc" fetch="join">  <key column="user_id"></key>  //必須通過外表的外鍵建立的關聯(lián)

                Inverse=”true”進行反轉(zhuǎn),many端來維護關聯(lián)

          <one-to-many class="Address"/>  </set>  </class>  </hibernate-mapping>

           d. <hibernate-mapping package="ManyToOne"> <class name="Address" table="address">

                <id name="id" column="id">   <generator class="identity"/>  </id>

                <property name="address" column="address"></property>

              <many-to-one name="user" column="user_id"></many-to-one> </class> </hibernate-mapping>

           e.使用時要設置關聯(lián):MyUser user=new MyUser();user.setName(“hello”);

             Set<Address> addresses=new HashSet<Address>();

             Address add1=new Address();add1.setZipcode(“241000”);

             add1.setUser(user);  addresses.add(add1);  user.setAddresses(addresses);

           




          .HQL:特點:語法類似sql,使用面向?qū)ο蟮姆庋b,直接返回對象或?qū)ο髷?shù)組

          1.查詢整個實體對象(不加select)

          String hql="from com.mypack.User4"; Query  query=session.createQuery(hql);

               List lists=query.list();   for(int i=0;i< lists.size();i++){

          User4 user=(User4)lists.get(i);   System.out.println(user.getId());   }

          或者: for(Iterator iter=users.iterator();iter.hasNext();){

               User4 user=(User4)iter.next(); }




          2.
          查詢單個屬性(返回單個屬性類型): hql="select u.name from User4 u";

                 query=session.createQuery(hql);   List names=query.list();//執(zhí)行查詢

                 for(int i=0;i<names.size();i++){   String name=(String)names.get(i);    }



          3.1
          查詢多個屬性返回對象數(shù)組的集合: hql="select u.name,u.age from User4 u";

                 query=session.createQuery(hql);     List names=query.list();//一步步轉(zhuǎn)型

                 for(int i=0;i<names.size();i++){   Object[ ] object=(Object[])names.get(i);

                     String name=(String)object[0];        Integer age=(Integer)object[1];



          3.2
          也可以將多個屬性用單個屬性替代: hql="select new User4(u.name,u.age) from User4 u";

                 query=session.createQuery(hql);   List names=query.list();

                 for(int i=0;i<names.size();i++){   User4 user=(User4)names.get(i); }

             :需要在User4中添加User4(name,age)構造函數(shù),同時添加無參構造函數(shù)防止影響其他代碼



          4.
          聚合函數(shù)也可以使用: hql="select count(*) from User4 u";

                 query=session.createQuery(hql);   int count=(Integer)query.list().get(0);

                 System.out.println(count);

            當確定只有唯一的一個結果: int count=(Integer)query.uniqueResult(); 代替



          5.
          更新(需要加上Transaction): Transaction tr=session.beginTransaction();

                                       hql="update User4 u set u.name='liming'";

                query=session.createQuery(hql);     query.executeUpdate();   tr.commit();




          6.
          刪除操作: Transaction tr2=session.beginTransaction();

                      hql="delete from User4 u where u.id=81";

                      query=session.createQuery(hql);   query.executeUpdate();  tr2.commit();



          7.1.?
          查詢綁定: hql="from User4 u  where u.name=?";

          query=session.createQuery(hql); query.setString(0, "lm"); List user= query.list();




          7.2.
          引用占位符:查詢綁定: hql="from User4 u where u.name=:name and u.id=:id";

                query=session.createQuery(hql);

                query.setInteger("id", 84);     query.setParameter("name", "lm");推薦使用

                List user1= query.list(); assertEquals(8, user1.size());



          8.
          分頁查詢功能: hql="from User4 u order by u.id";  query=session.createQuery(hql);

          query.setFirstResult(2);從零計數(shù) query.setMaxResults(10);//十分方便數(shù)據(jù)庫的移植

                List userlist=query.list();     for(int i=0;i<userlist.size();i++){

                User4 name=(User4)userlist.get(i); System.out.println(name.getId()); }



          9.
          同樣支持原生SQL語句: String sql="select id ,name, age from t_user4";

               Query sqlQuery=session.createSQLQuery(sql);

               List result =sqlQuery.list(); for(Iterator it=result.iterator();it.hasNext();){

                   Object[] obj=(Object[])it.next();  Integer id=(Integer)obj[0];

                   String name=(String)obj[1];        Integer age=(Integer)obj[2]; }

            利用得到的數(shù)據(jù): List<User4> users=new ArrayList();

                           User4 user4=new User4(); user4.setId(id); users.add(user4);

          posted on 2007-08-15 11:02 mrklmxy 閱讀(1548) 評論(2)  編輯  收藏

          評論

          # re: Hibernate關系映射和HQL 2007-09-26 14:30 Leasen

          整理的太好了 非常的感謝你!  回復  更多評論   

          # re: Hibernate關系映射和HQL 2008-02-01 16:03 超哥

          不錯,很好,非常感謝!  回復  更多評論   


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 临汾市| 合川市| 屯昌县| 昭通市| 酉阳| 杭锦后旗| 灵璧县| 安化县| 东山县| 普兰店市| 灵宝市| 友谊县| 西宁市| 罗城| 定西市| 天峨县| 鄂托克前旗| 社会| 盐津县| 论坛| 名山县| 科技| 临湘市| 买车| 张家川| 兴山县| 定结县| 班玛县| 鄂托克前旗| 临邑县| 葵青区| 米泉市| 盐池县| 苍溪县| 石门县| 阜宁县| 共和县| 邹城市| 南岸区| 武冈市| 仙游县|