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

NO IMAGE

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文件裡

    • 配置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"/>
    
  • 添加主類進行測試

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();
}
  • 條件查詢

    • 索引佔位(下面的例子是查詢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問題

  • 保存到本地線程

    • 在核心配置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方法清空所有一級緩存
  • 二級緩存

相關文章

MongoDB的地理位置索引

MongoDB入門篇

MangoDB的下載和安裝

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