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ù)庫并包含緩存功能
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)
由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表示不延遲加載。