4 api詳解【多練】
4.1 體系結構
PO:persistent object ,用於與數據庫交互數據。–dao層 (JavaBean + hbm )
BO:Business object 業務數據對象。–service層
VO:Value Object 值對象。–web層
開發中:直接使用JavaBean 描述三個對象。
4.2 Configuration 配置對象
hibernate 核心配置文件種類
hibernate.cfg.xml 通常使用xml配置文件,可以配置內容更豐富。
hibernate.properties 用於配置key/value 形式的內容,key不能重複的。配置有很多的侷限性。一般不用。
參考文件:hibernate-distribution-3.6.10.Final\project\etc\ hibernate.properties
提供了核心配置文件常用的配置項,及選擇參數。
1.提供構造 new Configuration() hibernate將自動加載 hibernate.properties文件
hibernate.properties文件必須存放在類路徑(src)下
2.提供方法 configure() 將加載src下的hibernate.cfg.xml
3.擴展api
configure(String) 加載指定目錄下的 xml文件
4.手動加載配置文件
// 手動加載指定的配置文件
config.addResource("com/itheima/a_hello/User.hbm.xml");
// 手動加載指定類,對應的映射文件 User--> User.hbm.xml
config.addClass(User.class);
常見異常:
開發中:將hbm.xml映射 配置 hibernate.cfg.xml
學習中:可以使用 addClass 或 addResource
4.3 SessionFactory工廠
SessionFactory 相當於java web連接池,用於管理所有session
獲得方式:config.buildSessionFactory();
sessionFactory hibernate緩存配置信息 (數據庫配置信息、映射文件,預定義HQL語句 等)
SessionFactory線程安全,可以是成員變量,多個線程同時訪問時,不會出現線程併發訪問問題。
提供api:
//打開一個新的會話 session
factory.openSession();
//獲得當前線程中綁定的會話session
factory.getCurrentSession();
hibernate支持,將創建的session綁定到本地線程中,底層使用ThreadLocal,在程序之間共享session。
1.必須在hibernate.cfg.xml 配置
2 與本地線程綁定
thread
2.如果提交或回滾事務,底層將自動關閉session
4.4 Session 會話
Session 相當於 JDBC的 Connection – 會話
通過session操作PO對象 –增刪改查
session單線程,線程不安全,不能編寫成成員變量。
session api
save 保存
update 更新
delete 刪除
get 通過id查詢,如果沒有 null
load 通過id查詢,如果沒有拋異常
createQuery(“hql”) 獲得Query對象
createCriteria(Class) 獲得Criteria對象
4.5 Transaction 事務
開啓事務 beginTransaction()
獲得事務 getTransaction()
提交事務:commit()
回滾事務:rollback()
try{
//開啓
//session操作
//提交
} catch(e){
//回滾
}
擴展:不需要手動的管理事務,之後所有的事務管理都交予spring。
4.6 Query對象
hibernate執行hql語句
hql語句:hibernate提供面向對象查詢語句,使用對象(類)和屬性進行查詢。區分大小寫。
獲得 session.createQuery(“hql”)
方法:
list() 查詢所有
uniqueResult() 獲得一個結果。如果沒有查詢到返回null,如果查詢多條拋異常。
setFirstResult(int) 分頁,開始索引數startIndex
setMaxResults(int) 分頁,每頁顯示個數 pageSize
4.7 Criteria對象(瞭解)
QBC(query by criteria),hibernate提供純面向對象查詢語言,提供直接使用PO對象進行操作。
獲得方式:Criteria criteria = session.createCriteria(User.class);
條件
criteria.add(Restrictions.eq("username", "tom"));
// Restrictions.gt(propertyName, value) 大於
// Restrictions.ge(propertyName, value) 大於等於
// Restrictions.lt(propertyName, value) 小於
// Restrictions.le(propertyName, value) 小於等於
// Restrictions.like(propertyName, value) 模糊查詢,注意:模糊查詢值需要使用 % _
4.8 工具類
public class H3Utils {
// 會話工廠,整個程序只有一份。
private static SessionFactory factory;
static{
//1 加載配置
Configuration config = new Configuration().configure();
//2 獲得工廠
factory = config.buildSessionFactory();
//3 關閉虛擬機時,釋放SessionFactory
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
System.out.println("虛擬機關閉!釋放資源");
sf.close();
}
}));
}
/**
* 獲得一個新的session
* @return
*/
public static Session openSession(){
return factory.openSession();
}
/**
* 獲得當前線程中綁定session
* * 注意:必須配置
* @return
*/
public static Session getCurrentSession(){
return factory.getCurrentSession();
}
}
5 核心配置文件詳解
5.1 詳細配置【多讀】
<!-- SessionFactory,相當於之前學習連接池配置 -->
<session-factory>
<!-- 1 基本4項 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///h_day01_db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!-- 2 與本地線程綁定 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 3 方言:爲不同的數據庫,不同的版本,生成sql語句(DQL查詢語句)提供依據
* mysql 字符串 varchar
* orcale 字符串 varchar2
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 4 sql語句 -->
<!-- 顯示sql語句 -->
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<!-- 5 自動創建表(瞭解) ,學習中使用,開發不使用的。
* 開發中DBA 先創建表,之後根據表生產 PO類
* 取值:
update:
如果表不存在,將創建表。
如果表已經存在,通過hbm映射文件更新表(添加)。(映射文件必須是數據庫對應)
表中的列可以多,不負責刪除。
create :如果表存在,先刪除,再創建。程序結束時,之前創建的表不刪除。
create-drop:與create幾乎一樣。如果factory.close()執行,將在JVM關閉同時,將創建的表刪除了。(測試)
validate:校驗 hbm映射文件 和 表的列是否對應,如果對應正常執行,如果不對應拋出異常。(測試)
-->
<property name="hibernate.hbm2ddl.auto">create</property>
<!-- 6 java web 6.0 存放一個問題
* BeanFactory 空指針異常
異常提示:org.hibernate.HibernateException: Unable to get the default Bean Validation factory
* 解決方案:取消bean校驗
-->
<property name="javax.persistence.validation.mode">none</property>
<!-- 添加映射文件
<mapping >添加映射文件
resource 設置 xml配置文件 (addResource(xml))
class 配置類 (addClass(User.class)) 配置的是全限定類名
-->
<mapping resource="com/itheima/a_hello/User.hbm.xml"/>
</session-factory>
6 Hibernate中持久化類
6.1 編寫規則
• 提供一個無參數 public訪問控制符的構造器
• 提供一個標識屬性,映射數據表主鍵字段
• 所有屬性提供public訪問控制符的 set get 方法(javaBean)
• 標識屬性應儘量使用基本數據類型的包裝類型
• 不要用final修飾實體 (將無法生成代理對象進行優化)
6.2 持久化對象的唯一標識 OID
Java按地址區分同一個類的不同對象.
關係數據庫用主鍵區分同一條記錄
Hibernate使用OID來建立內存中的對象和數據庫中記錄的對應關係
結論: 對象的OID和數據庫的表的主鍵對應。爲保證OID的唯一性,應該讓Hibernate來爲OID付值
6.3 區分自然主鍵和代理主鍵
主鍵需要具備: 不爲空/不能重複/不能改變
自然主鍵: 在業務中,某個屬性符合主鍵的三個要求.那麼該屬性可以作爲主鍵列.
代理主鍵: 在業務中,不存符合以上3個條件的屬性,那麼就增加一個沒有意義的列.作爲主鍵.
基本數據類型和包裝類型對應hibernate的映射類型相同
基本類型無法表達null、數字類型的默認值爲0。
包裝類默認值是null。當對於默認值有業務意義的時候需要使用包裝類。
6.5 類型對應
Java數據類型 Hibernate數據類型 標準SQL數據類型
(PS:對於不同的DB可能有所差異)
6.6 普通屬性
<hibernate-mapping>
package 用於配置PO類所在包
例如: package="com.itheima.d_hbm"
<class> 配置 PO類 和 表 之間對應關係
name:PO類全限定類名
例如:name="com.itheima.d_hbm.Person"
如果配置 package,name的取值可以是簡單類名 name="Person"
table : 數據庫對應的表名
dynamic-insert="false" 是否支持動態生成insert語句
dynamic-update="false" 是否支持動態生成update語句
如果設置true,hibernate底層將判斷提供數據是否爲null,如果爲null,insert或update語句將沒有此項。
普通字段
<property>
name : PO類的屬性
column : 表中的列名,默認name的值相同
type:表中列的類型。默認hibernate自己通過getter獲得類型,一般情況不用設置
取值1: hibernate類型
string 字符串
integer 整形
取值2: java類型 (全限定類名)
java.lang.String 字符串
取值3:數據庫類型
varchar(長度) 字符串
int 整形
<property name="birthday">
<column name="birthday" sql-type="datetime"></column>
</property>
javabean 一般使用類型 java.util.Date
jdbc規範提供3中
java類型 mysql類型
java.sql.Date date
java.sql.time time
java.sql.timestamp timestamp
null datetime
以上三個類型都是java.util.Date子類
length : 列的長度。默認值:255
not-null : 是否爲null
unique : 是否唯一
access:設置映射使用PO類屬性或字段
property : 使用PO類屬性,必須提供setter、getter方法
field : 使用PO類字段,一般很少使用。
insert 生成insert語句時,是否使用當前字段。
update 生成update語句時,是否使用當前字段。
默認情況:hibernate生成insert或update語句,使用配置文件所有項
注意:配置文件如果使用關鍵字,列名必須使用重音符
6.7 主鍵
主鍵
<id>配置主鍵
name:屬性名稱
access="" 設置使用屬性還是字段
column="" 表的列名
length="" 長度
type="" 類型
<generator> class屬性用於設置主鍵生成策略
1.increment 由hibernate自己維護自動增長
底層通過先查詢max值,再+1策略
不建議使用,存在線程併發問題
2.identity hibernate底層採用數據庫本身自動增長列
例如:mysql auto_increment
3.sequence hibernate底層採用數據庫序列
例如:oracle 提供序列
4.hilo
</generator>
5.native 根據底層數據庫的能力選擇 identity、sequence 或者 hilo 中的一個。
##以上策略使用整形,long, short 或者 int 類型
6.uuid 採用字符串唯一值
##以上策略 代理主鍵,有hibernate維護。
7.assigned 自然主鍵,由程序自己維護。