1.框架體系結構
2.hibernate入門
2.1 ORM框架
Hibernate是一個數據持久化層的ORM框架.
Object:對象,java對象,此處特指JavaBean
Relational:關係,二維表,數據庫中的表。
映射|映射元數據:對象中屬性,與表的字段,存在對應關係。
2.2 什麼是hibernate
- Hibernate是輕量級JavaEE應用的持久層解決方案,是一個關係數據庫ORM框架
- ORM 就是通過將Java對象映射到數據庫表,通過操作Java對象,就可以完成對數據表的操作
- Hibernate提供了對關係型數據庫增刪改成操作
2.3 主流的ORM框架
- JPA Java Persistence API.JPA通過JDK 5.0註解或XML描述對象-關係表的映射關係(只有接口規範)
- Hibernate 最流行ORM框架,通過對象-關係映射配置,可以完全脫離底層SQL
- MyBatis 本是apache的一個開源項目 iBatis,支持普通 SQL查詢,存儲過程和高級映射的優秀持久層框架
- Apache DBUtils 、Spring JDBCTemplate
2.4 優點
- Hibernate對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼
- Hibernate是一個基於jdbc的主流持久化框架,是一個優秀的orm實現,它很大程度的簡化了dao層編碼工作 session.save(User);
- Hibernate使用java的反射機制
- Hibernate的性能非常好,因爲它是一個輕量級框架。映射的靈活性很出色。它支持很多關係型數據庫,從一對一到多對多的各種複雜關係
3 入門案例【掌握】
3.1 編寫流程
1. 導入jar包
2. 創建數據庫和表
3. 編寫核心配置文件(hibernate.cfg.xml)--> 配置獲得鏈接等參數
4. 編寫映射文件 hibernate mapping(*.hbm.xml)
5 使用api測試
3.2 數據庫和表
create database h_day01_db;
use h_day01_db;
create table t_user(
id int auto_increment primary key,
username varchar(50),
password varchar(30)
);
3.3 導入jar包
版本:3.6.10 –> hibernate 4 建議註解開發,hibernate 4 對 3 不兼容。
目錄結構
jar介紹(9個)
核心(1個): hibernate3.jar
必須(6個):\lib\required
jpa規範(1個):lib\jpa : hibernate-jpa-2.0-api-1.0.1.Final.jar
mysql驅動(1個): mysql-connector-java-5.0.8-bin.jar
3.4 編寫JavaBean + 映射文件
文件位置:javabean同包
文件名稱:javabean同名
擴展名:*.hbm.xml
內容:
添加約束
“`java
public class User {
/*
* create table t_user(
id int auto_increment primary key,
username varchar(50),
password varchar(30)
);
*/
private Integer uid;
private String username;
private String password;
```xml
<!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.itheima.a_hello.User" table="t_user">
<!-- 主鍵 -->
<id name="uid">
<!-- 固定值:主鍵生成策略 -->
<generator class="native"></generator>
</id>
<!-- 普通屬性 -->
<property name="username"></property>
<property name="password"></property>
</class>
</hibernate-mapping>
3.5 編寫核心配置文件
位置:類路徑(classpath、src)–>WEB-INF/classes
名稱:hibernate.cfg.xml
內容:
添加約束
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 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>
<!-- 添加映射文件 -->
<mapping resource="com/itheima/a_hello/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
3.6 測試
@Test
public void demo01(){
User user = new User();
user.setUsername("偉哥哥");
user.setPassword("1234");
//1 加載配置文件獲得核心配置對象
Configuration config = new Configuration().configure();
//2 獲得工廠 SessionFactory,相當於連接池
SessionFactory factory = config.buildSessionFactory();
//3獲得會話session,相當於鏈接Connection
Session session = factory.openSession();
//4 開啓事務
Transaction transaction = session.beginTransaction();
//操作
session.save(user);
//5 提交事務 | 回滾事務
transaction.commit();
//6 釋放資源--關閉session
session.close();
//7 釋放資源--關閉工廠factory
factory.close();
}
3.7 常見異常
解決方案:
將映射文件添加到核心配置文件中 hbm.xml –> hibernate.cfg.xml
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 與本地線程綁定 -->
<property name="hibernate.current_session_context_class">thread</property>
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個條件的屬性,那麼就增加一個沒有意義的列.作爲主鍵.
6.4 基本數據與包裝類型
- 基本數據類型和包裝類型對應hibernate的映射類型相同
- 基本類型無法表達null、數字類型的默認值爲0。
- 包裝類默認值是null。當對於默認值有業務意義的時候需要使用包裝類。
6.5 類型對應
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 自然主鍵,由程序自己維護。【】