<!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="cn.edu.aynu.rjxy.domain.User" table="s_user">
<!--主鍵-->
<id name="id">
<!--native意思:原生-->
<generator class="native"></generator>
</id>
<!--普通字段-->
<PRoperty name="username"></property>
<property name="passWord"></property>
</class>
</hibernate-mapping>
配置核心約束文件位置:類路徑(classpath、src)-->WEB-INF/classes
名稱:hibernate.cfg.xml
導入hibernate-configuration-3.0.dtd 的約束頭
hibernate.cfg.xml 
<?xml version="1.0" encoding="UTF-8"?>
<!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.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/day29hibernate_test01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">111</property>
<!--添加映射文件-->
<mapping resource="cn/edu/aynu/rjxy/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
復制User.hbm.xml 的全路徑,需要刪掉 src 前面的內容。
【4】編寫test.java 文件,測試項目。
package cn.edu.aynu.rjxy.test;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import cn.edu.aynu.rjxy.domain.User;
publicclassTest01{
publicstaticvoid main(String args[]){
test();
}
publicstaticvoid test(){
// [1]加載配置文件獲得核心配置對象
Configuration configuration =newConfiguration().configure();
// [2]獲得工廠 SessionFactory,相當于連接池( build 構造)
SessionFactory buildSessionFactory = configuration
.buildSessionFactory();
// [3]獲得會話session,相當于鏈接Connection
Session openSession = buildSessionFactory.openSession();
// 【4】 保存一個user 信息
User user =newUser();
user.setPassword("111");
user.setUsername("耿帥佳");
// [5] 操作
openSession.save(user);
// [6] 關閉資源
openSession.close();
buildSessionFactory.close();
}
}圖片:
控制臺打印 sql 語句 。
運行結果 :
二,分析常見的Api 字段。
【1】Hibernate 的執行過程。

【2】對Configuraction 詳解。
package cn.edu.aynu.rjxy.api;
import org.hibernate.cfg.Configuration;
import cn.edu.aynu.rjxy.domain.User;
publicclassConfiguration_test{
// 詳解 Configuraction 對象
publicvoid fun1(){
// 1.1 調用configure() 方法=> 加載src下名為hibernate.cfg.xml
// (調用configuraction() 方法 => 加載src下的 hibernate.properties)
Configuration configuration =newConfiguration().configure();
// <三種加載核心配置文件的方式:>
// 1.2 如果配置文件不符合默認加載規則.我們可以調用
// new Configuration().configure(file); 通過file加載
// new Configuration().configure(path); 通過指定的路徑加載
// <加載映射文件的兩種方式:>
// 1.3 可以通過Configuration對象加載 映射文件(不推薦)(映射文件就是:User.hbm.xml)
// 手動配置(不推薦)
// configuration.addClass(User.class);
// configuration.addResource("cn/edu/aynu/rjxy/domain/User.hbm.xml");
// 推薦hibernate.cfg.xml 使用 mapping 屬性引入配置文件
configuration.addClass(User.class);
configuration.addResource("cn/edu/aynu/rjxy/domain/User.hbm.xml");
// <ORM(User.hmb.xml) 映射文件編寫規范>
// 規范: 1>orm映射文件名稱與實體的簡單類名一致 (User.hbm.xml User.java )
// 2>orm映射文件 需要與實體的類在同一包下
}
}圖解:
【3】 對 SessionFactory 的詳解。
package cn.edu.aynu.rjxy.api;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
// 對sessionFactory 的詳解
publicclassSessionFactory_test{
//
publicvoid fun1(){
// 1加載配置
Configuration conf =newConfiguration().configure();
// 2 根據Configuration 配置信息創建 SessionFactory
// sessionFactory 可以理解為一個連接池,連接池中包含很多連接,而session 就相當于連接池中的 connection 對象
SessionFactory sf = conf.buildSessionFactory();
// 3 獲得session
// 3.1 openSession => 獲得一個全新的Session對象
sf.openSession();
// 3.2 getCurrentSession => 獲得與當前線程綁定的session對象
// 調用getCurrentSession 需要加上一個配置: <property
// name="hibernate.current_session_context_class">thread</property>
sf.getCurrentSession();
}
}圖解:
【4】詳解 Session 對象
測試我們常見的數據庫操作,增(insert),刪(delete),改(update),查(查一條,查所有,按條件查詢)(select)(1)在數據庫中添加一條數據。
調用了 session 的 save() 方法(主鍵自增) User user =newUser();
user.setUsername("test");
user.setPassword("111");
// 調用session 對象的 save 方法,來保存對象到數據庫中
session.save(user);添加數據 insert 
(2)修改一條數據,需要先查找到該對象,然后才能修改對象中的屬性
使用 update 方法// 先執行查的方法,找到需要修改的對象
User user =(User) session.get(User.class,1);
user.setUsername("耿帥佳--修改");
session.update(user);
(3)刪除一條數據,調用 delete 方法。 需要先找出該對象, 才能執行刪除。
// 先找出該對象
User user =(User) session.get(User.class,2);
// 再刪除
session.delete(user);
(5) 查詢一條記錄,查詢 id 為 2 的記錄。
(5.1)get 方法兩個參數 (Class class Serializable id) , 第二個參數就是標識的主鍵 // 查詢 id 為 2的這一條記錄。
User user =(User) session.get(User.class,2);
transaction.commit();
(5.1)使用 load 方法來查數據庫, 它不會立即查詢數據庫,當我們使用到這個對象的時候,就會查詢數據庫。User user =(User) session.load(User.class,2);
在debug 的模式下,我們執行到提交以后,再去點擊 user 對象,則會執行如下圖的查找。
比較:get()方法 和 load() 方法 get: get方法被調用時立刻 發送sql語句查詢load : 調用時并沒有查詢數據庫,當我們需要使用該對象的時候,才查詢數據(6)查詢所有,三種方式。
(6.1)使用HQL 語言進行查詢
(6.2)使用原生的sql 語句查詢
(6.3) 使用Hibernate 獨創的對象方式查詢 => 無語句
對應控制臺的輸出:
其中的問題:1 load方法.返回一個代理對象,獲得其內容時,會查詢數據庫,是每次訪問屬性都會查詢數據庫嗎?答:不是每次都查.代理對象中有一個標識是否被初始化的boolean型變量. 記錄是否被初始化過.2 代理都是要基于接口的,用load方法返回的代理,就沒有實現任何接口?答: java中的動態代理是基于接口. 而 Hibernate 是使用javassist-3.12.0.GA.jar 產生代理對象的.該代理與被代理對象之間的關系是繼承關系.與我們學的動態代理不是一種.所以不需要接口.【5】 詳解 Trancastion 對象。
事務是處理一系列的數據庫的操作。
注意: 事務關閉時,就會把當前線程上綁定的session 關閉,并刪除
【6】 詳解Query 對象
(1)可以使用這個對象,實現分頁顯示的功能。
(2)查詢一條結果。注意: 返回的結果只能是 一條,否則會報錯。
當返回多條數據的時候。
【7】詳解 Criteria 對象
criteria 是Hibernate 提供的面向對象查詢方式,無語言。(1) 查詢所有
Cretiaria對象 與 Query對象功能很像

(2)查詢username 屬性值為 jack 的記錄。(比較是否相等)
username 為javabean 中的一個屬性,對應數據庫的 username

(3)查詢username 屬性中有 a 這個字母的(Like)


總結:其它類似作用的方法調用
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) 模糊查詢,注意:模糊查詢值需要使用 % _
這些方法的命名,很像在學習數據庫的時候,中間使用的查詢條件。
【8】生成一個 HibernateUtils 的類。
package cn.edu.aynu.rjxy.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
publicclassHibernateUtils{
privatestaticSessionFactory sessionFactory;
static{
// 1加載配置
Configuration configuration =newConfiguration().configure();
// 2獲取seesionFactory
sessionFactory = configuration.buildSessionFactory();
Runtime.getRuntime().addShutdownHook(newThread(newRunnable(){
@Override
publicvoid run(){
System.out.println("虛擬機關閉!釋放資源");
sessionFactory.close();
}
}));
}
/**
* @return
*/
publicstaticSession openSession(){
return sessionFactory.openSession();
}
/**
* @return
*/
publicstaticSession getCurrentSession(){
return sessionFactory.getCurrentSession();
}
}三,核心配置文件詳解(hibernate.cfg.xml) (多讀)
代碼:<?xml version="1.0" encoding="UTF-8"?>
<!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.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/day29hibernate_test01</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">111</property>
<!-- show_sql:操作數據庫時,會向控制臺打印sql語句-->
<property name="show_sql">true</property>
<!-- format_sql:打印sql語句前,會將sql語句先格式化-->
<property name="format_sql">true</property>
<!-- hbm2ddl.auto:生成表結構的策略配置 update(最常用的取值):如果當前數據庫中不存在表結構,那么自動創建表結構.
如果存在表結構,并且表結構與實體一致,那么不做修改如果存在表結構,并且表結構與實體不一致,那么會修改表結構.會保留原有列. create(很少):無論是否存在表結構.每次啟動Hibernate都會重新創建表結構.(數據會丟失)
create-drop(極少):無論是否存在表結構.每次啟動Hibernate都會重新創建表結構.每次Hibernate運行結束時,刪除表結構.
validate(很少):不會自動創建表結構.也不會自動維護表結構.Hibernate只校驗表結構.如果表結構不一致將會拋出異常.-->
<property name="hbm2ddl.auto">update</property>
<!--數據庫方言配置 org.hibernate.dialect.MySQLDialect(選擇最短的)-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- hibernate.connection.autocommit:事務自動提交-->
<property name="hibernate.connection.autocommit">true</property>
<!--將Session與線程綁定=>只有配置了該配置,才能使用getCurrentSession -->
<property name="hibernate.current_session_context_class">thread</property>
<!--引入ORM 映射文件填寫src之后的路徑-->
<!--添加映射文件-->
<mapping resource="cn/edu/aynu/rjxy/domain/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>四,映射配置文件(PO.hbm.xml)
【1】對PO (持久化類)的要求 :
(1)提供一個無參的 public 的構造方法 (2)提供一個標識屬性,既在數據庫中當作主鍵 (3)提供public 的get 和 set 方法 (4)使用包裝類型來標識屬性 (5)不要對實體使用 final ,否則無法生成代理對象
1.1 持久化對象的唯一標識 OID
lJava按地址區分同一個類的不同對象.
l關系數據庫用主鍵區分同一條記錄
lHibernate使用OID來建立內存中的對象和數據庫中記錄的對應關系
結論: 對象的OID和數據庫的表的主鍵對應。為保證OID的唯一性,應該讓Hibernate來為OID付值
1.2 區分自然主鍵和代理主鍵
l 主鍵需要具備: 不為空/不能重復/不能改變
自然主鍵: 在業務中,某個屬性符合主鍵的三個要求.那么該屬性可以作為主鍵列.
代理主鍵: 在業務中,不存符合以上3個條件的屬性,那么就增加一個沒有意義的列.作為主鍵.

1.3 基本數據與包裝類型
l基本數據類型和包裝類型對應hibernate的映射類型相同
l基本類型無法表達null、數字類型的默認值為0。
l包裝類默認值是null。當對于默認值有業務意義的時候需要使用包裝類。
我們在設置參數的數據類型參照這個表,設置。Java數據類型
Hibernate數據類型
標準SQL數據類型(PS:對于不同的DB可能有所差異)
byte、java.lang.Byte
byte
TINYINT
short、java.lang.Short
short
SMALLINT
int、java.lang.Integer
integer
INGEGER
long、java.lang.Long
long
BIGINT
float、java.lang.Float
float
FLOAT
double、java.lang.Double
double
DOUBLE
java.math.BigDecimal
big_decimal
NUMERIC
char、java.lang.Character
character
CHAR(1)
boolean、java.lang.Boolean
boolean
BIT
java.lang.String
string
VARCHAR
boolean、java.lang.Boolean
yes_no
CHAR(1)('Y'或'N')
boolean、java.lang.Boolean
true_false
CHAR(1)('Y'或'N')
java.util.Date、java.sql.Date
date
DATE
java.util.Date、java.sql.Time
time
TIME
java.util.Date、java.sql.Timestamp
timestamp
TIMESTAMP
java.util.Calendar
calendar
TIMESTAMP
java.util.Calendar
calendar_date
DATE
byte[]
binary
VARBINARY、BLOB
java.lang.String
text
CLOB
java.io.Serializable
serializable
VARBINARY、BLOB
java.sql.Clob
clob
CLOB
java.sql.Blob
blob
BLOB
java.lang.Class
class
VARCHAR
java.util.Locale
locale
VARCHAR
java.util.TimeZone
timezone
VARCHAR
java.util.Currency
currency
VARCHAR
【2】映射文件配置詳解(記住)
代碼:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- ORM元數據表對象關系映射文件
package:配置該配置文件中類所在的包.-->
<hibernate-mapping package="com.itheima.a_hello">
<!--class:配置實體與表的關系
name :填寫實體的完整類名
table:與實體對應表的名稱
dynamic-insert:動態插入默認值是false
true=>如果字段值為null,不參與insert語句
dynamic-update:動態更新默認值"false"
true=>沒改動過的屬性,將不會生成到update語句中
-->
<class name="User" table="t_user">
<!-- id:配置實體與表中 id對應
name: user對象中標識主鍵的屬性名稱
column:主鍵在表中的列名
length:列的數據長度
unsaved-value(不常用):指定主鍵為什么值時,當做null來處理.
access(強烈推薦不要用):field 那么在操作屬性時,會直接操作對應的字段而不是get/set方法
-->
<id name="id" column="id" length="255">
<!-- generator:主鍵生成策略
1.increment數據庫自己生成主鍵.先從數據庫中查詢最大的ID值,將ID值加1作為新的主鍵
2.identity依賴于數據的主鍵自增功能
3.sequence序列,依賴于數據中的序列功能(Oracle).
4.hilo(純了解,永遠用不到):Hibernate自己實現序列的算法,自己生成主鍵.(hilo算法)
5.native自動根據數據庫判斷,三選一. identity|sequence|hilo
6.uuid生成32位的不重復隨機字符串當做主鍵
7.assigned自己指定主鍵值.表的主鍵是自然主鍵時使用.
-->
<generator class="uuid"></generator>
</id>
<!-- property :實體中屬性與表中列的對應
name :實體中屬性名稱
column :表中列的名稱
length :數據長度
precision:小數點后的精度
scale:有效位數
insert(一般不用):該屬性是否加入insert語句.
update(一般不用):該屬性是否加入update語句.
not-null:指定屬性的約束是否使用非空
unique :指定屬性的約束是否使用唯一
-->
<!--
type:表達該屬性的類型
可以用三種方式指定屬性
java類型數據庫類型指定Hibernate類型指定
java.lang.String varchar string
-->
<property name="name" column="name" update="true" type="string"></property>
<property name="password" column="password"></property>
<property name="sal" column="sal" precision="2" scale="3"></property>
</class>
</hibernate-mapping>
新聞熱點
疑難解答