Hibernate基礎知識(一)

Hibernate_day01總結

今日內容

Hibernate框架的概述

Hibernate的快速入門

日誌記錄

Hibernate常見配置及核心API

Hibernate的持久化類

主鍵的生成策略

1.1 Struts2的複習

第一天:

* Struts2入門:(流程)

第二天:

* Struts2數據封裝/類型轉換/數據校驗/國際化/攔截器

第三天:

* 文件上傳/下載 值棧和OGNL. 防止表達重複提交.

第四天-第五天:

 

Struts2基於MVC設計模式web層框架.

 

1.2 Hibernate框架的概述:

1.2.1 什麼是Hibernate:

框架:軟件的半成品,完成部分功能代碼.

 

Hibernate:Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSPWeb應用中使用,最具革命意義的是,Hibernate可以在應用EJBJ2EE架構中取代CMP,完成數據持久化的重任。

 

Hibernate是輕量級JavaEE應用的持久層解決方案,是一個關係數據庫ORM框架.

* ORM:Object Relational Mapping.

* 傳統方式開發:

* 持久層:

* 編寫SQL.執行SQL. String sql = insert into values (?,?,?...);

* 開發語言Java:面向對象.

* 數據庫:MySQL(關係型的數據庫.)

* Java中的實體類與數據庫的關係表建立一個映射.就可以操作Java中對象,從而操作數據庫.

 

***** Hibernate就是一個持久層的ORM的框架.

 

常見的持久層框架:

* Hibernate:

* JPA:JPA Java Persistence API.JPA通過JDK 5.0註解或XML描述對象-關係表的映射關係(只有接口規範)

* MyBatis:前身Ibatis.

* 企業開發兩套架構:

* SSH:Struts2 + Spring + Hibernate

* SSI:SpringMVC + Spring + Ibatis

* DbUtils:

 

1.2.2 爲什麼要學習Hibernate:

HibernateJDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼

Hibernate是一個基於jdbc的主流持久化框架,是一個優秀的orm實現,它很大程度的簡化了dao層編碼工作

Hibernate使用java的反射機制,而不是字節碼增強程序類實現透明性

Hibernate的性能非常好,因爲它是一個輕量級框架。映射的靈活性很出色。它支持很多關係型數據庫,從一對一到多對多的各種複雜關係.

 

1.2.3 Hibernate版本:

Hibernate3.x版本 和 Hibernate4.x

* 企業中常用的還是Hibernate3.x.

 

1.3 Hibernate的日誌記錄:

日誌:程序開發中的一些信息.

 

常用信息輸出:System.out.println(“”);

* 這種方式不好:

* 如果輸出內容比較多,項目已經開發完畢,不想使用輸出.需要打開每個類,將輸出的代碼註釋.

 

日誌:Hibernate中使用slf4j技術.

slf4j:SLF4J,即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,它只服務於各種各樣的日誌系統。

* 用於整合其他日誌系統.

在企業中常用的日誌記錄:log4j

* 是具體的日誌記錄方案.

 

Log4J的日誌級別:

* fatal(致命的)error(普通錯誤)warn(警告)info(信息)debug(調試)trace(堆棧信息).

Logger.error(錯誤信息);  

* 通過配置文件的形式,顯示錯誤信息.

* 配置的級別是info.

 

Log4J的三個組件:

記錄器(Loggers

* 格式:記錄器 = 級別, 輸出源1 , 輸出源2

* log4j.rootLogger=info, stdout

輸出源(Appenders

* log4j.appender.stdout=org.apache.log4j.ConsoleAppender:控制檯進行輸出.

* log4j.appender.file=org.apache.log4j.FileAppender:向文件進行輸出.

佈局(Layouts

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

1.4 Hibernate的入門:

1.4.1 Hibernate的入門:

第一步:下載Hibernate的開發包:

http://sourceforge.net/projects/hibernate/files/hibernate3

 

第二步:Hibernate框架目錄結構:

documentation:Hibernate文檔

lib:Hibernate開發jar

* bytecode:操作字節碼jar.

* jpa:Hibernate的實現jpa規範.

* optional:Hibernate的可選jar.

* required:Hibernate的必須的jar.

project:Hibernate提供的工程

 

第三步:創建一個工程:(Java工程)

導入相應jar:

* hibernate3.jar

* HIBERNATE_HOME/lib/required/*.jar

* HIBERNATE_HOME/lib/jpa/hibernate-jpa-2.0-api-1.0.1.Final.jar

* 導入日誌記錄的包:

* log4j-1.2.16.jar

* slf4j-log4j12-1.7.2.jar

* 導入數據庫驅動:

 

第四步:創建表:(關係型數據庫)

create database hibernate3_day01;

use hibernate3_day01;

create table customer(

id int primary key auto_increment,

name varchar(20),

age int

);

 

第五步:創建一個實體類:(面向對象)

public class Customer {

private int id;

private String name;

private int age;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

}

 

第六步:創建ORM的映射.

映射文件只要是一個XML格式文件就可以.名字任意.

* 通常情況下名稱規範:

* 實體類名稱.hbm.xml

引入約束:

* hibernate3.jar/org.hibernate.hibernate-mapping-3.0.dtd

 

<!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 :類的全路徑  table:表名稱 -->

<class name="cn.itcast.hibernate3.demo1.Customer" table="customer">

<!-- 建立類中屬性與表中的字段映射 -->

<!-- 唯一標識 -->

<!-- 使用id的標籤 配置唯一屬性 -->

<!-- <id>標籤中配置一個主鍵的生成策略. -->

<id name="id" column="id">

<generator class="native"/>

</id>

<!-- 普通屬性 -->

<!-- property標籤:映射類中的普通屬性 name:類中的屬性名稱, column:表中字段名稱 -->

<!--

type:三種寫法

* Java類型:java.lang.String

* Hibernate類型:string

* SQL類型:不能直接使用type屬性,需要子標籤<column>

* <column name="name" sql-type="varchar(20)"/>

 -->

<property name="name" column="name" type="string"/>

<property name="age" column="age"/>

</class>

</hibernate-mapping>

 

第七步:創建一個Hibernate的核心配置文件.

通知Hibernate連接是哪個數據庫.

src下創建一個hibernate.cfg.xml

 

<hibernate-configuration>

<session-factory>

<!-- 必須去配置的屬性 -->

<!-- 配置數據庫連接的基本信息: -->

<property name="hibernate.connection.driver_class">

com.mysql.jdbc.Driver

</property>

<property name="hibernate.connection.url">

jdbc:mysql:///hibernate3_day01

</property>

<property name="hibernate.connection.username">root</property>

<property name="hibernate.connection.password">123</property>

<!-- Hibernate的方言 -->

<!-- 生成底層SQL不同的 -->

<property name="hibernate.dialect">

org.hibernate.dialect.MySQLDialect

</property>

 

<!-- 可選的屬性 -->

<!-- 顯示SQL -->

<property name="hibernate.show_sql">true</property>

<!-- 格式化SQL -->

<property name="hibernate.format_sql">true</property>

<!-- hbm:映射 to DDL: create drop alter -->

<property name="hibernate.hbm2ddl.auto">update</property>

 

<!-- 通知Hibernate加載那些映射文件 ->

<mapping resource="cn/itcast/hibernate3/demo1/Customer.hbm.xml" />

 

</session-factory>

</hibernate-configuration>

 

第八步:編寫測試

向數據庫中插入一條記錄

@Test

// 向數據庫中插入一條記錄

public void demo1(){

// 1.Hiberante框架加載核心配置文件(有數據庫連接信息)

Configuration configuration = new Configuration().configure();

// 2.創建一個SessionFactory.(獲得Session--相當連接對象)

SessionFactory sessionFactory = configuration.buildSessionFactory();

// 3.獲得Session對象.

Session session = sessionFactory.openSession();

// 4.默認的情況下,事務是不自動提交.

Transaction tx = session.beginTransaction();

// 5.業務邏輯操作

// 向數據庫中插入一條記錄:

Customer customer = new Customer();

customer.setName("任童");

customer.setAge(28);

session.save(customer);

// 6.事務提交

tx.commit();

// 7.釋放資源

session.close();

sessionFactory.close();

}

 

1.4.2 HibernateCRUD的操作

保存記錄:

* session.save(customer);

 

根據主鍵進行查詢:

* Customer customer = (Customer)session.get(Customer.class ,1);

* Customer customer = (Customer)session.load(Customer.class,1);

 

***** get load的區別:(面試題)

* 1.發送SQL的時機:

* load這個方法採用了一個技術.lazy延遲加載(懶加載).真正使用這個對象的數據的時候.(對象的數據不包括主鍵).

* get這個方法是立即檢索.當執行session.get()方法的時候,馬上發送SQL語句查詢.

 

* 2.返回的對象:

* load方法返回的是代理對象.

* get方法返回的是真實的對象.

 

* 3.查詢一個不存在的數據:

* load方法拋異常:ObjectNotFoundException.

* get方法拋異常:NullPointException.

 

修改記錄

* session.update(customer);

修改有兩種方式 :

// 5.1手動創建對象的方式

Customer customer = new Customer();

customer.setId(2);

customer.setName("蒼老師");

session.update(customer);

***** 這種方式如果沒有設置的屬性,將這個屬性的默認值存入了.(不好.)

 

// 5.2先查詢在修改的方式(推薦方式)

Customer customer = (Customer) session.get(Customer.class, 1);

customer.setName("鳳姐");

session.update(customer);

 

刪除記錄:

* session.delete(customer);

刪除記錄有兩種方式:

// 5.1手動創建對象的方式

Customer customer = new Customer();

customer.setId(2);

session.delete(customer);

 

// 5.2先查詢在刪除的方式

Customer customer = (Customer)session.get(Customer.class, 1);

session.delete(customer);

 

查詢所有:

HQL:

HQL:Hibernate Query Language.

面向對象的寫法:

Query query = session.createQuery("from Customer where name = ?");

query.setParameter(0, "蒼老師");

Query.list();

 

QBC:

Query By Criteria.(條件查詢)

 

Criteria criteria = session.createCriteria(Customer.class);

criteria.add(Restrictions.eq("name", "鳳姐"));

List<Customer> list = criteria.list();

SQL:

SQLQuery query = session.createSQLQuery("select * from customer");

List<Object[]> list = query.list();

 

SQLQuery query = session.createSQLQuery("select * from customer");

query.addEntity(Customer.class);

List<Customer> list = query.list();

1.5 Hibernate的常用的配置及核心API.

1.5.1 Hibernate的常見配置:

核心配置:

核心配置有兩種方式進行配置:

* 屬性文件的配置:

* hibernate.properties

* 格式:

* key=value

* hibernate.connection.driver_class=com.mysql.jdbc.Driver

***** 注意:沒有辦法在覈心配置文件中加載映射文件.(必須手動編碼的方式進行加載.)

 

* XML格式文件配置:

* hibernate.cfg.xml

* 格式:

<property name="hibernate.connection.username">root</property>

 

核心配置中:

1.必須的配置:

* 連接數據庫4個基本參數:

hibernate.connection.driver_class  連接數據庫驅動程序

hibernate.connection.url   連接數據庫URL

hibernate.connection.username  數據庫用戶名

hibernate.connection.password   數據庫密碼

 

* Hibernate的方言:

hibernate.dialect   操作數據庫方言

 

2.可選的配置:

hibernate.show_sql  true 在控制檯上輸出SQL語句

hibernate.format_sql  true  格式化控制檯輸出的SQL語句

hibernate.connection.autocommit  true 事務是否自動提交

hibernate.hbm2ddl.autocreate/create-drop/update/validate

* create:每次執行的時候,創建一個新的表.(如果以前有該表,將該表刪除重新創建.) 一般測試的時候的使用.

* create-drop:每次執行的時候,創建一個新的表,程序執行結束後將這個表,刪除掉了.一般測試的時候使用.

* update:如果數據庫中沒有表,創建一個新的表,如果有了,直接使用這個表.可以更新表的結構.

* validate:會使用原有的表.完成校驗.校驗映射文件與表中配置的字段是否一致.不一致報錯.

 

3.映射的配置:

* 在覈心配置文件中加載映射文件:

* <mapping resource="cn/itcast/hibernate3/demo1/Customer.hbm.xml" />

* 使用手動編碼的方式進行加載 :

 

映射文件的配置:

ORM:對象和關係映射.

* 配置Java對象與表映射.

* 配置類與表的映射:

* name:類的全路徑:

* table:表的名稱:(可以省略的.使用類的名稱作爲表名.)

<class name="cn.itcast.hibernate3.demo1.Order" table=orders>

 

* 配置普通屬性與字段映射:

<property name="name" column="name" type="string" length=20/>

type:三種寫法

* Java類型:java.lang.String

* Hibernate類型:string

* SQL類型:不能直接使用type屬性,需要子標籤<column>

* <column name="name" sql-type="varchar(20)"/>

 

* 配置唯一標識與主鍵映射:

* 一個表中只有一個主鍵的形式:

<id name=id column=id>

* 生成策略:

 

* 一個表對應多個主鍵形式:(複合主鍵:)---瞭解.

* <composite-id></composite-id>

 

* 關聯關係:

* 命名SQL:

<query name="findAll">

from Customer

</query>

<sql-query name="sqlFindAll">

select * from customer

</sql-query>

 

1.6 Hibernate的核心API:

1.6.1 Hibernate的核心API:

Configuration:負責管理 Hibernate 的配置信息

1.加載核心配置文件:

核心配置有兩種:

* hibernate.properties:

* 加載:

* Configuration configuration = new Configuration();

* hibernate.cfg.xml:

* 加載:

* Configuration configuration = new Configuration().configure();

 

2.加載映射文件:

* 第一種寫法:

* configuration.addResource("cn/itcast/hibernate3/demo1/Customer.hbm.xml");

* 第二種寫法:(要求:映射文件名稱要規範,類與映射在同一個包下)

* configuration.addClass(Customer.class);

 

SessionFactory:Session工廠.

Configuration對象根據當前的配置信息生成 SessionFactory對象

SessionFactory 對象中保存了當前的數據庫配置信息和所有映射關係以及預定義的SQL語句

SessionFactory 對象是線程安全的

SessionFactory還負責維護Hibernate的二級緩存

 

SessionFactory對象根據數據庫信息,維護連接池,創建Session(相當於Connection)對象.

 

抽取工具類:

public class HibernateUtils {

private static Configuration configuration;

private static SessionFactory sessionFactory;

static{

configuration = new Configuration().configure();

sessionFactory = configuration.buildSessionFactory();

}

public static Session openSession(){

return sessionFactory.openSession();

}

public static void main(String[] args) {

openSession();

}

}

 

Hibernate中使用c3p0連接池:

* 引入c3p0jar

* 在覈心配置中添加一段配置:

<!-- C3P0連接池設定-->

<!-- 使用c3po連接池  配置連接池提供的供應商-->

<property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider                                                                                                                                        </property>

<!--在連接池中可用的數據庫連接的最少數目 -->

<property name="c3p0.min_size">5</property>

<!--在連接池中所有數據庫連接的最大數目  -->

<property name="c3p0.max_size">20</property>

<!--設定數據庫連接的過期時間,以秒爲單位,

如果連接池中的某個數據庫連接處於空閒狀態的時間超過了timeout時間,就會從連接池中清除 -->

<property name="c3p0.timeout">120</property>

 <!--3000秒檢查所有連接池中的空閒連接 以秒爲單位-->

<property name="c3p0.idle_test_period">3000</property>

 

Session:

相當於 JDBCConnection

Session 是應用程序與數據庫之間交互操作的一個單線程對象,是 Hibernate 運作的中心

Session是線程不安全的

所有持久化對象必須在 session 的管理下纔可以進行持久化操作

Session 對象有一個一級緩存,顯式執行 flush 之前,所有的持久化操作的數據都緩存在 session 對象處

持久化類與 Session 關聯起來後就具有了持久化的能力

Session維護了Hiberante一級緩存.

 

save()/persist():添加.

update() :修改

saveOrUpdate() :增加和修改對象

delete()  :刪除對象

get()/load()  :根據主鍵查詢

createQuery() :創建一個Query接口,編寫HQL語句

createSQLQuery() :創建一個SQLQuery接口,編寫SQL語句數據庫操作對象

createCriteria()  :返回一個Criteria接口.條件查詢

 

Transaction:

獲得:

Transaction tx = session.beginTransaction();

 

常用方法:

commit():提交相關聯的session實例

rollback():撤銷事務操作

wasCommitted():檢查事務是否提交

 

***** 如果沒有開啓事務,那麼每個Session的操作,都相當於一個獨立的事務

 

Query

Query代表面向對象的一個Hibernate查詢操作

session.createQuery 接受一個HQL語句

HQLHibernate Query Language縮寫, 語法很像SQL語法,但是完全面向對象的

 

Criteria

Criteria條件查詢:

 

1.7 Hibernate中的持久化類:

持久化類:實體類 + 映射文件.

 

持久化類是有編寫規範:

* 提供一個無參數 public訪問控制符的構造器:用到反射.

* 提供一個標識屬性,映射數據表主鍵字段:

* java區分兩個對象是否是同一個使用 地址.

* 數據庫區分兩條記錄是否一致:使用  主鍵.

* Hibernate中區分持久化對象是否是同一個,根據唯一標識:

* 所有屬性提供public訪問控制符的 set  get 方法:框架中存值和取值的時候使用.

* 標識屬性應儘量使用基本數據類型的包裝類型

* 使用基本數據類型:

* 成績表:

學號姓名成績

1張三null

* 持久化類儘量不要使用final進行修飾:

* final修飾的類是不能被繼承.無法生成代理對象.(延遲加載的時候返回代理對象.延遲加載就失效.)

 

建表的時候:

* 自然主鍵和代理主鍵:

* 自然主鍵:

* 創建一個人員表.人員表中某條記錄唯一確定.人都有身份證號.我們可以使用身份證號作爲主鍵.(身份證號本身就是人員的一個屬性.作爲主鍵.)

 

* 代理主鍵:

* 創建一個人員表.人員表中某條記錄唯一確定.但是沒有使用身份證號作爲主鍵,新建字段(用新建的字段作爲主鍵.只是一個標識作用.)

 

* 儘量要Hibernate自己去維護主鍵:

* 主鍵的生成策略:

* increment:自動增長.適合 short int long...不是使用數據庫的自動增長機制.使用Hibernate框架提供的自動增長方式.

* select max(id) from ; 在最大值的基礎上+1.(多線程的問題.)在集羣下不要使用

 

* identity:自動增長.適合 short int long...採用數據庫的自動增長機制.適合於Oracle數據庫.

* sequence:序列.適用於 short int long ... 應用在Oracle.

* uuid:適用於字符串類型的主鍵.採用隨機的字符串作爲主鍵.

* native:本地策略.底層數據庫不同.自動選擇適用identity 還是 sequence.

* assigned:Hibernate框架不維護主鍵,主鍵由程序自動生成.

* foreign:主鍵的外來的.(應用在多表一對一的關係.)

 

今天的內容總結:

Hibernate第一天學習:

* Hibernate框架:

* 就是一個持久層的ORM框架.

* ORM:Object Relational Mapping

* 常見持久層框架:

 

* Hibernate入門:

* 關鍵配置映射和核心配置.

* 編寫測試程序.

 

* HibernateCRUD:

* Hibernate的配置:

* 核心配置:

屬性文件:

XML文件:

* 映射配置:

 

* Hibernate的核心API:

* Hibernate的持久化的類編寫:

* 無參數構造:

* 屬性提供set/get方法

* 屬性儘量使用包裝類

* 類不要使用final

* 提供唯一標識OID

* Hibernate主鍵生成策略:

 

 

作業 :

* 搭建Hibernate的環境 :

* 抽取Hibernate工具類.

* CRUD.

* 映射文件和核心配置文件.

 

 

 

 

 

 

 

 

 

 

 

 


發佈了66 篇原創文章 · 獲贊 22 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章