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

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

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

    hibernate 一級緩存:(緩存的是實體對象)

    一級緩存很短和session的生命周期一致,一級緩存也叫session級的緩存或事務(wù)緩存

     

    哪些方法支持一級緩存:

    *get()

    *load()

    *iterate()  (查詢實體對象)

     

    如何管理一級緩存:

    * session.clear() session.evict()

     

    如何避免一次性大量的實體數(shù)據(jù)入庫導(dǎo)致內(nèi)存溢出

    *先flush,再clear

     

    如果數(shù)據(jù)量特別大,考慮采用jdbc實現(xiàn),如果jdbc也不能滿足要求,可以考慮采用數(shù)據(jù)庫本身的特定導(dǎo)入工具

     

    一.Load測試: 在同一個session中發(fā)出兩次load查詢

           Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

     

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

           在同一個session中發(fā)出兩次load查詢,第一次load的時候不會去查詢數(shù)據(jù)庫,因為他是LAZY的,當(dāng)使用的時候才去查詢數(shù)據(jù)庫,  第二次load的時候也不會,當(dāng)使用的時候也不會查詢數(shù)據(jù)庫,因為他在緩存里找到,不會發(fā)出sql

     

     

    Load測試: 開啟兩個session中發(fā)出兩次load查詢

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

    sessioin.close();

    ………..

           sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

           開啟兩個session中發(fā)出兩次load查詢,第一次load的時候不會去查詢數(shù)據(jù)庫,因為他是LAZY的,當(dāng)使用的時候才去查詢數(shù)據(jù)庫,  第二次load的時候也不會,當(dāng)使用的時候查詢數(shù)據(jù)庫,因為session間不能共享一級緩存的數(shù)據(jù),因為他會隨session的生命周期存在和消亡

     

     

    二.Get測試: 在同一個session中發(fā)出兩次get查詢

        Student sutdent = (Student)session.get(Student.class,1);

           System.out.println(student.getName());

     

           sutdent = (Student)session.get(Student.class,1);

           System.out.println(student.getName());

           在同一個session中發(fā)出兩次get查詢, 第一次get的時候去查詢數(shù)據(jù)庫,第二次get的時候不會查詢數(shù)據(jù)庫,因為他在緩存里找到,不會發(fā)出sql

     

     

    三.iterate測試: 在同一個session中發(fā)出兩次iterator查詢

    Student student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();

    System.out.println(student.getName());

     

    student = (Student)session.createQuery(“from Student s where s.id=1”).iterate().next();

    System.out.println(student.getName());

           在同一個session中發(fā)出兩次iterator查詢,第一次iterate().next()的時候會發(fā)出查詢id的sql,使用的時候會發(fā)出相應(yīng)的查詢實體對象,第二次iterate().next()的時候會發(fā)出查詢id的sql,不會發(fā)出查詢實體對象的sql,因為iterate使用緩存,不會發(fā)出sql

     

     

    四.Iterate查詢屬性測試: 同一個session中發(fā)出兩次查詢屬性

    String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();

    System.out.println(name);

     

    String name = (String)session.createQuery(“select s.name from Student s where s.id=1”).iterate().next();

    System.out.println(name);

           在同一個session中發(fā)出兩次查詢屬性, 第一次iterate().next()的時候會發(fā)出查詢屬性的sql,第二次iterate().next()的時候會發(fā)出查詢屬性的sql,iterate查詢普通屬性,一級緩存不會緩存,所以會發(fā)出sql

     

     

    五.同一個session中先save,再發(fā)出load查詢save過的數(shù)據(jù)

     

           Student stu = new Student();

           stu.setName(“王五”);

     

       Serializable id = session.save(stu);

     

    Student sutdent = (Student)session.load(Student.class,id);

           System.out.println(student.getName());

     

          

    save的時候,他會在緩存里放一份,不會發(fā)出sql,因為save是使用緩存的

    六.同一個session中先調(diào)用load查詢,然后執(zhí)行sessio.clear()session.evict(),再調(diào)用load查詢

     

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

           session.clear();

     

    Student sutdent = (Student)session.load(Student.class,1);

           System.out.println(student.getName());

     

     

           sessio.clear()或session.evict()可以管理一級緩存,一級緩存無法取消,但可以管理.

    上面的語句都會發(fā)出sql 因為一級緩存中的實體被清除了

     

    七.向數(shù)據(jù)庫中批量加入1000條數(shù)據(jù)

     

    for(int i=0;i<1000;i++){

           Student student = new Student();

           student.setName(“s” + i);

           session.save(student);

    //每20條數(shù)據(jù)就強制session將數(shù)據(jù)持久化,同時清除緩存,避免大量數(shù)據(jù)造成內(nèi)存溢出

           if( i %20 == 0 ){

                  session.flush();

                  session.clear();

    }

    }

     

    posted @ 2009-04-06 11:59 胡鵬 閱讀(414) | 評論 (0)編輯 收藏

     

    hibernate查詢緩存(hibernate默認(rèn)是關(guān)閉的)

     

    查詢緩存是針對普通屬性結(jié)果集的緩存

    對實體對象的結(jié)果集只緩存id

     

    查詢緩存的生命周期,當(dāng)前關(guān)聯(lián)的表發(fā)生修改,那么查詢緩存生命周期結(jié)束

     

    查詢緩存的配置和使用:

    1. 啟用查詢緩存:在hibernate.cfg.xml中加入:

    <property name=”hibernate.cache.use_query_cache”>true</property>

      2. 在程序中必須手動啟用查詢緩存,如:query.setCacheable(true);

     

     

    測試查詢緩存:

    一.  開啟查詢緩存,關(guān)閉二級緩存,開啟一個session,分別調(diào)用query.list  (查詢屬性)

     

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    List names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

     

    System.out.println(“------------------------------------------”);

     

    query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

    第二次沒有去查詢數(shù)據(jù)庫,因為啟用了查詢緩存

     

    二.  開啟查詢緩存,關(guān)閉二級緩存,開啟兩個session,分別調(diào)用query.list  (查詢屬性)

     

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    List names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    List names = query.list();

    for(Iterator iter = names.terator();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

    第二次沒有去查詢數(shù)據(jù)庫,因為查詢緩存生命周期與session生命周期無關(guān)

     

    三.  開啟查詢緩存,關(guān)閉二級緩存,開啟兩個session,分別調(diào)用query.iterate (查詢屬性)

     

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    for(Iterator iter =query.iterate();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“select s.name from Student s”);

    //啟用查詢緩存

    query.setCacheable(true);

     

    for(Iterator iter = query.iterate();iter.hasNext();){

           String name = (String)iter.next();

           System.out.println(name);

    }

    第二去查詢數(shù)據(jù)庫,因為查詢緩存只對query.list()起作用,對query.iterate()不起作用,也就是說query.iterate()不使用查詢緩存

     

    四.  關(guān)閉查詢緩存,關(guān)閉二級緩存,開啟兩個session,分別調(diào)用query.list (查詢實體對象)

     

    Query query = session.createQuery(“ from Student s”);

    //query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“ from Student s”);

    //query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

    第二去查詢數(shù)據(jù)庫,因為list默認(rèn)每次都會發(fā)出查詢sql

     

    五.  開啟查詢緩存,關(guān)閉二級緩存,開啟兩個session,分別調(diào)用query.list (查詢實體對象)

     

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    第二去查詢數(shù)據(jù)庫時,會發(fā)出N條sql語句,因為開啟了查詢緩存,關(guān)閉了二級緩存,那么查詢緩存會緩存實體對象的id,所以hibernate會根據(jù)實體對象的id去查詢相應(yīng)的實體,如果緩存中不存在相應(yīng)的實體,那么將發(fā)出根據(jù)實體id查詢的sql語句,否則不會發(fā)出sql,使用緩存中的數(shù)據(jù)

     

    六.  開啟查詢緩存,開啟二級緩存,開啟兩個session,分別調(diào)用query.list (查詢實體對象)

     

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    session.close();

     

    System.out.println(“------------------------------------------”);

    ………

    Query query = session.createQuery(“ from Student s”);

    query.setCacheable(true);

    List students = query.list();

    for(Iterator iter = students.iterate();iter.hasNext();){

           Student stu = (Student)iter.next();

           System.out.println(stu.getName());

    }

     

    第二不會發(fā)出sql,因為開啟了二級緩存和查詢緩存,查詢緩存緩存了實體對象的id列表,hibernate會根據(jù)實體對象的id列表到二級緩存中取得相應(yīng)的數(shù)據(jù)

    posted @ 2009-04-06 11:58 胡鵬 閱讀(4884) | 評論 (0)編輯 收藏

    悲觀鎖

          

           悲觀鎖的實現(xiàn),通常依賴于數(shù)據(jù)庫機制,在整個過程中將數(shù)據(jù)鎖定,其它任何用戶都不能讀取或修改。

     

    舉個例子:

    //查詢id=1的那條記錄,使用悲觀鎖

    User user = (User)session.load(User.class, 1 ,  LockMode.UPGRADE);

    使用了數(shù)據(jù)庫中的 for update  鎖定

     

    樂觀鎖

    大多數(shù)基于數(shù)據(jù)版本記錄機制(version)實現(xiàn),一半是在數(shù)據(jù)庫表加入一個version字段,讀取數(shù)據(jù)時將版本號一同讀出,之后更新數(shù)據(jù)時版本號加一,如果提交數(shù)據(jù)時版本號小于或等于數(shù)據(jù)庫表中的版本號,則認(rèn)為數(shù)據(jù)是過期的,否則給予更新。

     

    其實并非是鎖,是一種沖突檢測  (沒有hibernate也可以使用的,自己要在數(shù)據(jù)庫中建字段來控制,使用hibernate方便些,封裝好了)

     

    在*.hm.xml中 添加紅色部分:

                                                

    <class

    name="com.tao3c.orm.TbBusinessInfo"  table="tb_business_info"  optimistic-lock=”version”>

     

    其中version是com.tao3c.orm.TbBusinessInfo類的屬性,hiernbate會去維護的,不用自己去該

     

     

    posted @ 2009-04-06 11:57 胡鵬 閱讀(229) | 評論 (0)編輯 收藏

    悲觀鎖

          

           悲觀鎖的實現(xiàn),通常依賴于數(shù)據(jù)庫機制,在整個過程中將數(shù)據(jù)鎖定,其它任何用戶都不能讀取或修改。

     

    舉個例子:

    //查詢id=1的那條記錄,使用悲觀鎖

    User user = (User)session.load(User.class, 1 ,  LockMode.UPGRADE);

    使用了數(shù)據(jù)庫中的 for update  鎖定

     

    樂觀鎖

    大多數(shù)基于數(shù)據(jù)版本記錄機制(version)實現(xiàn),一半是在數(shù)據(jù)庫表加入一個version字段,讀取數(shù)據(jù)時將版本號一同讀出,之后更新數(shù)據(jù)時版本號加一,如果提交數(shù)據(jù)時版本號小于或等于數(shù)據(jù)庫表中的版本號,則認(rèn)為數(shù)據(jù)是過期的,否則給予更新。

     

    其實并非是鎖,是一種沖突檢測  (沒有hibernate也可以使用的,自己要在數(shù)據(jù)庫中建字段來控制,使用hibernate方便些,封裝好了)

     

    在*.hm.xml中 添加紅色部分:

                                                

    <class

    name="com.tao3c.orm.TbBusinessInfo"  table="tb_business_info"  optimistic-lock=”version”>

     

    其中version是com.tao3c.orm.TbBusinessInfo類的屬性,hiernbate會去維護的,不用自己去該

     

     

    posted @ 2009-04-06 11:57 胡鵬 閱讀(185) | 評論 (0)編輯 收藏

    hibernate中設(shè)置:

    查詢數(shù)據(jù)庫每次最多返回50條結(jié)果:

    <property name=”hibernate.jdbc.fetch_size”>50</property>

    30條更新數(shù)據(jù)庫一次:

    <property name= ”hibernatejdbc.batch_size”>30</property>

     但不是所有的數(shù)據(jù)庫都支持的,sqlServer orcale 都支持的。

     

    一.hibernate 抓取策略(Fetch) 單端代理批量抓取

     

    1.fetch=”select” 關(guān)聯(lián)實體

    //fetch 默認(rèn)是select

    <many-to-one name="businessId" column="business_id" insert="true" update="true" fetch="select">

     

    Student student = (Student)session.load(Student.class,1);

    System.out.println(student.getName());

    System.out.println(student.getClasses().getName()); //多對一中的屬性班級,獲取班級名稱

     

    Fetch=”select” ,上面程序會發(fā)2條sql語句,第二條發(fā)送一條select語句抓取當(dāng)前對象關(guān)聯(lián)實體或集合 (這里指是班級名稱)

     

    2.fetch=” join” 關(guān)聯(lián)實體

    //fetch 設(shè)置成 join

    <many-to-one name="businessId" column="business_id" insert="true" update="true"

    fetch=" join ">

     

    Student student = (Student)session.load(Student.class,1);

    System.out.println(student.getName());

    System.out.println(student.getClasses().getName()); //多對一中的屬性班級,獲取班級名稱

     

    fetch=” join” , 上面程序會發(fā)1條sql語句, hibernate會通過select使用外鏈接來加載其關(guān)聯(lián)實體或集合,此時lazy會失效 

     

    二.hibernate 抓取策略(Fetch) 集合代理批量抓取

     

    1.     fetch=”select”

    //fetch 默認(rèn)是select

    <set name="students" inverse="true" cascade="all" fetch="select">

                <key column="classid" />

                <one-to-many class="com.Student" />

    </set>

     

    Classes cla = (Classes)session.load(Classes.class,1);

    System.out.println(cla.getName());

    for(Iterator iter = cla.getStudents().iterator();iter.hasNext();){

           Student student = (Student)iter.next();

           System.out.println(student.getName());

    }

     

    fetch=”select” ,上面程序用到了就發(fā)sql語句,第二從循環(huán)中發(fā)了N條,如果:fetch=”subselect”,則只是發(fā)送一條語句,見下面

     

    2 fetch=”join”

    //fetch 設(shè)置成join

    <set name="students" inverse="true" cascade="all" fetch="join">

                <key column="classid" />

                <one-to-many class="com.Student" />

    </set>

     

    Classes cla = (Classes)session.load(Classes.class,1);

    System.out.println(cla.getName());

    for(Iterator iter = cla.getStudents().iterator();iter.hasNext();){

           Student student = (Student)iter.next();

           System.out.println(student.getName());

    }

     

    Fetch=”select” ,上面程序只發(fā)了一條sql語句

     

     

    三.hibernate 抓取策略(Fetch) 集合代理批量抓取

     

    2.     fetch=”subselect”

    //fetch設(shè)置成subselect

    <set name="students" inverse="true" cascade="all" fetch="subselect">

                <key column="classid" />

                <one-to-many class="com.Student" />

    </set>

     

    List classesList = session.createQuery(“select c from Classes c where c.id in(1,2,3)”);

    for(Iterator iter=classesList.iterator();iter.hasNext();){

           Classess classess = (Classess)iter.next();

           System.out.println(“classes.name=”+ classes.getName());

           for(Iterator iter1 = classess.getStudents().iterator();iter1.hasNext();){

                  Student student = (Student)iter1.next();

                  System.out.println(student.getName());

    }

    }

     

    Fetch=”subselct” ,另外發(fā)送一條select語句抓取在前面查詢到的所有實體對象的關(guān)聯(lián)集合

     

     

    四.hibernate 批量策略batch-size屬性,可以批量加載實體類,

    參見Classes.hbm.xml,同時集合也可以是使用,如:

     <set name="students" inverse="true" cascade="save-update" batch-size=”5”>

     

    在配置文件hbm.xml 設(shè)置中:

    <class name="com.Classes " table="tb_classes" batch-size=”3”>

     

    List students = session.createQuery(“select s from Student s where s.id in(:ids)”).setParameterList(“:ids”,new Object[]{1,11,21,31,41,51,61,71,81,91}).list();

     

    for(Iterator iter=students.iterator();iter.hasNext();){

           Student student = (Sutdent)iter.next();

           System.out.println(student.getName());

           System.out.println(student.getClassess().getName());

     

    }

     

    當(dāng)?shù)诙€for循環(huán)時,每次加載 之前設(shè)置的 數(shù)量 實體對象,  如:現(xiàn)在設(shè)置3,那么當(dāng)Iterator iter=students.iterator();iter.hasNext();時候,他會查詢出3個student對象

    posted @ 2009-04-06 11:57 胡鵬 閱讀(459) | 評論 (0)編輯 收藏

    一.hibernate多對多映射(單項),自動產(chǎn)生第三張表

    User--à Role

    user(id,name)    role(id,name)

    User類:

    private int  id;   private String name;  private  Set roles;

     

    Role類:

    private int id;    private String name;

     

    User.hbm.xml中:

    <set name=”roles” table=”t_user_role”>

           <key column=”userid” />

           <many-to-many class=”com.Role” column=”roleid” />

    </set>

     

    這樣,hibernate會自動產(chǎn)生中間表t_user_role(userid,roleid) 并且是復(fù)合主鍵,userid為t_user的外鍵,roleid為t_role的外鍵

     

     

    二.hibernate多對多的存儲

     

    Role r1 = new Role();

    r1.setName(“數(shù)據(jù)錄入人員”);

     

    Role r2 = new Role();

    r2.setName(“商務(wù)主管”);

     

    Role r3 = new Role();

    r3.setName(“大區(qū)經(jīng)理”);

     

     

    User u1 = new User();

    u1.setName(“10”);

    Set u1Roles = new HashSet();

    u1Roles.add(r1);

    u1Roles.add(r2);

    u1.setRoles(u1Roles);

     

    User u2 = new User();

    u1.setName(“祖兒”);

    Set u2Roles = new HashSet();

    u2Roles.add(r2);

    u2Roles.add(r3);

    u2.setRoles(u2Roles);

    User u3 = new User();

    u3.setName(“杰倫”);

    Set u3Roles = new HashSet();

    u3Roles.add(r1);

    u3Roles.add(r2);

    u3Roles.add(r3);

    u3.setRoles(u3Roles);

     

     

    session.save(r1);

    session.save(r2);

    session.save(r3);

     

    session.save(u1);

    session.save(u2);

    session.save(u3);

     

    結(jié)束之后,在第三張表中也有數(shù)據(jù)

     

     

     

    三.hibernate多對多的加載

     

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

    System.out.println(user.getName());

    for(Iterator iter = user.getRoles().iterator();iter.hasNext();){

           Role role = (Role)iter.next();

           System.out.println(role.getName());

     

    }

     每次加載都會發(fā)出sql語句

     

    三.hibernate多對多的 雙向映射

     

    User ß--.-àRole

    user(id,name)    role(id,name)

    User類:

    private int  id;   private String name;  private Set roles;

     

    Role類:

    private int id;    private String name; private Set users;

     

    User.hbm.xml中:

    <set name=”roles” table=”t_user_role”>

           <key column=”userid” />

           <many-to-many class=”com.Role” column=”roleid” />

    </set>

     

    Role.hbm.xml中:

    <set name=”roles” table=”t_user_role”>   //這里可以設(shè)置order-by=”userid”,根據(jù)userid排序

           <key column=”roleid” />

           <many-to-many class=”com.User” column=”userid” />

    </set>

     

    注意,上面中間表名字是一樣的

    這樣,hibernate也會自動產(chǎn)生中間表t_user_role(userid,roleid) 并且是復(fù)合主鍵,userid為t_user的外鍵,roleid為t_role的外鍵

     

    posted @ 2009-04-06 11:56 胡鵬 閱讀(1155) | 評論 (0)編輯 收藏

    一.hibernate多對多映射(單項),自動產(chǎn)生第三張表

    User--à Role

    user(id,name)    role(id,name)

    User類:

    private int  id;   private String name;  private  Set roles;

     

    Role類:

    private int id;    private String name;

     

    User.hbm.xml中:

    <set name=”roles” table=”t_user_role”>

           <key column=”userid” />

           <many-to-many class=”com.Role” column=”roleid” />

    </set>

     

    這樣,hibernate會自動產(chǎn)生中間表t_user_role(userid,roleid) 并且是復(fù)合主鍵,userid為t_user的外鍵,roleid為t_role的外鍵

     

     

    二.hibernate多對多的存儲

     

    Role r1 = new Role();

    r1.setName(“數(shù)據(jù)錄入人員”);

     

    Role r2 = new Role();

    r2.setName(“商務(wù)主管”);

     

    Role r3 = new Role();

    r3.setName(“大區(qū)經(jīng)理”);

     

     

    User u1 = new User();

    u1.setName(“10”);

    Set u1Roles = new HashSet();

    u1Roles.add(r1);

    u1Roles.add(r2);

    u1.setRoles(u1Roles);

     

    User u2 = new User();

    u1.setName(“祖兒”);

    Set u2Roles = new HashSet();

    u2Roles.add(r2);

    u2Roles.add(r3);

    u2.setRoles(u2Roles);

    User u3 = new User();

    u3.setName(“杰倫”);

    Set u3Roles = new HashSet();

    u3Roles.add(r1);

    u3Roles.add(r2);

    u3Roles.add(r3);

    u3.setRoles(u3Roles);

     

     

    session.save(r1);

    session.save(r2);

    session.save(r3);

     

    session.save(u1);

    session.save(u2);

    session.save(u3);

     

    結(jié)束之后,在第三張表中也有數(shù)據(jù)

     

     

     

    三.hibernate多對多的加載

     

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

    System.out.println(user.getName());

    for(Iterator iter = user.getRoles().iterator();iter.hasNext();){

           Role role = (Role)iter.next();

           System.out.println(role.getName());

     

    }

     每次加載都會發(fā)出sql語句

     

    三.hibernate多對多的 雙向映射

     

    User ß--.-àRole

    user(id,name)    role(id,name)

    User類:

    private int  id;   private String name;  private Set roles;

     

    Role類:

    private int id;    private String name; private Set users;

     

    User.hbm.xml中:

    <set name=”roles” table=”t_user_role”>

           <key column=”userid” />

           <many-to-many class=”com.Role” column=”roleid” />

    </set>

     

    Role.hbm.xml中:

    <set name=”roles” table=”t_user_role”>   //這里可以設(shè)置order-by=”userid”,根據(jù)userid排序

           <key column=”roleid” />

           <many-to-many class=”com.User” column=”userid” />

    </set>

     

    注意,上面中間表名字是一樣的

    這樣,hibernate也會自動產(chǎn)生中間表t_user_role(userid,roleid) 并且是復(fù)合主鍵,userid為t_user的外鍵,roleid為t_role的外鍵

     

    posted @ 2009-04-06 11:56 胡鵬 閱讀(182) | 評論 (0)編輯 收藏

       

    單態(tài)定義:

    Singleton模式主要作用是保證在Java應(yīng)用程序中,一個類Class只有一個實例存在。

    在很多操作中,比如建立目錄 數(shù)據(jù)庫連接都需要這樣的單線程操作。

    還有, singleton能夠被狀態(tài)化; 這樣,多個單態(tài)類在一起就可以作為一個狀態(tài)倉庫一樣向外提供服務(wù),比如,你要論壇中的帖子計數(shù)器,每次瀏覽一次需要計數(shù),單態(tài)類能否保持住這個計數(shù),并且能synchronize的安全自動加1,如果你要把這個數(shù)字永久保存到數(shù)據(jù)庫,你可以在不修改單態(tài)接口的情況下方便的做到。

    另外方面,Singleton也能夠被無狀態(tài)化。提供工具性質(zhì)的功能,

    Singleton模式就為我們提供了這樣實現(xiàn)的可能。使用Singleton的好處還在于可以節(jié)省內(nèi)存,因為它限制了實例的個數(shù),有利于Java垃圾回收(garbage collection)。

    我們常常看到工廠模式中類裝入器(class loader)中也用Singleton模式實現(xiàn)的,因為被裝入的類實際也屬于資源。

    如何使用?

    一般Singleton模式通常有幾種形式:

    public class Singleton {

      private Singleton(){}

      //在自己內(nèi)部定義自己一個實例,是不是很奇怪?

      //注意這是private 只供內(nèi)部調(diào)用

      private static Singleton instance = new Singleton();

      //這里提供了一個供外部訪問本class的靜態(tài)方法,可以直接訪問  

      public static Singleton getInstance() {

        return instance;   

       }

    }

    第二種形式:

    public class Singleton {

      private static Singleton instance = null;

      public static synchronized Singleton getInstance() {

      //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次     

      //使用時生成實例,提高了效率!

      if (instance==null)

        instance=new Singleton();

      return instance;   }

    }

    使用Singleton.getInstance()可以訪問單態(tài)類。

    上面第二中形式是lazy initialization,也就是說第一次調(diào)用時初始Singleton,以后就不用再生成了。

    注意到lazy initialization形式中的synchronized,這個synchronized很重要,如果沒有synchronized,那么使用getInstance()是有可能得到多個Singleton實例。關(guān)于lazy initialization的Singleton有很多涉及double-checked locking (DCL)的討論,有興趣者進一步研究。

    一般認(rèn)為第一種形式要更加安全些。

    使用Singleton注意事項:

    有時在某些情況下,使用Singleton并不能達到Singleton的目的,如有多個Singleton對象同時被不同的類裝入器裝載;在EJB這樣的分布式系統(tǒng)中使用也要注意這種情況,因為EJB是跨服務(wù)器,跨JVM的。

    我們以SUN公司的寵物店源碼(Pet Store 1.3.1)的ServiceLocator為例稍微分析一下:

    在Pet Store中ServiceLocator有兩種,一個是EJB目錄下;一個是WEB目錄下,我們檢查這兩個ServiceLocator會發(fā)現(xiàn)內(nèi)容差不多,都是提供EJB的查詢定位服務(wù),可是為什么要分開呢?仔細研究對這兩種ServiceLocator才發(fā)現(xiàn)區(qū)別:在WEB中的ServiceLocator的采取Singleton模式,ServiceLocator屬于資源定位,理所當(dāng)然應(yīng)該使用Singleton模式。但是在EJB中,Singleton模式已經(jīng)失去作用,所以ServiceLocator才分成兩種,一種面向WEB服務(wù)的,一種是面向EJB服務(wù)的。

    Singleton模式看起來簡單,使用方法也很方便,但是真正用好,是非常不容易,需要對Java的類 線程內(nèi)存等概念有相當(dāng)?shù)牧私狻?/p>

    總之:如果你的應(yīng)用基于容器,那么Singleton模式少用或者不用,可以使用相關(guān)替代技術(shù)。

    posted @ 2009-04-06 11:55 胡鵬 閱讀(323) | 評論 (0)編輯 收藏
      
       

    1.兩種配置文件:

    A.hibernate.cfg.xml和B.hibernate.properties

     

    A中可含映射文件的配置,而B中hard codes加映射文件。

     

    A.Configuration config=new Configuration().config();

    B. Configuration config=new Configuration();

    config.addClass(TUser.class);

     

    2.你不必一定用hibernate.cfg.xml或hibernate.properties這兩文件名,你也不一定非得把配置文件放在Classes下, File file=new File("c:\\sample\\myhibernate.xml"); Configuration config=new Configuration().config(file);

     

    3. session.Flush() 強制數(shù)據(jù)庫立即同步,當(dāng)用事務(wù)時,不必用flush,事務(wù)提交自動調(diào)用flush在session關(guān)閉時也會調(diào)用flush

     

    4. Hibernate總是使用對象類型作為字段類型

     

    5. XDoclet專門建立了hibernate doclet,就是在java代碼上加上一些java docTag,后來再讓XDoclet分析該java代碼,生成映射文件;

     

    6.HQL子句本身大小寫無關(guān),但是其中出現(xiàn)的類名和屬性名必須注意大小寫區(qū)分。

     

    7.關(guān)系: Constrained : 約束,表明主控表的主鍵上是否存在一個外鍵(foreigh key)對其進行約束。

     

    property-ref:關(guān)聯(lián)類中用于與主控類相關(guān)聯(lián)的屬性名,默認(rèn)為關(guān)聯(lián)類的主鍵屬性名

     

    單向一對多需在一方配置,雙向一對多需在雙方進行配置

     

    8.lazy=false:被動方的記錄由hibernate負(fù)責(zé)記取,之后存放在主控方指定的Collection類型屬性中

     

    9. java.util.Set或net.sof.hibernate.collecton.Bag類型的Collection

     

    10.重要:inverse:用于標(biāo)識雙向關(guān)聯(lián)中的被動方一端。

     

    inverse=false的一方(主控方)負(fù)責(zé)維護關(guān)聯(lián)關(guān)系.默認(rèn)值:false

     

    11.batch-size:采用延遲加載特征時,一次讀入的數(shù)據(jù)數(shù)昨。

     

    12.一對多通過主控方更新(主控方為一方時)

     

    user.getAddresses().add(addr);

     

    session.save(user);//通過主控對象級聯(lián)更新

     

    13.在one-to-many 關(guān)系中,將many 一方設(shè)為主動方(inverse=false)將有助性能的改善。在一方設(shè)置關(guān)系時,inverse=true,即將主控權(quán)交給多方, 這樣多方可主動從一方獲得foreign key,然后一次insert即可完工。

     

    addr.setUser(user);//設(shè)置關(guān)聯(lián)的TUser對象

     

    user.getAddresses().add(addr);

     

    session.save(user);//級聯(lián)更新

     

    14.只有設(shè)為主控方的一方才關(guān)心(訪問)對方的屬性,被動方是不關(guān)心對方的屬性的。

     

    15.one-to-many與many-to-one節(jié)點的配置屬性不同:

     

    一對多關(guān)系多了lazy和inverse兩個屬性多對多節(jié)點屬性:

     

    column:中間映射表中,關(guān)聯(lián)目標(biāo)表的關(guān)聯(lián)字段

     

    class:類名,關(guān)聯(lián)目標(biāo)類

     

    outer-join:是否使用外聯(lián)接

     

    注意:access是設(shè)置屬性值的讀取方式。

     

    column是設(shè)置關(guān)聯(lián)字段。

     

    16.多對多,注意兩方都要設(shè)置inverse和lazy,cascade只能設(shè)為insert-update

     

    多對多關(guān)系中,由于關(guān)聯(lián)關(guān)系是兩張表相互引用,因此在保存關(guān)系狀態(tài)時必須對雙方同時保存。

     

    group1.getRoles().add(role1); role1.getGroups().add(group1);

     

    session.save(role1); session.save(group1);

     

    17.關(guān)于vo和po vo經(jīng)過hibernate容量處理,就變成了po(該vo的引用將被容器保存,并且在session關(guān)閉時flush,因此po如果再傳到其它地方改變了,就危險了) vo和po相互轉(zhuǎn)換:BeanUtils.copyProperties(anotherUser,user);

     

    18.對于save操作而言,如果對象已經(jīng)與Session相關(guān)聯(lián)(即已經(jīng)被加入Session的實體容器中),則無需進行具體的操作。因為之后的Session.flush過程中,Hibernate 會對此實體容器中的對象進行遍歷,查找出發(fā)生變化的實體,生成并執(zhí)行相應(yīng)的update 語句。

     

    19.如果我們采用了延遲加載機制,但希望在一些情況下,實現(xiàn)非延遲加載時的功能,也就是說,我們希望在Session關(guān)閉后,依然允許操作user的addresses 屬性 Hibernate.initialize方法可以通過強制加載關(guān)聯(lián)對象實現(xiàn)這一功能: 這也正是我們?yōu)槭裁丛诰帉慞OJO時,必須用JDK Collection接口(如Set,Map), 而非特定的JDK Collection實現(xiàn)類(如HashSet、HashMap)申明Collection屬性的 原因。

     

    20.事務(wù):從sessionFactory獲得session,其自動提交屬性就已經(jīng)關(guān)閉(AutoCommit=false),此時若執(zhí)行了jdbc操作,如果不顯式調(diào)用session.BeginTransaction(),是不會執(zhí)行事務(wù)操作的。

     

    jdbc transaction:基于同一個session(就是同一個connection)的事務(wù);

     

    jta transaction:跨session(跨connection)事務(wù).

     

    對于jta事務(wù),有三種實現(xiàn)方法:

     

    A。UserTransaction tx=new InitialContext().lookup("...");

    tx.commit();

     

    B. 使用hibernate封裝的方法:(不推薦)

     

    Transaction tx=session.beginTransaction();

    tx.commit();

    C. 使用ejb之sessionBean的事務(wù)技持方法,你只要在把需要在發(fā)布描述符中,把需要jta事務(wù)的方法聲明為require即可

     

    21.悲觀鎖,樂觀鎖: 樂觀鎖一般通過version來實現(xiàn),注意version節(jié)點必須出現(xiàn)在id后。

     

    22.Hibernate中,可以通過Criteria.setFirstResult和Criteria.setFetchSize方法設(shè)定分頁范圍。

     

    Query接口中也提供了與其一致的方法,hibernate主要在dialect類中實現(xiàn)在這個功能。

     

    23.cache

     

    ……

     

    net.sf.ehcache.hibernate.Provider 

     

    還需對ecache本身進配置

     

     

     

    之后在映射文件中指定各個映射實體的cache策略

     

     

    ....

     

     

    ....

     

     

    ***************************************************** Query.list()跟Query.iterate()的不同:對于query.list()總是通過一條sql語句獲取所有記錄,然后將其讀出,填入pojo返回; 但是query.iterate(),則是首先通過一條Select SQL 獲取所有符合查詢條件的記錄的 id,再對這個id 集合進行循環(huán)操作,通過單獨的Select SQL 取出每個id 所對應(yīng)的記 錄,之后填入POJO中返回。

     

    也就是說,對于list 操作,需要一條SQL 完成。而對于iterate 操作,需要n+1 條SQL。,list方法將不會從Cache中讀取數(shù)據(jù)。iterator卻會。

     

    24.ThreadLocal:它會為每個線程維護一個私有的變量空間。實際上, 其實現(xiàn)原理是在JVM 中維護一個Map,這個Map的key 就是當(dāng)前的線程對象,而value則是線程通過ThreadLocal.set方法保存的對象實例。當(dāng)線程調(diào)用ThreadLocal.get方法時, ThreadLocal會根據(jù)當(dāng)前線程對象的引用,取出Map中對應(yīng)的對象返回。

     

    這樣,ThreadLocal通過以各個線程對象的引用作為區(qū)分,從而將不同線程的變量隔離開來。

     

    25.Hibernate官方開發(fā)手冊標(biāo)準(zhǔn)示例:

     

    public class HibernateUtil { private static SessionFactory sessionFactory;

    static { try { // Create the SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

    } catch (HibernateException ex) { throw new RuntimeException( "Configuration problem: " + ex.getMessage(), ex );

    } } public static final ThreadLocal session = new ThreadLocal();

    public static Session currentSession() throws HibernateException { Session s = (Session) session.get();

    // Open a new Session, if this Thread has none yet if (s == null) { s = sessionFactory.openSession();

    session.set(s);

    } return s;

    } public static void closeSession() throws HibernateException { Session s = (Session) session.get();

    session.set(null);

    if (s != null) s.close();

    } }

     

    26.通過filter實現(xiàn)session的重用:

     

    public class PersistenceFilter implements Filter { protected static ThreadLocal hibernateHolder = new ThreadLocal();

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { hibernateHolder.set(getSession());

    try { …… chain.doFilter(request, response);

    …… } finally { Session sess = (Session)hibernateHolder.get();

    if (sess != null) { hibernateHolder.set(null);

    try { sess.close(); } catch (HibernateException ex) { throw new ServletException(ex);

    } } } } ……}

    posted @ 2009-04-06 11:53 胡鵬 閱讀(213) | 評論 (0)編輯 收藏
    Eclipse快捷鍵指南   

    有些還是比叫有用的,不過不是很全


    編輯
    作用域 功能 快捷鍵
    全局 查找并替換 Ctrl+F
    文本編輯器 查找上一個 Ctrl+Shift+K
    文本編輯器 查找下一個 Ctrl+K
    全局 撤銷 Ctrl+Z
    全局 復(fù)制 Ctrl+C
    全局 恢復(fù)上一個選擇 Alt+Shift+↓
    全局 剪切 Ctrl+X
    全局 快速修正 Ctrl1+1
    全局 內(nèi)容輔助 Alt+/
    全局 全部選中 Ctrl+A
    全局 刪除 Delete
    全局 上下文信息 Alt+?
    Alt+Shift+?
    Ctrl+Shift+Space
    Java編輯器 顯示工具提示描述 F2
    Java編輯器 選擇封裝元素 Alt+Shift+↑
    Java編輯器 選擇上一個元素 Alt+Shift+←
    Java編輯器 選擇下一個元素 Alt+Shift+→
    文本編輯器 增量查找 Ctrl+J
    文本編輯器 增量逆向查找 Ctrl+Shift+J
    全局 粘貼 Ctrl+V
    全局 重做 Ctrl+Y

    查看
    作用域 功能 快捷鍵
    全局 放大 Ctrl+=
    全局 縮小 Ctrl+-


    窗口
    作用域 功能 快捷鍵
    全局 激活編輯器 F12
    全局 切換編輯器 Ctrl+Shift+W
    全局 上一個編輯器 Ctrl+Shift+F6
    全局 上一個視圖 Ctrl+Shift+F7
    全局 上一個透視圖 Ctrl+Shift+F8
    全局 下一個編輯器 Ctrl+F6
    全局 下一個視圖 Ctrl+F7
    全局 下一個透視圖 Ctrl+F8
    文本編輯器 顯示標(biāo)尺上下文菜單 Ctrl+W
    全局 顯示視圖菜單 Ctrl+F10
    全局 顯示系統(tǒng)菜單 Alt+-


    導(dǎo)航
    作用域 功能 快捷鍵
    Java編輯器 打開結(jié)構(gòu) Ctrl+F3
    全局 打開類型 Ctrl+Shift+T
    全局 打開類型層次結(jié)構(gòu) F4
    全局 打開聲明 F3
    全局 打開外部javadoc Shift+F2
    全局 打開資源 Ctrl+Shift+R
    全局 后退歷史記錄 Alt+←
    全局 前進歷史記錄 Alt+→
    全局 上一個 Ctrl+,
    全局 下一個 Ctrl+.
    Java編輯器 顯示大綱 Ctrl+O
    全局 在層次結(jié)構(gòu)中打開類型 Ctrl+Shift+H
    全局 轉(zhuǎn)至匹配的括號 Ctrl+Shift+P
    全局 轉(zhuǎn)至上一個編輯位置 Ctrl+Q
    Java編輯器 轉(zhuǎn)至上一個成員 Ctrl+Shift+↑
    Java編輯器 轉(zhuǎn)至下一個成員 Ctrl+Shift+↓
    文本編輯器 轉(zhuǎn)至行 Ctrl+L


    搜索
    作用域 功能 快捷鍵
    全局 出現(xiàn)在文件中 Ctrl+Shift+U
    全局 打開搜索對話框 Ctrl+H
    全局 工作區(qū)中的聲明 Ctrl+G
    全局 工作區(qū)中的引用 Ctrl+Shift+G


    文本編輯
    作用域 功能 快捷鍵
    文本編輯器 改寫切換 Insert
    文本編輯器 上滾行 Ctrl+↑
    文本編輯器 下滾行 Ctrl+↓


    文件
    作用域 功能 快捷鍵
    全局 保存 Ctrl+X
    Ctrl+S

    posted @ 2009-04-06 11:46 胡鵬 閱讀(275) | 評論 (0)編輯 收藏
    僅列出標(biāo)題
    共10頁: First 上一頁 2 3 4 5 6 7 8 9 10 下一頁 

    導(dǎo)航

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    統(tǒng)計

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    agile

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产成人高清精品免费观看| 99爱在线观看免费完整版 | 久久久久亚洲av毛片大| 国产真人无码作爱视频免费 | 亚洲综合小说另类图片动图| 亚洲av成人一区二区三区在线观看| 日韩免费的视频在线观看香蕉| 亚洲中文字幕一二三四区| 亚洲精品色婷婷在线影院| 5g影院5g天天爽永久免费影院| 亚洲国产成人AV在线播放| 亚洲va久久久噜噜噜久久| 免费高清在线影片一区| 免费人成网站在线观看不卡| 亚洲精品久久无码| 午夜亚洲AV日韩AV无码大全| 国产一级淫片免费播放| 18未年禁止免费观看| 成人免费网站久久久| 亚洲日韩精品无码专区加勒比 | 免费国产成人高清在线观看麻豆 | 亚洲精品制服丝袜四区| 国产成人精品高清免费| 亚洲三级在线免费观看| 三年在线观看免费观看完整版中文| 亚洲色偷偷色噜噜狠狠99网| 亚洲成熟xxxxx电影| 亚洲一区日韩高清中文字幕亚洲 | 久久亚洲精品国产精品黑人| 国产在线观看免费不卡| 综合在线免费视频| 日本免费人成网ww555在线| 日韩久久无码免费毛片软件| 亚洲黄色激情视频| 7777久久亚洲中文字幕蜜桃| 亚洲永久精品ww47| 亚洲日韩中文在线精品第一| 日韩免费视频在线观看| 大地资源在线观看免费高清| 久久久久久精品免费免费自慰| 国产一级高青免费|