Hibernate 是一個數據層的框架 所謂框架就是提升寫代碼的效率前端
他也是ORM(對象關係映射的實現 )mysql
裏面提供了一些方言(不一樣數據庫設置不一樣的方言)---跨數據庫sql
還提供了緩存來提升查詢效率 數據庫
主要咱們看一下配置文件(框架基本上都是用配置文件來搭建環境的)緩存
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">安全
<hibernate-configuration>session
<session-factory>併發
<!-- 鏈接數據庫的四個參數 -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>app
<!-- 鏈接池 -->
<property name="connection.pool_size">30</property>框架
<!-- 方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 線程和session同步-->
<property name="current_session_context_class">thread</property>
<!--展現SQL語句 -->
<property name="show_sql">true</property>
<!-- 格式化Sql -->
<property name="format_sql">true</property>
<!-- 若是有表就使用 沒表就建立 -->
<property name="hbm2ddl.auto">update</property>
<!-- 映射文件 -->
<mapping resource="com/zgl/entity/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
從上面能夠看這邊的配置文件主要配置的是怎麼鏈接數據庫而後就是Hibernate的核心配置 ---是否線程同步 是否展現SQL語句等等
還有一個重要的就好似映射文件 這裏面的映射文件極其重要 他反映了表和實體類的關係
先看單表的屬性配置文件
<!-- 這個文件叫作映射文件 -->
<!--
package:實體類的額包名
-->
<hibernate-mapping package="com.qf.entity">
<class name="User" table="t_user">
<!-- id比較特殊,用id標籤修飾 -->
<id name="id">
<!-- 主鍵自增策略 -->
<generator class="native" />
</id>
<!--
其餘屬性用property修飾
name:指定的是對象的中的屬性名稱
column:表中字段名稱
-->
<property name="username" column="name"></property>
<!--
表中的字段名稱和實體類中的屬性名稱一致,column能夠不寫
-->
<property name="password"></property>
</class>
</hibernate-mapping>
這個配置文件主要配置實體類和表中字段的對應關係若是表中字段和實體類屬性一致的話能夠只寫實體類的屬性便可
而後單表的增刪改查
先建立Session的工廠的工具類
private static final SessionFactory sessionFactory = buildSessionFactory();
private static SessionFactory buildSessionFactory() {
try {
// 1.配置相關對象
Configuration configuration = new Configuration();
// 2.讀取配置文件
Configuration configure = configuration.configure();
// 3.構建工廠
SessionFactory factory = configure.buildSessionFactory();
return factory;
} catch (Throwable ex) {
// Make sure you log the exception, as it might be swallowed
System.err.println("Initial SessionFactory creation failed." + ex);
throw new ExceptionInInitializerError(ex);
}
}
public static SessionFactory getSessionFactory() {
return sessionFactory;
}
}
而後在測試類調用這個方法這個類中的方法就能夠得到Session工廠了
記得操做數據庫以前要開啓事務session.beginTransaction(); 而後結束後要提交事務transaction.commit();
@Test
public void testHello() {
// 1.建立一個SessionFactory
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
// 2.經過SessionFactory建立session
Session session = sessionFactory.getCurrentSession();
// 3.開啓事務
Transaction transaction = session.beginTransaction();
User user = new User();
user.setUsername("admin");
user.setPassword("admin");
// 4.保存user
Serializable save = session.save(user);
System.out.println("save方法的返回值:"+save);
// 5.事務提交
transaction.commit();
其中 具體的調用方法
添加:session.save(user);--傳入對象
刪除:session.delete(user);---傳入對象
查找:session.get(User.class, userId);-傳入對象類型 和查找的條件
更新:先查找而後修改--session.get(User.class, 2);---session.update(user);
---------------------------------------------------------------其中這個Session 的建立有兩種方式
方式一:openSession
sessionFactory.openSession();---須要關閉Session
1.每次都會建立一個新的Session
2.session須要手動關閉
3.能夠在沒有事務的狀況下操做事務--查詢
4.提交事務的時候 會刷新緩衝區 提交事務
方式二 :getCurrentSession
sessionFactory.getCurrentSession();
1.每次建立Session 的時候會先在緩存區找若是有就直接使用沒有的話就建立
2.必需要開啓事務才能夠操做數據庫
3.提交事務的時候 會自動 關閉Session 刷新緩衝區 提交事務
----------------------------------------------------load 和 get查詢的區別
load:
session.load(User.class, 1);
查詢結果返回的是一個代理對象 這個對象只有ID有值 其餘屬性都爲空 只有 調用 除ID之外的屬性時 纔會 發送 sql語句
懶加載 能夠 更改 修改配置文件 的 Class節點 中的 lazy屬性
若是查詢的數據 會拋出異常
get:
session.get(User.class, 1);
查詢結果返回的是一個真實 的 對象
很積極查詢後立馬發送那個SQL語句
查詢一個 不存在的值 返回 NULL
-------------------------------------------------------------------------------------------------------------------------------------------------------
兩張表的鏈接 一對多 :
此時就須要 配置他們的對應關係了
一 的一方 :
首先要在實體類的裏面添加多的一方實體類用集合接收 而後配置 XML
這裏用set集合接收
name一的一方中多的一方的屬性名
關聯外鍵 一的一方在多的一方表中的字段名
配置關係 多的一方的實體類的全類名
<set name="addresss" inverse="true">
<!-- 關聯的外鍵 -->
<key column="user_id"></key>
<!-- 多的一方的全類名 -->
<one-to-many class="com.qf.entity.Address"/>
</set>
多的一方 --
一樣也要在實體類的裏面 添加 一 的一方的屬性
而後配置
多的一方 只須要配置與多的一方的關係
而後 關聯外間一的一方在多的一方的字段名
<many-to-one name="user">
<!-- 關聯外鍵 -->
<column name="user_id"></column>
</many-to-one>
這樣簡單的一對多的關係就配置好了
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
兩張表的級聯操做 :改變一張表另外一張表也隨之改變
cascade--級聯操做 (添加在一的一方的set標籤中 )
save-update:保存多的一方多的一方自動保存
delete : 刪除一的一方多的一方自動刪除
all:包含上面兩種 方式
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
inverse 控制反轉--設置爲true把維護權給另外一方
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.多對多
a)配置
1)A方
a)<set>
1)name:另外一方集合名稱
2)table:中間表名稱
3)<key>:當前表在中間表的關聯字段
b)<many-to-many>
a)class:另外一方的類型
b)column:另外一方在中間表的關聯字段
2)B方和A方相反
b)級聯操做
1)須要保存哪一方中間表維護權就給哪一方,因此另外一方須要反轉
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.抓取策略 抓取數據的一種策略
它是改變hibernate查詢的方式從而提升查詢效率
檢索方式
當即檢索 ---get
延時檢索---load
檢索級別 :
類級別的檢索
查詢的時候當前對象中的其餘屬性是否須要查詢
關聯級別
查詢的時候當前對象中的其餘對象是否須要查詢
fetch:決定的SQL語句
select:普通的查詢
join:鏈接查詢
subselect:子查詢
lazy:決定的懶載程度
true:懶惰
false:不懶惰
extra:極其懶惰
------------------------------------------------------------------------------------------------------------------------------------------------------------------
HQL查詢 :
純面向對象的查詢
裏面的關鍵字不區分大小寫
操做的都是對象或者屬性不是表中的字段
1.查詢List集合數據
利用Session的createQuery() 方法編寫 sql語句 ----面向對象 操做
而後獲得Query對象 而後 用List() 方法接受List集合數據 最後遍歷集合
查詢單個數據
和上面同樣只不過獲得Query對象後用 uniqueResult接收單個對象 或數據
演示分頁:
先寫Sql語句在緩衝區 而後設置他的大小 而後執行
綁定參數 :--傳入參數更靈活
看其中的?和 :id是佔位符 這邊賦值的話
知道類型就用類型不知道的話就用SetParmeter()----至關於Object
------------------------------------------------------------------------------------------------------------------------
QBC語句查詢:hql更加的面向對象
查詢集合 ;
分頁查詢:
離線查詢:
條件查詢:
排序:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
緩存機制
一級緩存 :session級別的緩存
在同一個Session中查詢語句的時候 先去緩存中去找 若是有就使用 沒有的話就去數據庫查詢而後在緩存中放一份
不一樣的Session之間的緩存不共享
二級緩存:sessionfacory級別的緩存
二級緩存默認不開啓 要在XMl文件中開啓 二級緩存 、
而且肯定二級緩存的供應商
而後肯定須要緩存的對象
應用場景:
1)什麼樣的數據應該方法緩存裏面
a)常常被訪問
b)不常常修改
c)不是很重的數據,容許偶爾出現併發問題
2)不該該放在緩存中的數據
a)常常被修改
b)重要的數據,不容許發生併發問題
3)性能和安全都在的時候先安全
1)內置緩存:給Hiberate本身使用
2)外置緩存:給用戶使用,可是隻提供了一個接口,具體實現由第三方來作
三級緩存--查詢緩存----查詢緩存要依賴二級緩存
須要開啓查詢緩存:
1)導入jar包
2)開啓二級緩存
3)肯定二級緩存的供應商
4)配置要緩存的對象
1)<class-cache>
a)class:須要被緩存的對象
b)usage:緩存的數據是否能被修改,通常都是隻讀
2)<collection-cache>:能夠緩存一個集合,還要把集合中方的對象也要緩存起來
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Hibernate裏面也可使用原生態的Sql語句
session.createSQLQuery("sql")
這種通常適用於比較複雜的SQL語句 通常都是用前面的 HQL 和 自定義的方法
幾種方式比較
-----------------------------------------------------------------------------------------------------------------------------------------------------
批處理 :
1.Hibernate框架是提升開發效率,性能沒有jdbc高
2.項目中作批量操做的時候要用jdbc
3.commit的方法會隱式調用flush()
----------------------------------------------------------------------------------------------------------------------------------------------------
Hibernate整合C3p0
a)導入jra包
b)配置
1)配置c3p0的驅動
2)配置c3p0屬性
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
鎖:解決併發問題
樂觀鎖:
修改的時候總會認爲別人不會修改,底層經過版本號控制來實現
1)原理
a)表中添加一個version字段
b)添加的時候先判斷version字段是否一致
1)若是一致就提交,版本號自增
2)若是不一致就不讓提交,說明數據已經被別的事務修改
2)Hibernate中如何實現
a)表中添加一個version字段
b)對象中添加一個version屬性
c)在映射文件中創建關係
d)這個字段Hibernate會幫咱們維護
悲觀鎖 :
b)悲觀鎖:修改的時候總會認爲別的事務也會修改,因此要加鎖。底層經過數據庫鎖實現的
1)select * from t_user where id = 1 for update
2)session.get(User.class, 1, LockOptions.UPGRADE);
-------------------------------------------------------------------------------------------------------------------------------------------------------
最後在鏈接前端的時候須要進行級聯操做 然而Session 已經關閉 會報錯 因此咱們要添加過濾器設置Session關閉的時機
----------------------------------------------------------------------------------------------------------------------------------------------
利用註解實現對象關係映射:
首先在覈心配置文件裏面要改變映射表達 配置全類名便可
而後在實體類的上面進行關係映射
2)註解
a)@Entity // 實體類
b)@Table // 表名稱
c)@id // 主鍵
d)@column // 列名稱
e)@OneToMany // 一對多
f)@ManyToOne // 多對一
g)@joinColumn // 關聯外鍵
=====================================================================================================================================