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

Hibernate開發(fā)流程

  • 導(dǎo)入Maven依賴(還有數(shù)據(jù)庫驅(qū)動)
<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-osgi</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-proxool</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-infinispan</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
</dependencies>
  • 創(chuàng)建核心配置文件和Mapper的xml文件里

    • 配置Xml頭在核心包(core)里的dtd文件里找到,如下
    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><
    
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    • 創(chuàng)建核心配置文件
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!--配置數(shù)據(jù)源-->
            <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
            <property name="connection.url">jdbc:mysql://localhost:3306/money2?userSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF8&amp;serverTimezone=GMT&amp;allowMultiQueries=true</property>
            <property name="connection.username">root</property>
            <property name="connection.password">root</property>
            <!--配置SQL方言-->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>
            <!--自動創(chuàng)建表(一般不需要)-->
            <property name="hbm2ddl.auto">update</property>
            <!--顯示SQL-->
            <property name="show_sql">true</property>
            <property name="format_sql">true</property>
            <!--配置數(shù)據(jù)實體-->
    
            <!--注冊mapper-->
            <mapping resource="mapping/AccUser.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>
    
    • 創(chuàng)建實體類和映射文件
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="com.libi.entity.AccUser" table="acc_user">
            <!--對象標(biāo)識OID-->
            <id name="id" column="id">
                <generator class="identity"/>
            </id>
            <!--屬性映射-->
            <property name="userName" column="user_name"/>
            <property name="password" column="password"/>
            <property name="createTime" column="create_time"/>
        </class>
    </hibernate-mapping>
    
    • 在核心配置文件的<session-factory>標(biāo)簽里注冊mapping
    <!--注冊mapper-->
    <mapping resource="mapping/AccUser.hbm.xml"/>
    
  • 添加主類進(jìn)行測試

public class Application {
    public static void main(String[] args) {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        AccUser user = new AccUser();
        user.setUserName("hibernate");
        user.setPassword("1233333");
        user.setCreateTime(System.currentTimeMillis());
        session.save(user);
        transaction.commit();
        session.close();
        sessionFactory.close();
    }
}

Hibernate主鍵生成策略

  • 配置位置:在Mapping配置文件里配置
<class name="com.libi.entity.AccUser" table="acc_user">
    <!--對象標(biāo)識OID-->
    <id name="id" column="id">
        <generator class="具體策略"/>
    </id>
</class>
  • 生成策略
    • identity:采用數(shù)據(jù)庫底層的自增長列(MySQL)
    • sequence:采用數(shù)據(jù)庫底層的自增長列(Oracle)
    • native:根據(jù)數(shù)據(jù)庫選擇identity,sequence或hilo中的一個
    • increment:采用Hibernate自己維護(hù)的自增長(先查詢max,再+1)
    • uuid:采用UUID作為唯一字符串(id字段必須是string類型)
    • assigned:需要明確賦值(開發(fā)者維護(hù))

Hibernate的自動模式(生成映射文件和實體類)

  • 在IDEA里配置Database(右面maven上面的按鈕)
  • 添加Hibernate插件的支持

HQL

  • HQL = Hibernate Query Language,主要用面向?qū)ο蟮乃季S來編寫SQL。下面的示例就可以查詢所有的User,并且實現(xiàn)分頁
public List<AccUser> selectAllUser() {
    Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
    SessionFactory sessionFactory = configuration.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Query<AccUser> query = session.createQuery("select au from AccUser au", AccUser.class);
    query.setFirstResult(0);
    query.setMaxResults(10);
    return query.getResultList();
}
  • 條件查詢

    • 索引占位(下面的例子是查詢Id是傳入數(shù)字的AccUser)
    public AccUser selectUserById(Long uid) {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Query<AccUser> query = session.createQuery("select au from AccUser au where id = ?", AccUser.class);
        //傳入占位的ID實現(xiàn)查詢
        query.setParameter(0, uid);
        //獲取單個結(jié)果
        return query.uniqueResult();
    }
    
    • 命名占位(只需要在上例的基礎(chǔ)上修改hql語句和傳入?yún)?shù)的語句)
    ...
    Query<AccUser> query = session.createQuery("select au from AccUser au where id = :id", AccUser.class);
    ...
    query.setParameter("id", uid);
    ...
    
  • 模糊查詢

    • 使用百分號包起來做字符串部分匹配"%查詢內(nèi)容%"
  • HQL更新和刪除(類似SQL更新和刪除)

  • HQL查詢部分字段

    • 只查詢一個字段,在后面加上這個字段的類型
    Query userName = session.createQuery("select userName from AccUser where id = 1",String.class);
    
    • 不知道這是什么類型或者查詢兩個以上的字段,使用Object數(shù)組(Hibernate會用Object數(shù)組的方式返回給你)
    Query userName = session.createQuery("select userName, password from AccUser where id = 1");
    

解決傳遞當(dāng)前Session問題

  • 保存到本地線程

    • 在核心配置xml里配置允許保存到本地線程
    <property name="hibernate.current_session_context_class">thread</property>
    
    • 在線程里獲取session (使用這種session必須開啟事務(wù)并且不用關(guān)閉session,現(xiàn)在這個session會和這個線程共存亡)
    Session currentSession = sessionFactory.getCurrentSession();
    

級聯(lián)查詢

  • Hibernate可以實現(xiàn)不通過寫SQL或HQL語句拿到字段里外鍵約束對應(yīng)的記錄的映射對象(關(guān)聯(lián)信息默認(rèn)是懶加載的)
  • 具體做法可以在IDEA的逆向生成工具生成

延遲檢索

  • 相當(dāng)我使用這個對象時才會查詢數(shù)據(jù)庫
    • 使用session.get(class)是立即檢索(先查session緩存再查數(shù)據(jù)庫)
    • 使用session.load(calss)時延遲檢索(先查session緩存再查二級緩存最后查數(shù)據(jù)庫)
  • 關(guān)聯(lián)表的延遲與立即(在<many-to-noe>默標(biāo)簽里添加lazy屬性,認(rèn)是延遲lazy = true

實體類的狀態(tài)

  • 瞬時態(tài):沒有主鍵,沒有被session管理(實體類剛剛被創(chuàng)建)
  • 持久態(tài):有主鍵,被session管理(實體類被session做save、get等操作,現(xiàn)在實體類被session管理)
  • 游離態(tài):有主鍵,但是沒有被session管理(session被關(guān)閉)

緩存

  • 一級緩存:
    • 緩存在session中,如果修改了緩存內(nèi)容(持久態(tài)的對象被修改)并且提交了事務(wù)之后,Hibernate會進(jìn)行快照對比,如過不一致,會同步到數(shù)據(jù)庫
    • 可以調(diào)用clear方法清空所有一級緩存
  • 二級緩存
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容