hibernate是位於數據層(持久層)的框架。主要用於封裝對數據的操做 mysql
hibernate 做用是將面向關係型數據庫的操做,轉換成面向對象的操做 算法
所以,須要有數據庫與對象的映射關係,也成ORM元數據 sql
JPA包: 數據庫
required包: 緩存
mysql數據庫驅動包: session
文件名: ClassName + .hbm.xml app
存放位置: 與相應類同包 框架
元數據文件解讀: dom
<?xml version="1.0" encoding="UTF-8"?> ide
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!—dtd約束,從hibernate核心包裏的 org.hibernate 包內的hibernate-mapping-3.0.dtd拷貝 -->
<hibernate-mapping>
<!-- key 是配置主鍵的生成策略 -->
<class name="cn.xiaoge.domain.Student" table="t_student">
<id name="id">
<!-- key 是配置主鍵的生成策略
#1 increment 主鍵自增(先查詢數據庫中最大id,而後再+1)
#2 identity mysql中的主鍵自增
#3 sequence oracl中的主鍵自增
#4 hilo hilo算法,也能實現主鍵自增
#5 native 自動匹配identity sequence hilo這三種
#6 uuid 利用uuid自動生成主鍵
#7 assigned 手動設置主鍵
-->
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 配置一對多 -->
<!--
set元素 表示 一對多 或 多對多的關係
inverse屬性 表示是否不維護關聯關係(若是不維護關聯關係,值應設置爲true)
cascade表明級聯
#1 save-update(偶爾用) 保存及更新
#2 delete(不用) 刪除相關的元素
#3 all(不用) save-update + delete
#4 delete-orphan(不用) 刪除孤兒元素(如,外鍵爲空的order會被刪除)
#5 all-delete-orphan(不用) 至關於 all + delete-orphan
#6 none 默認值 無關聯
-->
<set name="courses" table="t_student_course">
<!—key 是配置本身被引用做外鍵時的屬性 -->
<key column="sid"></key>
<!-- class 必定要寫全類名,或者以前配置package column是class對應的外鍵名 -->
<many-to-many class="cn.xiaoge.domain.Course" column="cid">
</many-to-many>
</set>
</class>
</hibernate-mapping>
文件名: hibernate.cfg.xml (固定名)
存放位置: src目錄下
基本配置:
<?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>
<!-- 配置數據庫鏈接的基本信息(驅動名,url,用戶名,密碼---合稱「四大天王」) -->
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql:///myhibernate01
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<!-- 配置是否顯示sql語句 -->
<property name="show_sql">true</property>
<!-- 是否將sql語句格式化輸出 -->
<property name="format_sql">true</property>
<!--
hbm2ddl.auto 表結構生成策略
create(學習、測試) 每次啓動時從新建立表結構
create-drop(學習、測試) 每次啓動時從新建立表結構,在關閉時,將表刪除
update(學習時用) 操做表時,表不存在就建立表,表存在就在原表操做
validate 驗證表,操做表時,表不存在,或表結構不符合,就拋出異常
-->
<property name="hbm2ddl.auto">update</property>
<!-- 設置當前session與 xx 綁定(通常設置與線程綁定) -->
<property name="current_session_context_class">thread</property>
<!-- 設置sql語句的方言(通常選擇最短的那個方言) -->
<property name="dialect">
org.hibernate.dialect.MySQL5Dialect
</property>
<!-- 配置映射文件 -->
<mapping resource="cn/xiaoge/domain/User.hbm.xml" />
</session-factory>
</hibernate-configuration>
特色:
無oid && 未與session鏈接(不在session緩存中)
特色:
有oid && 與session鏈接
特色:
有oid && 不與session鏈接
注意:
有id,可是數據庫中沒有與之相應的id。這種對象不能算做是遊離狀態,勉強也只能算是瞬時狀態
一對多:(如顧客Customer與訂單Order的關係)
(1)在Customer的實體類中,引用Order的set集合
private Set<Order> orders = new HashSet<Order>();
(2)在Customer.hbm.xml映射文件中,添加set元素
<set name="orders" cascade="save-update">
<key column="cid"></key> //表示是本身主鍵被引用的列名
<one-to-many class="cn.xiaoge.domain.Order" /> //注意,class是多的一方的全名
</set>
多對一:
(3)在Order的實體類中,引用Customer的對象
private Customer customer;
(4)在Order.hbm.xml的關係映射文件中,作以下配置
<many-to-one name="customer" column="cid" class="cn.xiaoge.bean.Customer">
</many-to-one>
多對多(如學生Student與課程Course)
(1)在Student的實體類中,引用Course的set集合
private Set<Student> students = new HashSet<Student>();
(2)在Student.hbm.xml配置關係映射
<set name="courses" table="t_student_course"> //多對多的中間表
<key column="sid"></key> //sid 是中間表引用student主鍵時的外鍵名
<many-to-many class="cn.xiaoge.bean.Course" column="cid">
</many-to-many> //cid 是中間表引用Course主鍵時的外鍵名
</set>
(3)在Course與Course.hbm.xml中,作相似操做,注意,是相似,不是如出一轍!!!
一對一關係:如公司與註冊登記的公司地點
(1)在Company中引用地址的對象
private Address address;
(2)在Company.hbm.xml中作以下配置:
<one-to-one name="address" class="cn.xiaoge.bean.Address"></one-to-one>
(3)在Address的實體類中引用Company
private Company company;
(4)在Address.hbm.xml中作以下配置:
//方式一
<id name="id">
<generator class="foreign">
<param name="property">company</param>
</generator>
</id>
<one-to-one name="company" class="cn.xiaoge.bean.Company" constrained="true">
</one-to-one>
//方式二
<id name="id">
<generator class="native"></generator>
</id>
<property name="address"></property>
<many-to-one name="company" class="cn.xiaoge.bean.Company"
column="cid" unique="true">
</many-to-one>
涉及的方法: load方法
涉及的屬性: class元素上的lazy屬性
lazy : true(默認值): 延遲檢索 => 不會當即發送sql查詢.使用時才查詢
lazy : false : 當即檢索 => 會當即發送sql查詢.
注: get方法永遠是當即檢索.
結論: 延遲檢索用於提升效率.若是不用, 不會檢索.使用時才加載.
一對多:
涉及屬性:
fetch屬性: 決定加載關聯數據時使用哪一種sql語句
select(默認值): 會使用單表查詢select語句加載關聯數據.
join: 會使用表連接語句加載關聯數據.
subselect:使用子查詢加載關聯數據
lazy屬性: 決定加載關聯數據的時機
true: 延遲加載.=> 在使用關聯數據時纔會加載.
false: 當即加載.=> 不管是否使用關聯數據,都會當即加載
extra: 極其懶惰.=> 若是僅僅得到關聯數據集合的size.只會發送count聚合函數查詢數量.
策略配置:
fetch(默認值) : select
lazy(默認值) : true
//結論: 使用關聯數據時,才加載關聯數據.加載時使用單表select查詢.
---------------------------------------------------------------------
fetch(默認值) : select
lazy(默認值) : false
//結論: 得到客戶時,當即加載與客戶關聯的訂單數據.使用單表select查詢
---------------------------------------------------------------------
fetch(默認值):select
lazy(默認值): extra
//結論: 加載客戶時,不會加載關聯的訂單.打印訂單數量時,
//只發送count查詢數量.打印屬性時,會發送單表select查詢.
---------------------------------------------------------------------
fetch(默認值):join
lazy(默認值): true/false/extra
//結論: fetch使用多表查詢,必定會同時加載關聯數據. 那麼lazy屬性失效.
----------------------------------------------------------------------
fetch(默認值) : subselect 子查詢 =>
//查詢單個客戶=>至關於select
//查詢多個客戶=> 加載多個客戶的關聯數據時,會使用子查詢
lazy(默認值): false
//結論: 加載多個客戶數據時,會當即使用子查詢加載全部客戶的訂單數據.
----------------------------------------------------------------------
fetch(默認值):subselect 子查詢 => 查詢單個客戶=>至關於select
//查詢多個客戶=> 加載多個客戶的關聯數據時,會使用子查詢
lazy(默認值): true
//結論: 查詢多個客戶時,不會當即查詢客戶下的訂單數據. 使用訂單時,會使用子查詢加載全部客戶的訂單數據
-----------------------------------------------------------------------
fetch(默認值):subselect 子查詢 => 查詢單個客戶=>至關於select
//查詢多個客戶=> 加載多個客戶的關聯數據時,會使用子查詢
lazy(默認值): extra
//結論: 查詢多個客戶時,不會當即查詢客戶下的訂單數據.打印客戶的訂單數量時,只會發送count查詢數量. 使用訂單具體屬性時,會使用子查詢加載全部客戶的訂單數據
多對一:
涉及屬性:
fetch屬性: 使用什麼樣的sql語句查詢
select:單表select查詢
join:多表鏈接
lazy屬性: 加載策略
false:當即加載
proxy:我不決定加載策略.由對方類級別加載策略決定
no-proxy: 不作研究.
測試:
fetch(默認值):select
lazy(默認值): false
//結論: 查詢訂單時,會當即查詢訂單的客戶.會發送多條單表查詢select.
--------------------------------------------------------------------
fetch(默認值):select
lazy(默認值): proxy
//true
//false
//結論: 查詢訂單時,發送多條單表查詢select. 至因而否當即加載,要看Customer的類級別加載策略.
--------------------------------------------------------------------
// fetch(默認值):join
// lazy(默認值): proxy/false
//結論: 加載訂單時,會使用多表查詢,同時加載訂單的客戶數據. lazy屬性失效
關聯級別檢索策略(一對多) |
|||
Fetch Lazy |
select |
join |
subselect |
true |
使用關聯數據時,才加載關聯數據.並使用單表select查詢 |
當即查詢關聯數據,多表查詢,lazy屬性失效 |
延時查詢關聯數據,在關聯數據時,使用子查詢 |
false |
查詢主對象時,當即加載關聯數據,並使用單標select查詢 |
當即查詢關聯數據,多表查詢,lazy屬性失效 |
當即查詢關聯數據,並使用子查詢 |
extra |
延時查詢關聯數據時, 查詢關聯數據數量時,只查詢數量,不查詢關聯對象的具體信息 |
當即查詢關聯數據,奪標查詢,lazy屬性失效 |
延時查詢關聯數據,查詢關聯數據數量時,只查詢數量,不查詢關聯對象的具體信息 |
關聯級別檢索策略(多對一) |
||
Fetch Lazy |
select |
join |
false |
例如:查詢訂單時,當即查詢訂單的客戶.並會發送多條單表查詢select |
當即查詢關聯數據,且是多表查詢,lazy屬性失效 |
proxy |
例如:查詢訂單時,會依據顧客的lazy屬性值。若顧客的lazy=「false「,當即查詢訂單的客戶.並會發送多條單表查詢select。若顧客的lazy=「true」,會延時查詢顧客信息 |
當即查詢關聯數據,且是多表查詢,lazy屬性失效 |
no-proxy |
不研究 |
不研究 |
1. 根據OID查詢.
參考類級別檢索策略。能夠分爲get(Xxx.class,oid)和load(Xxx.class,oid)
2.對象視圖導航.
根據對象.屬性,或 對象.方法()進行查詢
3.SQL查詢
相似mysql語句查詢,詳細信息查看mysql總結:http://my.oschina.net/xiaogezi/blog/631825
4.HQL查詢
HQL:Hibernate Query Language
基本查詢: Query query = session.createQuery("from Customer");
條件查詢: Query query = session.createQuery("from Customer where id = 1");
投影查詢: Query query = session.createQuery("select new Customer(c.cid,c.cname) from Customer c");
排序: Query query = session.createQuery("from Customer order by cid desc");
分頁:
Query query = session.createQuery("from Customer");
// *** pageNum 當前頁(以前的 pageCode)
query.setFirstResult(0);
// * 每頁顯示個數 , pageSize
query.setMaxResults(2);
綁定參數:
//方式1. 用索引設置參數
Query query = session.createQuery("from Customer where cid = ?");
query.setInteger(0, cid);
//方式2. 用字段名設置參數
Query query = session.createQuery("from Customer where cid = :xxx");
query.setParameter("xxx", cid);
聚合函數&分組:
聚合函數:sum avg max min count
分組: group by
鏈接查詢:
內鏈接:
顯式內鏈接: session.createQuery(" from Customer c inner join c.orders ");
隱式內鏈接: session.createQuery(" from Customer c, Order o where c.id = o.cid ");
迫切內鏈接:session.createQuery(" from Customer c inner join fetch c.orders ");
外鏈接:
左外鏈接:session.createQuery(" from Customer c left outer join c.orders ");
左外迫切鏈接:session.createQuery(" from Customer c left outer join fetch c.orders ");
右外鏈接:session.createQuery(" from Customer c right outer join c.orders ");
右外迫切鏈接:session.createQuery(" from Customer c right outer join fetch c.orders ");
鏈接與迫切鏈接的區別:
普通外鏈接,是把結果封裝到不一樣的對象中,最終獲得了一個Object[]的list對象
右外迫切鏈接,自動把一對多中多的對象封裝到一的一方,最終獲得了一的一方的對象的list集合。
5.Criteria查詢(瞭解內容)
Criteria的離線查詢
// #1.獲取離線criteria對象
DetachedCriteria dCriteria = DetachedCriteria.forClass(Customer.class);
//#2.拼裝參數
dCriteria.add(Restrictions.ge("id", 5));
//#3.獲取能夠執行的criteria
Criteria criteria = dCriteria.getExecutableCriteria(session);
List<Customer> list = criteria.list();
Criteria的普通查詢:session.createCriteria(Customer.class).list();
Criteria的條件查詢:
criteria.add(Restrictions.xxx(字段名, 值));
// 模糊查詢 like;
/*Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.like("cname", "t%"));
List<Customer> list = criteria.list();*/
// 條件並列查詢
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.like("cname", "t%"));
criteria.add(Restrictions.ge("age", 35));
List<Customer> list = criteria.list();
Criteria的分頁查詢:
Criteria criteria = session.createCriteria(Order.class);
criteria.setFirstResult(10); //設置索引值
criteria.setMaxResults(10); //設置每頁顯示的最大數量
Criteria的排序:
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder(org.hibernate.criterion.Order.asc("age")); //升序
criteria.addOrder(org.hibernate.criterion.Order.desc("age")); //降序
List<Customer> list = criteria.list();