Maven,Hibernate有關(guān)內(nèi)容

Maven,主要是一個jar包管理倉庫和項目構(gòu)建严嗜,了解了常用框架*

  • 前端:jquery easyui bootstrap amazeui
  • java后臺:struts1 struts2 springmvc(流程控制框架)领舰;hibernate mybatis springdata(持久層框架);spring ( 一站式框架)
  • 技術(shù)選型: spring+springmvc +hibernate;spring+springmvc +mybatis;spring+struts2+hibernate
  • 權(quán)限管理:shrio springsecurity
  • 數(shù)據(jù)存儲:redis mongodb

1、 maven安裝

①檢查JAVA_HOME環(huán)境變量
C:\Windows\System32>echo %JAVA_HOME%
D:\DevInstall\jdk1.7.0_07

②解壓Maven的核心程序
將apache-maven-3.2.2-bin.zip解壓到一個非中文無空格的目錄

③配置環(huán)境變量
M2_HOME D:\DevInstall\apache-maven-3.2.2
path .....;D:\DevInstall\apache-maven-3.2.2\bin

④查看Maven版本信息驗證安裝是否正確
命令行中輸入命令:mvn -v(注意:v一定不能大寫)

2锚国、約定的目錄結(jié)構(gòu)

我們可以通過Maven命令來自動生成一個按照約定目錄的項目骨架,步驟入下
命令行中輸入mvn archetype:generate
在執(zhí)行過程中停止到Choose a number or apply filter按回車鍵繼續(xù)
輸入自定義文字groupid (一般是公司域名)
輸入自定義文字artifactid (項目名稱)
輸入自定義文字version (項目版本)
輸入自定義文字package (創(chuàng)建項目默認的包名)
確認之后輸入Y開始創(chuàng)建玄坦。

執(zhí)行完畢之后在本地文件夾 c/user/ artifactid  下中便創(chuàng)建了按照約定目錄的maven項目

3血筑、jar包坐標定位

①用http://mvnrepository.com/直接搜索,復制里面的定位文件放到pom.xml里dependencies下

version:當前模塊的版本       3.2.3 beta
 beta(公測)
SNAPSHOT 快照 ,內(nèi)側(cè)版本
release  發(fā)布版本

Hibernate

1煎楣、Hibernate是一款工作在持久化層的大型豺总、開源、免費的ORM框架择懂。

①將對數(shù)據(jù)庫的操作轉(zhuǎn)換為對象Java對象的操作喻喳,從而簡化開發(fā)。通過修改一個“持久化”對象的屬性從而修改數(shù)據(jù)庫表中對應(yīng)的記錄數(shù)據(jù)困曙。通過操作對象達到數(shù)據(jù)庫的目的表伦。

②提供線程和進程兩個級別的緩存提升應(yīng)用程序性能。
緩存:查詢出來數(shù)據(jù)之后在緩存中進行保存慷丽,下次查詢相同數(shù)據(jù)直接從緩存中讀取蹦哼,減少數(shù)據(jù)庫操作

③有豐富的映射方式將Java對象之間的關(guān)系轉(zhuǎn)換為數(shù)據(jù)庫表之間的關(guān)系。

④屏蔽不同數(shù)據(jù)庫實現(xiàn)之間的差異盈魁。在Hibernate中只需要通過“方言”的形式指定當前使用的數(shù)據(jù)庫翔怎,就可以根據(jù)底層數(shù)據(jù)庫的實際情況生成適合的SQL語句窃诉。
例如:
MySQL分頁:LIMIT
Oracle分頁:ROWNUM

2杨耙、對象關(guān)系映射

①概念:Object/Relationship Mapping,對象關(guān)系映射

②對象:Java程序中用于封裝業(yè)務(wù)數(shù)據(jù)的對象飘痛。通常稱為實體類(Entity)珊膜,以JavaBean(POJO)技術(shù)實現(xiàn)。例如:Book 宣脉、User车柠、Person等等這樣的類的對象。

③關(guān)系:關(guān)系型數(shù)據(jù)庫塑猖,目前主流的數(shù)據(jù)庫都是關(guān)系型的竹祷。

④映射:建立從“對象”到“關(guān)系型數(shù)據(jù)庫”之間的對應(yīng)關(guān)系。
簡單的說:
使用一個pojo類表示一張表的結(jié)構(gòu),這個動作就是映射羊苟。

3塑陵、Hibernate搭建環(huán)境

①導入Hibernate需要的JAR包

②導入數(shù)據(jù)庫驅(qū)動

③創(chuàng)建Hibernate自身的配置文件:hibernate.cfg.xml

④創(chuàng)建持久化類PO Persistence Object (POJO類,實體類蜡励,數(shù)據(jù)模型類)

⑤創(chuàng)建持久化類對應(yīng)的關(guān)系映射文件:Student.hbm.xml文件

⑥在hibernate.cfg.xml文件中聲明映射文件的位置(在3中完成)

<?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/1702shop</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">123</property>
        <!-- 配置連接數(shù)據(jù)庫所需要的常量 這些常量提供給hibernate連接數(shù)據(jù)庫使用
        show_sql 我們是操作對象令花,看不到sql語句阻桅,我們可以通過設(shè)置show_sql,
        hibernate運行操作數(shù)據(jù)庫會把執(zhí)行需要的sql語句輸出到控制臺中 --><property name="show_sql">true</property>
<!--自動創(chuàng)建|更新|驗證數(shù)據(jù)庫表結(jié)構(gòu),自動建立起表的結(jié)構(gòu),model類自動更新表結(jié)構(gòu)-->
<property name="hibernate.hbm2ddl.auto" value=”update" />
            </session-factory>
</hibernate-configuration>

創(chuàng)建持久化類

參照表結(jié)構(gòu)創(chuàng)建對應(yīng)的pojo對象

表-> 類

字段->屬性

字段sql類型->屬性java類型

要求類需要有oid屬性兼都,相當于一個表需要有主鍵一樣

Person.hbm.xml實體類配置文件

[1]創(chuàng)建位置:和持久化類在同一個包下

[2]創(chuàng)建名稱:pojo類名.hbm.xml
用于聲明類與表嫂沉,屬性與字段之間關(guān)系的配置文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-6-7 12:16:56 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <!-- name實體類的包名+類名, table 就是表名 -->
    <class name="com.qianfeng.Users" table="USERS">

        <!-- 屬性名設(shè)置為id扮碧,hibernate默認會把它當做主鍵 -->
        <!-- name代表類的屬性名 ,type是屬性的類型 -->
        <id name="id" type="int">
        <generator class="native" />
        </id>
        <!-- property表示普通字段 -->
        <property name="username" type="java.lang.String">
            <column name="USERNAME" />
        </property>
        <property name="age" type="int">
            <column name="AGE" />
        </property>
        
    </class>
</hibernate-mapping>

hibernate.cfg.xml中聲明hbm.xml文件的位置

  • 在hibernate配置文件中除了設(shè)置鏈接數(shù)據(jù)庫相關(guān)信息之外趟章,還需要添加關(guān)聯(lián)到hbm.xml文件。一般來說每一個想要通過hibernate操作的表都會有對應(yīng)類慎王,那么每一個都有對應(yīng)的hbm.xml文件尤揣,hiernate.cfg.xml也就有對應(yīng)每一個的映射聲明。
    <mapping resource="com/atguigu/bean/Student.hbm.xml" />

hibernate中session和JDBC區(qū)別

代表Hibernate應(yīng)用程序和數(shù)據(jù)庫之間的一次會話柬祠,作用相當于JDBC中的Connection北戏。其中封裝了操作一系列方法操作數(shù)據(jù)庫并包含緩存功能

96vAG6.png

96veMD.png

SessionFactory

用于創(chuàng)建Session對象的工廠類。
特點:

1SessionFactory對象一旦構(gòu)造完畢漫蛔,即被賦予特定的配置信息嗜愈。

2構(gòu)造SessionFactory很消耗資源,一般情況下一個應(yīng)用中只初始化一個 SessionFactory對象莽龟。

3Hibernate4新增了一個ServiceRegistry 接口蠕嫁,所有基于Hibernate的配置或者服務(wù)都必須統(tǒng)一向這個ServiceRegistry注冊后才能生效。

創(chuàng)建SessionFactory對象的步驟
[1]創(chuàng)建封裝配置信息的Configuration對象毯盈。
[2]在ServiceRegistry對象中注冊配置信息剃毒。
[3]通過Configuration對象構(gòu)建SessionFactory對象。

  • 主要代碼
①測試目標:使用Hibernate實現(xiàn)將Student對象保存到數(shù)據(jù)庫中搂赋。
②實現(xiàn)步驟
[1]創(chuàng)建SessionFactory對象
Configuration configuration = new Configuration().configure();
ServiceRegistryBuilder builder = new ServiceRegistryBuilder();
 builder.applySettings(configuration.getProperties());
 ServiceRegistry serviceRegistry = builder.buildServiceRegistry();
SessionFactory factory = configuration.buildSessionFactory(serviceRegistry);
 
[2]通過SessionFactory對象創(chuàng)建Session對象赘阀,也就是開啟和數(shù)據(jù)庫之間的一次會話
Session session = factory.openSession();
 [3]開啟事務(wù)
Transaction transaction = session.beginTransaction();
 [4]執(zhí)行操作
Student student = new Student(null, "Tom2015", 20, new Date());
session.save(student);
 [5]提交事務(wù)
transaction.commit();
 [6]關(guān)閉Session
session.close();
 [7]關(guān)閉SessionFactory
factory.close();
  • 4.x版本與5.x版本
Hibernate各個版本對sessionFactory對象的初始化代碼并不一樣,以上代碼是依照4.0的版本脑奠。
以下是5.x對sessionFactyory對象的初始化方式基公,其他使用基本一樣

//但在5.1.0版本匯總,hibernate則采用如下新方式獲人纹邸: 
//1. 配置類型安全的準服務(wù)注冊類轰豆,這是當前應(yīng)用的單例對象,不作修改齿诞,所以聲明
為final //在configure(“cfg/hibernate.cfg.xml”)方法中酸休,如果不指定資源路徑,
默認在類路徑下尋找名為hibernate.cfg.xml的文件 
 StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("cfg/hibernate.cfg.xml").build(); 
//2. 根據(jù)服務(wù)注冊類創(chuàng)建一個元數(shù)據(jù)資源集祷杈,同時構(gòu)建元數(shù)據(jù)并生成應(yīng)用一般唯一的的session工廠 
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();

數(shù)據(jù)庫表生成策略

①概述
Hibernate在創(chuàng)建SessionFactory對象時斑司,會根據(jù)*.hbm.xml映射文件中的信息自動生成對應(yīng)的數(shù)據(jù)庫表,而在生成數(shù)據(jù)庫表的過程中吠式,可以根據(jù)不同的配置信息采取不同的生成策略陡厘。

②配置方式
在hibernate.cfg.xml配置文件中加入如下配置
<property name="hbm2ddl.auto">update</property>

③可以選擇的生成策略

  • [1]create:根據(jù)*.hbm.xml文件生成新的數(shù)據(jù)庫表抽米,而且是每一次運行都刪除舊表創(chuàng)建新的表,即使兩次操作的過程中數(shù)據(jù)庫表沒有任何改變
  • [2]update:按照如下幾種情況生成數(shù)據(jù)庫表
    <1>數(shù)據(jù)庫表不存在:生成新的數(shù)據(jù)庫表
    <2>數(shù)據(jù)庫表存在且表結(jié)構(gòu)不需要改變:保留原來的數(shù)據(jù)庫表
    <3>數(shù)據(jù)庫表存在但表結(jié)構(gòu)有變化:在原來數(shù)據(jù)庫表的基礎(chǔ)上更新數(shù)據(jù)庫表糙置,不會刪除原有的行和列
  • [3]create-drop:每一次運行都生成新的數(shù)據(jù)庫表云茸,并在執(zhí)行操作后將表刪除
    [4]validate:會和數(shù)據(jù)庫中的表進行比較,若*.hbm.xml文件中的列在數(shù)據(jù)表中不存在谤饭,則拋出異常

Session與緩存

  Session接口是Hibernate向應(yīng)用程序提供的操縱數(shù)據(jù)庫的最主要的接口标捺,它提供了基本的保存、
  更新揉抵、刪除和加載Java對象的方法亡容。 
  每一個Session對象都在內(nèi)存中維護了一個緩存,我們叫他一級緩存冤今。 
  兩次調(diào)用session.get(Student.class,1);方法闺兢,僅發(fā)送1條SQL語句。原因是第一次
  使用get()方法加載的Student被緩存到了內(nèi)存中戏罢,第二次調(diào)用get()方法直接使用了
  內(nèi)存中緩存的Student對象屋谭,從而減少了訪問數(shù)據(jù)庫的次數(shù)。

持久化對象狀態(tài)

一般我們認為有三種但也有說四種的

狀態(tài)表對應(yīng)的狀態(tài)

  • 臨時狀態(tài)
    由java的new命令開辟內(nèi)存空間的java對象也就是普通的java對象龟糕,如果沒有變量引用它它將會被JVM收回桐磁。臨時對象在內(nèi)存中是孤立存在的,它的意義是攜帶信息載體讲岁,不和數(shù)據(jù)庫中的數(shù)據(jù)由任何的關(guān)聯(lián)我擂。通過Session的save()方法和saveOrUpdate()方法可以把一個臨時對象和數(shù)據(jù)庫相關(guān)聯(lián),并把臨時對象攜帶的信息通過配置文件所做的映射插入數(shù)據(jù)庫中缓艳,這個臨時對象就成為持久化對象校摩。
  • 持久化狀態(tài):
    持久化對象在數(shù)據(jù)庫中有相應(yīng)的記錄,持久化對象可以是剛被保存的郎任,或者剛被加載的秧耗,但都是在相關(guān)聯(lián)的session聲明周期中保存這個狀態(tài)备籽。如果是直接數(shù)據(jù)庫查詢所返回的數(shù)據(jù)對象舶治,則這些對象和數(shù)據(jù)庫中的字段相關(guān)聯(lián),具有相同的id车猬,它們馬上變成持久化對象霉猛。如果一個臨時對象被持久化對象引用,也立馬變?yōu)槌志没瘜ο蟆?/li>
  • 游離狀態(tài)
    Session關(guān)閉之后珠闰,與此Session關(guān)聯(lián)的持久化對象就變成為脫管對象惜浅,可以繼續(xù)對這個對象進行修改,如果脫管對象被重新關(guān)聯(lián)到某個新的Session上伏嗜,會在此轉(zhuǎn)成持久對象坛悉。

4.hibernate中的表關(guān)系

  • 一對多
  • 一對一
user  id name age tel mobile chanzhen adress city country 
數(shù)據(jù)庫中有一個表為user伐厌。需要保存用戶信息,包括id挣轨,名稱,性別轩猩,座機卷扮,手機,傳真等均践。其中座機晤锹,手機,傳真我們可以單獨提取出來一張聯(lián)系方式表彤委。
故當涉及到一個具體實體的信息量較多鞭铆,或者可以分類的時候,就可以使用了1-1焦影,當然只要你能把一個實體的關(guān)系拆分成幾個有歸類的部分也可以適用衔彻。
如果都放在一張表里,一:不便于管理(包括查詢執(zhí)行速度)偷办,二:也就達不到關(guān)系型數(shù)據(jù)庫的原子性特性艰额。


1對1需要主鍵和外鍵
比如:
經(jīng)理與部門的關(guān)系實現(xiàn)。
經(jīng)理表manager
部門department表
如果想要確定一個部門的經(jīng)理是誰椒涯,我們可以在經(jīng)理表中添加外鍵指向部門表的主鍵來實現(xiàn)柄沮。

實現(xiàn)方式:
Department表的主鍵作為外鍵關(guān)聯(lián)到Manager表。意思是department表的主鍵不是像之前我們常用的自增废岂,因為是1對1所以Department的主鍵又充當外鍵關(guān)聯(lián)manager

2映射文件1
department
 <class name ="Department" table="DEPARTMENTS">
        <id name ="deptId" type="java.lang.Integer">
            <column name ="DEPT_ID" />
            <!-- 設(shè)置當前表的主鍵列依賴另外一張表的主鍵實現(xiàn) -->
            <generator class ="foreign">
                 <param name ="property">manager</ param>
            </generator >
        </id >
        <property name ="deptName" type="java.lang.String">
            <column name ="DEPT_NAME" />
        </property >
        <!-- 使用constrained屬性給生成的主鍵列加上外鍵約束 -->
        <one-to-one name ="manager" class="Manager" constrained= "true" />
    </class > 

2映射文件

manager
 <class name ="Manager" table="MANAGERS">
        <id name ="mngId" type="java.lang.Integer">
            <column name ="MNG_ID" />
            <generator class ="native" />
        </id >
        <property name ="mngName" type="java.lang.String">
            <column name ="MNG_NAME" />
        </property >
        <one-to-one name ="department" class="Department" />
    </class > 
  • 多對一
    n對1
    1對n
    雙向1對n

首先什么是多對一祖搓,多對一的場景

  • 現(xiàn)有兩張表,users和score湖苞。Users表保存所有學生信息拯欧,score表保存所有學生所有課程的成績。那么現(xiàn)在users表和score表就構(gòu)成了一對多的關(guān)系财骨。因為一個學生可以考試多門成績镐作,也就是說在users表中的一條記錄表示的學生在score表中有多條對應(yīng)的考試成績記錄。
    一個學生可以有多個成績隆箩,故:
    Users (一) ----》score(多)一對多關(guān)系
    思考還有其他場景也符合多對一關(guān)系该贾?
實現(xiàn):
1分別創(chuàng)建持久化類

2創(chuàng)建對應(yīng)的*.hbm.xml映射文件

3添加映射關(guān)系配置信息(額外的表示關(guān)系的配置)

單向多對一:
創(chuàng)建持久化類:
①one:Customer
封裝自身必要的信息即可,不包含Order集合的引用
②many:Order
除了要封裝自身相關(guān)的信息捌臊,還要包含Customer對象的引用杨蛋,屬性中無需出現(xiàn)外鍵字段

創(chuàng)建*.hbm.xml映射文件
one:Customer.hbm.xml
簡單的單表映射(xml內(nèi)容略)

many:Order.hbm.xml
[1]映射OID和自身信息
[2]映射many-to-one關(guān)聯(lián)關(guān)系
屬性說明:
Name: Order類中Customer屬性名。
Class:Customer類的類名(完整的是包名+類名)
Column:order表中外鍵的字段名

多對多

  • 場景舉例:
    學生和選修課程,一個學生可以選修多門課程逞力,一個課程也可以擁有多個學生曙寡。
    電影和演員,一個演員可以參演多個電影寇荧,一部電影有很多演員卵皂。
    用戶和權(quán)限組,一個用戶可以有都個權(quán)限砚亭,擁有一個權(quán)限的有很多用戶灯变。

5.hibernate中三種檢索方式

  • hql

在SQL中,F(xiàn)ROM子句是用于指定要查詢的數(shù)據(jù)庫表捅膘,在HQL中添祸,替換為與數(shù)據(jù)庫表對應(yīng)的Java實體類即可

例如: SQL SELECT * FROM EMPS HQL FROM Employee

和SQL的語法一樣,HQL中的WHERE子句也用來指定查詢條件寻仗。只不過這里指定查詢條件使用的不是數(shù)據(jù)庫表的字段刃泌,而是Java類的屬性。
SQL
SELECT * FROM EMPS WHERE EMPS.SALARY>5000
HQL 
FROM Employee   e WHERE e.salary>5000

將上例中的具體值使用占位符“?”代替署尤,并調(diào)用Query對象的setXxx()方法按照參數(shù)的不同類型動態(tài)填充即可耙替,需要注意的是和JDBC中的PreparedStatement接口不同,這里占位符的索引從0開始曹体。
HQL
FROM Employee e WHERE e.salary>?
 
填充占位符
query.setDouble(0, 8000.00);
  • 在HQL中不但能夠使用基于位置的占位符參數(shù)俗扇,還能夠使用基于名稱的具名參數(shù),使用具名參數(shù)的好處是不必關(guān)心當前參數(shù)的索引值箕别。
    具名參數(shù)的格式是:“:參數(shù)名稱”铜幽。

例如: HQL FROM Employee e WHERE e.salary>:salaryParam

使用ORDER BY子句可以進行排序

HQL FROM Employee e WHERE e.salary>:salaryParam ORDER BY e.salary DESC

和SQL一樣,默認按照升序排列串稀。DESC表示降序除抛,ASC表示升序。

分頁查詢是HQL的一大亮點母截,不必關(guān)心底層數(shù)據(jù)庫的具體實現(xiàn)是什么到忽,使用HQL調(diào)用固定的方法就能夠?qū)崿F(xiàn)垮數(shù)據(jù)庫平臺的分頁查詢。(mysql和orcal實現(xiàn)分頁關(guān)鍵詞不同)
在分頁時我們需要指定兩個最基本的數(shù)據(jù)清寇,一個是當前頁的頁碼:pageNo喘漏,一個是每頁顯示多少條數(shù)據(jù):pageSize。

下面列出了Query接口中與分頁相關(guān)的兩個函數(shù)
setFirstResult(int index)相當于offset
指定查詢結(jié)果從index位置開始取颗管,index從0開始
setMaxResults(int maxResults)  相當于limit
指定查詢結(jié)果取maxResults條數(shù)據(jù)

 index和pageNo的關(guān)系是:index=(pageNo-1)*pageSize(pageNo:當前頁的頁碼; pageSize:每頁顯示數(shù)據(jù)的數(shù)量)

所謂投影查詢其實就是僅查詢實體類對象的部分字段陷遮,這里用到了HQL語句的SELECT關(guān)鍵詞。
SELECT e.empName,e.salary From Employee e WHERE e.salary>9000 
那么此時的查詢結(jié)果以什么形式返回呢垦江?
HQL并沒有將使用空的Employee對象接收empName和salary的值,而是把它們放在了一個Object數(shù)組中。
   Query query = session.createQuery(queryString);
          List<Object[]> list = query.list();
          for (Object[] objects : list) {
              System. out.println(objects[0]+" "+objects[1]);
          } 

接收投影查詢結(jié)果可以仍然使用實體類的對象比吭,但要求實體類中提供對應(yīng)的構(gòu)造器绽族。

HQL

SELECT new Employee(e.empName,e.salary) From Employee e 這樣得到的每一條數(shù)據(jù)都將被封裝到Employee對象中。

HQL:

select s.id,s.name,sc.score from Student as s,Score as sc where s.id = sc.user.userId;

上面字段都是 javabean的屬性衩藤,其他與sql語句類似吧慢。

返回類型List<object[]>數(shù)組

from a,b where a.id=b.a_id
from a inner jion b on a.id=b.a_id
form a  left outer jion b on a.id=b.a_id
全連接
full jion ,但是mysql不支持這種寫法,可以使用union來吧左外和右外的結(jié)果拼接成一個結(jié)果集赏表,union會去除重復數(shù)據(jù)检诗。這樣就得到了一個全連接結(jié)果,也就是包含左表和右表全部數(shù)據(jù)瓢剿。
union all也是拼接結(jié)果集逢慌,但是不進行去重

和SQL一樣,HQL也使用GROUP BY和HAVING子句配合起來進行分組间狂,再結(jié)合統(tǒng)計函數(shù)進行報表查詢攻泼。

SELECT min(e.salary),max(e.salary) 
From Employee e 
GROUP BY e.department 
HAVING min(e.salary)>3000
(每)
min()和max()統(tǒng)計函數(shù)的結(jié)果最終被放在了一個Object數(shù)組中。
  • 子查詢是SQL語句中非常重要的功能鉴象,它可以在SQL語句中利用另外一條SQL語句的查詢結(jié)果忙菠。HQL同樣對子查詢功能提供了支持。與SQL子查詢不同的是纺弊,HQL不支持在FROM子句中使用子查詢牛欢。
查詢部門名以“A”開頭的部門的員工姓名
select e.empName,e.department 
from Employee e 
where e.department in 
     (From Department d where d.deptName like 'A%')

刪除數(shù)據(jù)
HQL
Delete From Employee e WHERE e.empId=117
 
session.createQuery(queryString).executeUpdate()
 
更新數(shù)據(jù)
HQL
UPDATE Employee e Set e.empName=’Tom’ WHERE e.empId=115
 
session.createQuery(queryString).executeUpdate()
  • 原生sql

有些情況下我們需要直接執(zhí)行原始的SQL語句,這時可以使用session對象創(chuàng)建SQLQuery對象淆游,并調(diào)用list()或uniqueResult()方法返回查詢結(jié)果氢惋,如果是執(zhí)行增刪改操作,可以調(diào)用executeUpdate()方法稽犁。

List cats= sess.createSQLQuery(" select * from cats " ).addEntity(Cat. class).list();

addEntity()方法將SQL表的別名和實體類聯(lián)系起來焰望,并且確定查詢結(jié)果集的形態(tài)。
  • qbc

QBC查詢就是通過使用Hibernate提供的Query By Criteria API來查詢對象已亥,這種API 封裝了SQL語句的動態(tài)拼裝熊赖,對查詢提供了更加面向?qū)ο蟮墓δ芙涌凇?/p>

  • 1創(chuàng)建Criteria對象
Criteria criteria = session.createCriteria(Employee.class);
創(chuàng)建Criteria對象,類似于HQL查詢中創(chuàng)建Query對象虑椎,只不過Criteria對象和Query對象的用法差別很大震鹉。
Criteria對象可以通過session對象的createCriteria()方法創(chuàng)建,創(chuàng)建時需要提供目標持久化類的Class類對象(即目標持久化類)捆姜。
  • 取得查詢結(jié)果
Criteria criteria = session.createCriteria(Employee.class);
List<Employee> list = criteria.list();
Criteria對象大體上有兩種方式獲取查詢結(jié)果:list()方法和uniqueResult()方法传趾。list()方法獲取多條記錄的查詢結(jié)果,uniqueResult()方法獲取單一記錄的查詢結(jié)果泥技。
這個例子表示不帶任何查詢條件浆兰,查詢?nèi)縀mployee對象,并返回全部Employee對象組成的List集合。
  • QBC查詢最大的特點是可以將SQL語句中的查詢條件以面向?qū)ο蟮姆绞椒庋b起來簸呈,并根據(jù)封裝好的查詢條件返回結(jié)果榕订。

封裝查詢條件要用到Restrictions類的各個靜態(tài)方法
封裝查詢條件之后,上述靜態(tài)方法都會返回一個Criterion接口的實例蜕便,拿到這個Criter
ion對象后可以將其添加到Criteria對象中劫恒。

例如:
Criterion like = Restrictions.like("empName","%a%");
Criterion gt = Restrictions.gt("salary",9000.00);
List<Employee> list = criteria
                         .add(like)
                         .add(gt)
                         .list();

其中add()方法也支持連綴調(diào)用。

  • 在QBC API中使用Conjunction類表示AND轿腺,使用Disjunction表示OR两嘴,它們都可以連接Criterion對象生成AND或OR語句。
Criterion like = Restrictions. like(“empName”, “%a%”);
Criterion gt = Restrictions. gt(“salary”, 9000.00);
//創(chuàng)建AND條件對象
Conjunction conjunction = Restrictions.conjunction();
//使用AND連接like和 gt
conjunction.add(like).add(gt);
List<Employee> list = session.createCriteria(Employee.class)
                                            .add(conjunction)
                                            .list();

甚至AND和OR作為整體也可以連接在一起

Conjunction conjunction01 = Restrictions.conjunction();
Conjunction conjunction02 = Restrictions.conjunction();
Disjunction disjunction = Restrictions.disjunction();
//(   and  )  or  (  and  )
disjunction.add(conjunction01).add(conjunction02);
  • 在QBC查詢中可以使用Projections類的靜態(tài)方法封裝SQL中的統(tǒng)計函數(shù)
AggregateProjection max = Projections.max("salary");
criteria.setProjection(max);

如果有多個統(tǒng)計函數(shù)需要執(zhí)行族壳,則創(chuàng)建ProjectionList對象憔辫,用于包含多個Projection對象

AggregateProjection max = Projections.max("salary");
AggregateProjection min = Projections.min("salary");
ProjectionList projectionList = Projections.projectionList();
projectionList.add(max).add(min);
List<Object[]> list = session.createCriteria(Employee.class)
                   .setProjection(projectionList)
                   .list();

可以使用groupProperty(String propertyName)方法對查詢結(jié)果進行分組

Criteria criteria = session.createCriteria(Employee.class);
 
PropertyProjection groupProperty = Projections.groupProperty("department");
 
criteria.setProjection(groupProperty).list();

Order asc = Order.asc("salary");
Order desc = Order.desc("empName");
List<Employee> list = session.createCriteria(Employee.class)
                                     .addOrder(asc)
                                     .addOrder(desc)
                                     .list();

QBC分頁和HQL分頁的操作大體上是一致的

int pageNo = 2;
int pageSize = 5;
        
List<Employee> list = session.createCriteria(Employee.class)
    .setFirstResult((pageNo - 1)*pageSize)
    .setMaxResults(pageSize)
    .list();

6.檢索策略

  • 立即檢索策略

采用立即檢索策略,會將被檢索的對象决侈,以及和這個對象關(guān)聯(lián)的一對多對象都加載到緩存中螺垢。Session的get方法就使用的立即檢索策略。

  • 優(yōu)缺點
優(yōu)點:頻繁使用的關(guān)聯(lián)對象能夠被加載到緩存中赖歌。
缺點:1枉圃、占用內(nèi)存。2庐冯、Select語句過多孽亲。
  • 延遲檢索策略
  • 在類級別操作時, 延遲檢索策略展父,只加載類的OID不加載類的其他屬性返劲,只用當?shù)谝淮卧L問其他屬性時,才回訪問數(shù)據(jù)庫去加載內(nèi)容栖茉。(Load方法與get方法的區(qū)別)

  • 在關(guān)聯(lián)級別操作時篮绿,延遲檢索策略,只加載類本身吕漂,不加載關(guān)聯(lián)類亲配,直到第一次調(diào)用關(guān)聯(lián)對象時,才去加載關(guān)聯(lián)對象(默認)
  • 優(yōu)缺點
優(yōu)點:由程序決定加載哪些類和內(nèi)容惶凝,避免了大量無用的sql語句和內(nèi)存消耗吼虎。
缺點:在Session關(guān)閉后,就不能訪問關(guān)聯(lián)類對象了苍鲜。 需要確保在Session.close方法前思灰,調(diào)用關(guān)聯(lián)對象。
  • 有關(guān)延時和禁止延時的配置
1.若lazy存在class標記中使用lazy那么可選值是true/false,分別是使用延遲和禁止使用

2.lazy還可以出現(xiàn)雜set標簽中混滔,那么可選值是三個true/false/extra
true:
默認取值洒疚,它的意思是只有在調(diào)用這個集合獲取里面的元素對象時歹颓,才發(fā)出查詢語句,加載其 
     集合元素的數(shù)據(jù) 
false:
取消懶加載特性拳亿,即在加載對象的同時晴股,就發(fā)出第二條查詢語句加載其關(guān)聯(lián)集合的數(shù)據(jù) 
extra:
一種比較聰明的懶加載策略愿伴,即調(diào)用集合的size/contains等方法的時候肺魁,hibernate并不會去加載整個集合的數(shù)據(jù),而是發(fā)出一條聰明的SQL語句隔节,以便獲得需要的值鹅经,只有在真正需要用到這些集合元素對象數(shù)據(jù)的時候,才去發(fā)出查詢語句加載所有對象的數(shù)據(jù)

3.lazy還可以存在于many-to-one標記中可選值有false/proxy/no-proxy怎诫。
默認值是proxy表示延遲加載瘾晃,false表示不延遲加載。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末幻妓,一起剝皮案震驚了整個濱河市蹦误,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌肉津,老刑警劉巖强胰,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異妹沙,居然都是意外死亡偶洋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門距糖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玄窝,“玉大人,你說我怎么就攤上這事悍引《髦” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵趣斤,是天一觀的道長俩块。 經(jīng)常有香客問我,道長唬渗,這世上最難降的妖魔是什么典阵? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮镊逝,結(jié)果婚禮上壮啊,老公的妹妹穿的比我還像新娘。我一直安慰自己撑蒜,他們只是感情好歹啼,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布玄渗。 她就那樣靜靜地躺著,像睡著了一般狸眼。 火紅的嫁衣襯著肌膚如雪藤树。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天拓萌,我揣著相機與錄音岁钓,去河邊找鬼。 笑死微王,一個胖子當著我的面吹牛屡限,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炕倘,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼钧大,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罩旋?” 一聲冷哼從身側(cè)響起啊央,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涨醋,沒想到半個月后园匹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體澎办,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了怕敬。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔚鸥。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡斗埂,死狀恐怖塞琼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情愧膀,我是刑警寧澤拦键,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站檩淋,受9級特大地震影響芬为,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蟀悦,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一媚朦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧日戈,春花似錦询张、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唯袄。三九已至,卻和暖如春蜗帜,著一層夾襖步出監(jiān)牢的瞬間恋拷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工厅缺, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蔬顾,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓店归,卻偏偏與公主長得像阎抒,于是被迫代替她去往敵國和親酪我。 傳聞我的和親對象是個殘疾皇子消痛,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Hibernate: 一個持久化框架 一個ORM框架 加載:根據(jù)特定的OID,把一個對象從數(shù)據(jù)庫加載到內(nèi)存中OID...
    JHMichael閱讀 1,973評論 0 27
  • 本文中我們介紹并比較兩種最流行的開源持久框架:iBATIS和Hibernate秩伞,我們還會討論到Java Persi...
    大同若魚閱讀 4,312評論 4 27
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法欺矫,內(nèi)部類的語法纱新,繼承相關(guān)的語法,異常的語法穆趴,線程的語...
    子非魚_t_閱讀 31,644評論 18 399
  • 第二堂課是在周六去的脸爱,正月十五的下午,老師專門來館里給我上課未妹。也許是因為和家人和有了爭執(zhí)鬧情緒簿废,也許是換了個大教室...
    Tina_Sun閱讀 151評論 0 0
  • 二十二年了,媽媽络它,我想你族檬。
    伊石榴閱讀 168評論 1 1