国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
寶寶 Hibernate學習總結
Hibernate是一個開放源代碼的ORM(對象關系映射)框架,它對JDBC進行了輕量級的封裝,Java程序員可以使用面向對象的編程思維來操縱數(shù)據(jù)庫,它通過對象屬性和數(shù)據(jù)庫表字段之間的映射關系,將對象持久化到數(shù)據(jù)庫中,可以說Hibernate就是將數(shù)據(jù)從對象形式轉換成表字段后存入數(shù)據(jù)庫的一種框架。hibernate移植非常好,因為它用到了方言配置,可以根據(jù)不同的數(shù)據(jù)庫自動發(fā)出不同的sql。


下面是我感覺比較重要的方面就列出來了:
首先是搭建環(huán)境:
    1、我建的是個Java項目,第一步先引入HIbernate的jar包:hibernate3.jar這是核心包,還有l(wèi)ib下的所有包。
 
    2、我用oracle做測試,所以在引入oracle的驅動包,classes12.jar。
 
   3、在從源碼包中拷貝一個hibernate.cfg.xml(放到src下,而且這個文件的配置可以參考etc/hibernate.properties      這個文件)這是Hibernate的默認配置文件名字,和User.hbm.xml(此文件跟你的pojo放在一塊)映射配置文件。
這樣Hibernate的環(huán)境基本上就搭建好了。

4、hibernate可以根據(jù)映射文件和pojo自動創(chuàng)建數(shù)據(jù)庫表(用SchemaExport這個類)。

5、hibernate默認事務是手動的,所以我們必須手動獲取事務,開啟和關閉它。

6、在hibernate中持久化對象有三個狀態(tài),這個面試時可能會問到:
 (1)transient瞬時態(tài):在數(shù)據(jù)庫中沒有與之匹配的數(shù)據(jù),一般就是只new出了這個對象,并且在session緩存中也沒有即此對象沒                有納入session的管理,此狀態(tài)的對象不能直接存入數(shù)據(jù)庫(會拋出TransientObjectException)。
 (2)persistent持久態(tài):在數(shù)據(jù)庫中有與之匹配的數(shù)據(jù),并且納入了session的管理(一般就是執(zhí)行了save、update、load、get                  后的對象),在提交事務時(清理session緩存時)會和數(shù)據(jù)庫同步更新,持久態(tài)對象才可以存入數(shù)據(jù)                 庫。
 (3)detached游離態(tài):在數(shù)據(jù)庫中有與之匹配的數(shù)據(jù),但沒有納入session緩存的管理。
 
7、(1)    討論下hibernate的增(save)、刪(delete)、改(update)、查(get,load)。
       增沒什么說的,關于刪除和修改時我們完全可以new出一個對象進行操作,只要給這個對象的標示賦值為庫中存在的對象就行了,這個過程應該是這樣的,當我們new出對象后并設置了相應的id(標示),然后執(zhí)行session.delete()或者session.update()后,此對象在session緩存中就有了一份,再當我們commit提交
       事務時(清理緩存),數(shù)據(jù)庫中有同樣id標示的對象就會與session緩存中的持久態(tài)對象進行同步更新,所以這樣更新和刪除完全可以實現(xiàn),但是我們一般不能這么做,   最好是先查出來在去更新或者刪除,比如:當我們要更新一個User對象時,沒有先查出來而是用new的方法并給這個新對象設置了一個與庫中有對應ID的形式去更新,那么更新完后,如果沒有賦值的屬性都會變成null,這個可不是我們想要的結果哦。
   
    (2)在說說get和load這兩個單一對象的查詢方法:
        <1>get方法不支持lazy延遲加載,即一執(zhí)行到get方法立刻發(fā)出sql語句,而load有延遲加載,即           load方法執(zhí)行后,并不會執(zhí)行查詢sql只是返回了一個代理對象,只有等真正用到了這個對象才會發(fā)出查詢       語句。
            <2>當get方法查找的對象不存在則返回null,而load會拋出異常。
              共同點:load和get只能通過主鍵標示加載實體對象。

8、 數(shù)據(jù)庫的隔離級別決定了只發(fā)出插入sql而沒有提交事務后是否能select看到數(shù)據(jù)。其實只要發(fā)出了插入的sql語句,即使你       沒有提交事務,庫里面就已經有了數(shù)據(jù),只是數(shù)據(jù)庫的默認隔離級別不會讓你看到數(shù)據(jù),這時你就可以回滾事務,取消        數(shù)據(jù)插入,而且這種隔離級別還可以設置的。

9、在hibernate中,持久態(tài)對象不能引用瞬時態(tài)對象。(插入有關聯(lián)關系的對象時可能會遇到這種異常)。

10、hiberntate級聯(lián)(cascade)只對增、刪、改有作用,與查詢沒關系,默認不會級聯(lián)即值為none。

11、在hibernate中對象之間的映射關系通常都配成雙向的,比如雙向一對一外鍵關聯(lián)映射(這也是一對一中最常用的)。

12、一對一主鍵關聯(lián)默認就有級聯(lián)關系,其他關聯(lián)關系都沒有這種默認設置。

13、<many-to-one>標簽會在當前表中加字段即外鍵,而<one-to-one name="user">標簽不會加字段,
    指示hibernate如何加載關聯(lián)對象,它默認就去另一張表中找主鍵與當前表主鍵相等的數(shù)據(jù)。

14、在主鍵生成器中uuid和native比較常用,它們的區(qū)別是:
    (1)uuid在執(zhí)行完save后只會把此對象放在session緩存中,并為其賦id值(是一個32位字符串),它只有事務提交時       也就是清理了緩存時才會發(fā)出sql。
    (2)native在執(zhí)行完save后就立刻發(fā)出插入sql語句,即此時庫中已經有了此對象數(shù)據(jù),而且native是根據(jù)本地數(shù)據(jù)庫    進行自增的,比如你用的是oracle,那它就會通過序列進行自增。

15、hibernate中的flush方法可以清理session緩存并執(zhí)行相應的sql,我們可以手動執(zhí)行,但提交事務前也會被自動執(zhí)行的。

16、hibernate中的雙向多對一和一對多是同一個概念,而且一對多和多對一都是在多的一端加個外鍵來指向一的一端,一對多單     向會發(fā)出多余的update語句(所以一般都配成雙向 )。

17、hibernate一般在持久類中用到集合映射時都用Set(放入的對象不可重復)很少用List,而且還不能用Hashset具體類去聲明     ,必須用接口Set去聲明     ,因為hibernate對Set進行了擴展。

18、hibernate映射文件的單雙向都是針對加載而言的。

19、hibernate支持lazy延遲加載(只有真正使用該對象時才會創(chuàng)建,即發(fā)出相應的sql語句),默認lazy都是true而且Session不    能關,否則lazy就失效了,如果你在Session關閉后在把延遲加載的對象輸出給頁面就會拋出異常即特別是用load(它支持lazy)   進行加載時Session關閉后在返回所查詢的對象時就會拋此異常   org.hibernate.LazyInitializationException,但用get()加   載時就不存在這問題,因為lazy的生命周期和Session是同步的,這個面試可能會問到,解決方法就是不關Session,直到查詢   的內容已經返回給頁面在關閉,Spring框架就提供了一個Filter(過濾器)實現(xiàn)了此功能即從請求訪問一直到響應返回后在關   閉Session。hibernate的延遲加載實現(xiàn)用的是第三方庫cglib.jar,這是個動態(tài)代理類庫,跟JDK的動態(tài)代理是不一樣的,JDK的   動態(tài)代理只能代理實現(xiàn)了一定的接口的類。hibernate的lazy可以應用的標簽類型有<class>、<property>、<one-to-one>、    <many-to-one>、集合。

20、get和load兩個方法在同一個session中都會用到session緩存(也就是hibernate一級緩存)在執(zhí)行這兩個方法后都會給        session緩存中放一份,即第二次查詢同一對象時不會在發(fā)出sql,只會從一級緩存中直接讀取數(shù)據(jù),一級緩存只緩存實體對象    ,不緩存普通屬性,而且一級緩存的生命周期和Session的生命周期是一致的,不同的Session之間不能共享Session緩存中的數(shù)       據(jù)。

21、session.save()時也用到了一級緩存,即添加完后會給session緩存中放一份對象。

22、一級緩存不能控制,包括設置容量、或者取消,只能通過session.clear()等方法清空它。一級緩存是session緩存即同一個     session共享,二級緩存是進程級的緩存即SessionFactory級緩存(它的生命周期和SessionFactory一致),不同session之間    是可以共享的,它們的共同點是都緩存對象,不緩存普通屬性。Hibernate的二級緩存集成了第三方庫,比如:ehcache,而且    使用時必須配置(如:配置用哪種二級緩存,哪些實體類使用二級緩存)。
    二級緩存的簡單示例:
    比如當二級緩存沒配置時(默認是開啟的)——>我們用load或者get查詢時先會去一級緩存中查,沒有找到再發(fā)出SQL。
    當二級緩存開啟并配置后——>查詢時先去一級緩存,如果沒有在去二級緩存找,再沒有就發(fā)出相應的SQL.。
    當二級緩存開啟并配置后,load和get查詢默認后會給一級緩存和二級緩存中都放一份(可以配置不往二級緩存中放),二級緩存可以被SessionFactory去直接管理,比如:清空。
  Hibernate還有一種緩存叫查詢緩存(Hibernate默認是關閉的)此緩存對Query.iterate()不起作用,它是緩存普通屬性和對象id標示的,它的生命周期不可控制(與session的生命周期沒有關系的),利用率不高,此緩存使用時必須配置。
   忠告:Hibernate用不好會發(fā)出N多條sql語句,效率會大大降低。

23、用Query或者save操作大量實體對象時給Session緩存中都會放一份,這樣會影響效率,很可能內存溢出,所以大量數(shù)據(jù)操作不     適合用hibernate。

24、每次執(zhí)行l(wèi)ist()默認都會像數(shù)據(jù)庫發(fā)出sql語句,但它會一次性把集合中的所有元素都查出來,它只會為一級緩存中放數(shù)據(jù),     但不會從緩存中取,而iterate()方法會先從緩存中取,如果緩存中沒有就會很可能發(fā)生N+1問題。
    N+1問題:1—>首先發(fā)出一條查詢對象id列表的sql。N—>根據(jù)id的列表一個一個去一級緩存中查找,如果沒有就每個id發(fā)出一條sql,即N個id就發(fā)出N條查詢語句。

25、hibernate 還支持HQL語句外置,即把HQL語句放到任何一個的hbm.xml映射文件中。

26、hibernate 還支持查詢過濾器,即在相應的hbm.xml映射配置文件中配置條件后,在執(zhí)行action中的HQL查詢時就會自動加上     映射文件中配置的條件。

27、hibernate 也帶left join和right join,左連接就是左邊表全部顯示,右邊為空的就顯示null。右連接正好相反。

28、HQL也支持DML風格語句,即用HQL的update、delete等,這個不建議使用,關鍵是我也沒用過,嘿嘿。

29、hibernate的抓取策略默認就是fetch="select",意思是用到關聯(lián)對象時,會再發(fā)一條select查詢語句。如果手動設置        fetch="join"抓取策略,Hibernate會通過一條select語句使用外連接直接查出實體對象和與其關聯(lián)的對象或者集合(即使你    不使用那些相關聯(lián)的對象,照樣會一次性查出來,影響效率)。
    Hibernate還有其他抓取策略,等用到了再去看吧!
   
30、hibernate 還可以配置批量查詢、更新,即在配置文件中可以配置一個最大返回記錄數(shù),一般可以設為50,意思就是當你一次     性查詢10000條數(shù)據(jù)時,底層數(shù)據(jù)庫都是50條50條的給你返回,這個功能需要特定的數(shù)據(jù)庫支持才行。

31、Hibernate的映射配置文件還是比較復雜,但它有注解配置,這個現(xiàn)在用的也非常多,個人也比較喜歡這種配置方式。


32、最后再說下Hibernate還集成了一個測試工具類,junit這是個第三方庫,只要我們寫的類繼承了TestCase,然后
    方法必須是公共的返回值為空,且方法名以小寫test開頭,不能帶參數(shù)。(類名無限制,但推薦最好以大寫的Test結尾),這樣就可以很方便的進行測試了。


下面貼出一些測試用例代碼:
第一、hibernate.cfg.cml是Hibernate的主配置文件(這個名字可以隨便起):

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- 配置與數(shù)據(jù)庫連接有關的信息,并引入映射文件,此配置文件的屬性都比較簡單就不用再38了 -->
<hibernate-configuration>
    <session-factory>
        <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:ORCL9I</property>
        <property name="connection.username">test</property>
        <property name="connection.password">test</property>
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
        <!--下面這個屬性配置成update后,則我們從新生成表時,沒有改變的表將不會被drop(刪了從建),只會新建有變動的表,而且這個屬性設置后我們也不用hibernate的生成表工具(SchemaExport)去執(zhí)行創(chuàng)建表,而是當我們插入數(shù)據(jù)時,hibernate會自動幫我們先創(chuàng)建表,再去插入數(shù)據(jù)。 -->
        <property name="hbm2ddl.auto">update</property>
        <property name="show_sql">true</property>
       
        <mapping resource="many_to_many_shuangxiang/User.hbm.xml"/>
        <mapping resource="many_to_many_shuangxiang/Role.hbm.xml"/>
    </session-factory>
</hibernate-configuration>


第二、列出Hibernate中比較復雜的多對多雙向關聯(lián)映射配置(如果我是項目經理,這些對象的所有關心都不會配置,呵呵)

      就以用戶和角色為例:
      1、用戶的映射文件如下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- 加入這個package屬性后,下面就不用寫全包名了 -->
<hibernate-mapping package="many_to_many_shuangxiang">
    <class name="User" table="t_user">
        <id name="userId">
            <generator class="uuid"/>
        </id>
        <property name="userName"/>
        <!-- set 中的table會創(chuàng)建個中間表-->
        <set name="roles" table="user_role">
        <!-- 下面這個key是中間表中的外鍵,引用當前表的主鍵 -->
            <key column="userId"/>           
            <!-- many-to-many中的column也是中間表的外鍵(中間表用的是復合主鍵),引用class屬性中持久類Role對應表的主鍵 -->
            <many-to-many class="Role" column="roleId"/>
        </set>
    </class>
</hibernate-mapping>

       2、角色的映射文件如下:
       <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <!-- 加入這個package屬性后,下面就不用寫全包名了 -->
<hibernate-mapping package="many_to_many_shuangxiang">
    <class name="Role" table="t_role">
        <id name="roleId">
            <generator class="uuid"/>
        </id>
        <property name="roleName"/>
        <set name="users" table="user_role">
            <key column="roleId"/>
            <many-to-many class="User" column="userId"/>
        </set>
    </class>
</hibernate-mapping>



第三、Hibernate根據(jù)持久化類(pojo+映射文件)去創(chuàng)建對應的數(shù)據(jù)庫表:

public static void main(String[] args) {
        //加載hibernate的配置文件
        //Configuration cfg = new Configuration();這樣會默認讀取的是properties文件;
        Configuration cfg = new Configuration().configure();//調用了這個方法后才會默認去讀取hibernate.cfg.xml配置文件。
        SchemaExport export = new SchemaExport(cfg);//用這個類就可以生成數(shù)據(jù)庫表。
        export.create(true,true);//此方法生成表。
    }


第四、SessionFactory是個重量級對象,所以最好在整個系統(tǒng)就只創(chuàng)建一次,再給Session設計個單態(tài)模式:
public class SessionUtil {
    private static SessionFactory factory;
    private static Session session;
    static{
        Configuration cfg = new Configuration().configure();
        factory = cfg.buildSessionFactory();
        session = factory.openSession();
    }   
    public static Session getSession(){
        return session;
    }   
    public static void closeSession(Session session){
        if(session != null) session.close();
    }
}


第五、Hibernate 的增、刪、改、查:

增——>session.save(user); 
刪——>session.delete(user),這個通常是先查出來
改——>session.update(user),同樣是先查出來,此時可以不調用update(),set()修改完屬性后直接提交事務就行了。
查——>session.load(user.class,id) , session.get(user.class,id)個人比較喜歡用這種方式。;



第六、列出常用的HQL查詢語句:

1、簡單實體列表查詢:
//里面?zhèn)鞯氖荋QL查詢語言,這里的User類跟此類沒在同一個包下,hibernate會默認找到User所在的包。
Query query =  session.createQuery("from User");
List list = query.list();

2、Hibernate分頁查詢:
//里面?zhèn)鞯氖荋QL查詢語言,查詢的直接是對象集合。
Query query =  session.createQuery("from User u order by u.userName");           
query.setFirstResult(0);//設置從庫中第一條數(shù)據(jù)開始查詢,即傳0,在數(shù)據(jù)庫中是從0開始的。           
query.setMaxResults(2);    //設置每次查詢的記錄數(shù)為2,即查詢的對象個數(shù)。
List list = query.list();


3、單個實體查詢:
User user = (User)session.createQuery("from User as u where u.userId='uuid1'").uniqueResult();

4、對象屬性查詢(直接用iterate()方法):
Iterator iterator = session.createQuery("select u.userName from User u where u.userId=? and u.userName=?")
                        .setString(0,"8a88831127f5fd8d0127f5fd90b20003")
                        .setString(1,"馬文濤")//這兩個參數(shù)就可以從頁面?zhèn)鬟^來
                        .iterate();
            while(iterator.hasNext()){
                String userName = (String)iterator.next();
                System.out.println(userName);
            }

5、使用where、like、分組、過濾、排序、內置函數(shù)進行條件查詢
List list = session.createQuery("select count(u),u.userName from User u where u.userName " +
                    "like '%文%' group by u.userName having count(u)>2 order by u.userName").list();
            for(Iterator i = list.iterator();i.hasNext();){
                Object[] o = (Object[])i.next();
                long count = (Long)o[0];//這個count()返回的類型是long,不能用int接受。
                String name = (String)o[1];
                System.out.println(name+"它的個數(shù)為:"+count);
            }:
/*這里的List返回的是一個對象數(shù)組(Object[]),數(shù)組長度就是select返回的屬性類型個數(shù),
數(shù)組元素中的類型就跟對應屬性的類型一致。*/


6、用hibernate提供的內部函數(shù)包含(in)查詢:
List list = session.createQuery("select userName from User where userName in(:name)")
            .setParameterList("name",new Object[]{"寶寶","濤哥"})
            .list();

7、用hibernate對象導航查詢,用點進行導航(u.userName)如果有其他屬性都可以點。
List list = session.createQuery("select u.userName from User u where u.userName=:name")
                        .setParameter("name","寶寶")
                        .list();
            for(Iterator i = list.iterator();i.hasNext();){
                String userName = (String)i.next();
                System.out.println(userName);
            }



好啦,不能在寫了,剛搬了房子公交車很不方便,晚上209路居然7點半就是最后一趟了,昨天都意外打出租了,嘿嘿!
本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Hibernate程序性能優(yōu)化的考慮要點
Hibernate對多表關聯(lián)查詢
Hibernate優(yōu)化
hibernate延遲加載(get和load的區(qū)別)
在Hibernate應用中如何處理批量更新和批量刪除?
ssh框架問題
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服