團長大人的學習筆記——Hibernate

Hibernate開發流程

  • 導入Maven依賴(還有數據庫驅動)
<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>
複製代碼
  • 建立核心配置文件和Mapper的xml文件裏java

    • 配置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">
    複製代碼
    • 建立核心配置文件
    <!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>
            <!--配置數據源-->
            <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>
            <!--自動建立表(通常不須要)-->
            <property name="hbm2ddl.auto">update</property>
            <!--顯示SQL-->
            <property name="show_sql">true</property>
            <property name="format_sql">true</property>
            <!--配置數據實體-->
    
            <!--註冊mapper-->
            <mapping resource="mapping/AccUser.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>
    複製代碼
    • 建立實體類和映射文件
    <!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">
            <!--對象標識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>標籤裏註冊mapping
    <!--註冊mapper-->
    <mapping resource="mapping/AccUser.hbm.xml"/>
    複製代碼
  • 添加主類進行測試mysql

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">
    <!--對象標識OID-->
    <id name="id" column="id">
        <generator class="具體策略"/>
    </id>
</class>
複製代碼
  • 生成策略
    • identity:採用數據庫底層的自增加列(MySQL)
    • sequence:採用數據庫底層的自增加列(Oracle)
    • native:根據數據庫選擇identity,sequence或hilo中的一個
    • increment:採用Hibernate本身維護的自增加(先查詢max,再+1)
    • uuid:採用UUID做爲惟一字符串(id字段必須是string類型)
    • assigned:須要明確賦值(開發者維護)

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

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

HQL

  • HQL = Hibernate Query Language,主要用面向對象的思惟來編寫SQL。下面的示例就能夠查詢全部的User,而且實現分頁
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();
}
複製代碼
  • 條件查詢sql

    • 索引佔位(下面的例子是查詢Id是傳入數字的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實現查詢
        query.setParameter(0, uid);
        //獲取單個結果
        return query.uniqueResult();
    }
    複製代碼
    • 命名佔位(只須要在上例的基礎上修改hql語句和傳入參數的語句)
    ...
    Query<AccUser> query = session.createQuery("select au from AccUser au where id = :id", AccUser.class);
    ...
    query.setParameter("id", uid);
    ...
    複製代碼
  • 模糊查詢數據庫

    • 使用百分號包起來作字符串部分匹配"%查詢內容%"
  • HQL更新和刪除(相似SQL更新和刪除)數組

  • HQL查詢部分字段緩存

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

解決傳遞當前Session問題

  • 保存到本地線程bash

    • 在覈心配置xml裏配置容許保存到本地線程
    <property name="hibernate.current_session_context_class">thread</property>
    複製代碼
    • 在線程裏獲取session (使用這種session必須開啓事務而且不用關閉session,如今這個session會和這個線程共存亡)
    Session currentSession = sessionFactory.getCurrentSession();
    複製代碼

級聯查詢

  • Hibernate能夠實現不經過寫SQL或HQL語句拿到字段裏外鍵約束對應的記錄的映射對象(關聯信息默認是懶加載的)
  • 具體作法能夠在IDEA的逆向生成工具生成

延遲檢索

  • 至關我使用這個對象時纔會查詢數據庫
    • 使用session.get(class)是當即檢索(先查session緩存再查數據庫)
    • 使用session.load(calss)時延遲檢索(先查session緩存再查二級緩存最後查數據庫)
  • 關聯表的延遲與當即(在<many-to-noe>默標籤裏添加lazy屬性,認是延遲lazy = true

實體類的狀態

  • 瞬時態:沒有主鍵,沒有被session管理(實體類剛剛被建立)
  • 持久態:有主鍵,被session管理(實體類被session作save、get等操做,如今實體類被session管理)
  • 遊離態:有主鍵,可是沒有被session管理(session被關閉)

緩存

  • 一級緩存:
    • 緩存在session中,若是修改了緩存內容(持久態的對象被修改)而且提交了事務以後,Hibernate會進行快照對比,如過不一致,會同步到數據庫
    • 能夠調用clear方法清空全部一級緩存
  • 二級緩存
相關文章
相關標籤/搜索