SSH入門筆記
一、Oracle數據庫基礎
Oracle數據庫的主要特點如下:
(1)支持多用戶、大事務量的事務處理。
(2)在保持數據安全性和完整性方面性能優越。
(3)支持分布式數據處理。將分布在不同物理位置的數據庫用通信網絡連接起來,在分布式數據庫管理系統的控制下,組成一個邏輯上統一的數據庫,完成數據處理任務。
(4)具有可移植性。Oracle可以在Windows、Linux等多個操作系統平臺上使用,而SQL Server只能在Windows平臺上運行。
Oracle數據庫的結構
1>邏輯結構
數據庫-->表空間-->數據段-->數據區間-->數據塊
2>物理結構
數據文件(dbf):存儲數據的
日誌文件(log):記錄數據庫操作的日誌信息
控制文件(ctl):記錄物理文件的信息(位置,大小,創建時間)
Oracle數據類型
字符數據類型
1.CHAR數據類型
當需要固定長度的字符串時,使用CHAR數據類型。
2.VARCHAR2數據類型
VARCHAR2數據類型支持可變長度的字符串。
3.NCHAR數據類型
NCHAR,即國家字符集,使用方法和CHAR相同。如果開發的項目需要國際化,那麽數據類型選擇NCHAR數據類型。
數值數據類型
NUMBER數據類型可以存儲正數、負數、零、定點數和精度為38位的浮點數。
日期時間數據類型
1.DATA數據類型
DATA數據類型用於存儲表中的日期和時間數據。
2.TIMESTAMP數據類型
TIMESTAMP數據類型用於存儲日期的年、月、日,以及時間的小時、分和秒,其中秒值精確到小數點後6位,該數據類型同時包含時區信息。
LOB數據類型
1.CLOB
能夠存儲大量字符數據
2.BLOB
可以存儲較大的二進制對象
3.BFILE
能夠將二進制文件存儲在數據庫外部的操作系統文件中
4.NCLOB
用於存儲大的NCHAR字符數據
Oracle中的表可以有多個LOB列,每個LOB列可以是不同的LOB類型。
Oracle中的偽列
偽列就像Oracle中的一個表列,但實際上它並未存儲在表中。偽列可以從表中查詢,但是 不能插入、更新或刪除他們的值。
1.ROWID
數據庫中的每行都有一個行地址,ROWID偽列返回該行地址。可以使用ROWID值來定位表中的一行。通常情況下,ROWID值可以唯一的標識數據庫中的一行。
ROWID偽列有以下重要的用途:
能以最快的方式訪問表中的一行。
能顯示表的行是如何存儲的。
可以作為表中行的唯一標識。
2.ROWNUM
對於一個查詢返回的每行,ROWNUM偽列返回一個數值代表行的次序。
SQL語言簡介
數據庫定義語言(DDL):CREATE(創建)、ALTER(更改)、TRUNCATE(截斷)、DROP(刪除)
數據操縱語言(DML):INSERT(插入)、SELECT(選擇)、DELETE(刪除)、UPDATE(更新)
事務控制語言(TCL):COMMIT(提交)、SAVEPOINT(保存點)、ROLLBACK(回滾)
數據控制語言(DCL):GRANT(授予)、REVOKE(回收)
SQL操作符
1.算術操作符
查詢語句中要執行基於數值的計算。算數操作符包括:+(加)、-(減)、*(乘)、/(除)。
2.比較操作符
用於比較兩個表達式的值。比較操作符包括:=、!=、<、>、<=、>=、BETWEEN、AND(檢查是否在兩個值之間)、IN(與列表中的值相匹配)、LIKE(匹配字符模式)、IS NULL(檢查是否為空)。
3.邏輯操作符
用於組合多個比較運算的結果以生成一個或真或假的結果。邏輯運算符包括AND(與)、OR(或)、NOT(非)。
4.集合操作符
將兩個查詢的結果組合成一個結果集。
UNION操作符返回兩個查詢選定的所有不重復的行。
UNION ALL操作符合並兩個查詢選定的所有行,包括重復的行。
INTERSECT操作符只返回兩個查詢所有的行。
MINUS操作符只返回由第一個查詢選定而未被第二個查詢選定的行。
5.連接操作符
連接操作符(||)用於將兩個或多個字符串合並成一個字符串,或者將一個字符串與一個數值合並在一起 。
SQL函數分為單行函數、聚合函數和分析函數。
二、Oracle數據庫應用
1>創建用戶
create user 用戶名 identified by 密碼
[default tablespace 表空間的名稱]
分析:1>創建用戶時,用戶使用的表空間應存在,如果不存在則要先創建
表空間;
2>表空間也有內置的,也可以創建表空間
3>如果創建用戶時沒有指定表空間,那麽該用戶默認使用user表空間
eg:
javasmart/manager--->newtablespace(c:/.../javasmart.dbf)
如果用javasmart進入orcl數據庫後所存儲的數據在javasmart.dbf中
當新建一個新用戶後,當前這個新用戶還不能連接數據庫;還需要管理員授權後方可連接數據庫
grant connect to 新用戶;
當然授權後也可以撤消權限
revoke connect from 用戶
sqlplus / as sysdba
2>更改用戶的表空間及密碼
alter user 用戶名 identified by 密碼
[default tablespace 表空間的名稱]
3>刪除用戶
drop user 用戶名 [cascade]
分析:如果加上cascade表示級聯刪除;
4>用戶鎖定與解鎖
鎖定:alter user 用戶名 account lock;
解鎖:alter user 用戶名 account unlock;
5>創建表空間
create tablespace 表空間的名稱 datafile 數據文件 size 大小(M)
6>刪除表空間
drop tablespace 表空間名稱 [including datfiles and contents]
7>修改表空間
alter tablespace 表空間名稱 datafile 數據文件 size 大小(m)
8.>數據庫的刪除
universal installer
9.>新建數據庫
dbca | DataBase Configuration Assiant
表空間的可分為三類:永久性表空間、臨時性表空間、撤銷表空間。
表空間的目的:
(1)對不同用戶分配不同的表空間,對不同的模式對象分配不同的表空間,方便對用戶數據的操作,對模式對象的管理。
(2)可以將不同數據文件創建到不同磁盤中,有利於管理磁盤空間,有利於提高I/O性能,有利於備份和恢復數據等。
系統權限
系統權限是指被授權用戶是否可以連接到數據庫上及在數據庫中可以進行哪些系統操作。
系統權限是在數據庫中執行某種系統級別的操作,或者針對某一類的對象執行的某種操作的權利。
下面列舉4個常見的系統權限:
1) create session:連接到數據庫。
2) create table:創建表。
3) create view:創建視圖。
4) create sequence:創建序列。
對象權限
對象權限是指用戶對數據庫中具體對象所具有的權限。
對象權限是針對某個特定的模式對象執行操作的權利,只能針對模式對象來設置和管理對象權限。
Oracle數據庫用戶有兩種途徑獲得權限。
1.管理員直接向用戶授予權限。
2.管理員將權限授予角色,然後再將角色授予一個或多個用戶。(角色可以理解為一組權限的“集合”)
授予權限語法:
grant 權限|角色 to 角色名;
撤銷權限語法:
revoke 權限|角色 from 用戶名;
數據庫用戶安全設計原則:
1.數據庫用戶權限按照最小分配原則。
2.數據庫用戶分為管理、應用、維護、備份四類用戶。
3.不允許使用sys和system用戶創建數據庫應用對象。
4.禁止將dba權限賦予用戶。
Oracle系統預定義角色
1.connect:適用於需要連接上數據庫的用戶,特別是不需要創建表的用戶。
2.resource:適用於更為可靠和正式的數據庫用戶。可以創建表、觸發器、過程等。
3.dba:數據庫管理員角色,擁有管理數據庫的最高全向。一個具有dba角色的用戶可以撤銷任何其他用戶甚至其他dba權限,一般情況下,最好不要對用戶授予這個角色。
序列
序列是一種數據庫對象,用來自動產生一組唯一的序號。
序列是一種共享式的對象,多個用戶可以共同使用序列中的序號。
一般將序列應用於表的主鍵列,這樣當向表中插入數據時,主鍵列就使用了序列中的序號,從而保證主鍵列的值不會重復。
用這種方式可以代替在應用程序中產生主鍵值的方法,可以獲得更可靠的主鍵值。
註:在序列指定最大值和可循環屬性後,序列中的序號是可以循環使用的。
默認情況下,用戶可以在自己的模式中創建序列。如果希望在其他用戶的模式中創建序列,
則必須具有CREATE ANY SEQUENCE這個系統權限。
創建序列的命令為CREATE SEQUENCE
修改序列的命令是ALTER SEQUENCE。
用戶可以修改自己的序列,如果希望修改其他用戶的序列,則需要具有ALTER ANY SEQUENCE這個系統權限。
ALTER SEQUENCE命令的用法與CREATE SEQUENCE命令的用法基本相同,只要將關鍵字CREATE替換為ALTER即可。
刪除序列的命令是DROP SEQUENCE。
用戶可以刪除自己創建的序列,如果要刪除其他用戶的序列,則要具有DROP ANY SEQUENCE 系統權限。
序列被刪除後,它的相關信息就被從數據字典中刪除。
同義詞
同義詞是一種數據庫對象,它是為一個數據庫對象定義的別名,使用同義詞的主要目的是為了簡化SQL語句的書寫。
同義詞用途:
(1)簡化SQL語句。
(2)隱藏對象的名稱和所有者。
(3)為分布式數據庫的遠程對象提供了位置透明性。
(4)提供對對象的公共訪問。
同義詞可分為兩類:私有同義詞和公有同義詞
1.私有同義詞
私有同義詞只能被當前模式的用戶訪問,且私有同義詞名稱不可與當前模式的對象名稱相同。
2.公有同義詞
公有同義詞可被所有的數據庫用戶訪問。公有同義詞可以隱藏數據庫對象的所有者和名稱,並降低SQL語句的復雜性。
私有同義詞和公有同義詞的區別:
私有同義詞只能在當前模式下訪問,且不能與當前模式的對象同名。
公有同義詞可被所有的數據庫用戶訪問。
同義詞的創建和刪除
用戶可以在自己的模式中創建同義詞,這時需要具有CREATE SYNONYM這個系統權限。
如果希望在其他用戶的模式中創建同義詞,則需要具有CREATE ANY SYNONYM這個系統權限。
普通用戶如果希望創建公有同義詞,需要具有CREATE PUBLIC SYNONYM系統權限。
創建私有同義詞的命令是CREATE SYNONYM ,它的語法規則為:
CREATE SYNONYM 同義詞 FOR 用戶名.對象名;
創建公有同義詞的語法格式為:
CREATE SYNONYM 同義詞 FOR 用戶名.對象名;
刪除同義詞的命令是DROP SYNONYM,這條命令的語法格式為:
DROP SYNONYM 同義詞名;
註:如果要刪除公有同義詞的話,要在關鍵字SYNONYM之前加上關鍵字PUBLIC。
一個用戶可以刪除自己創建的同義詞,如果要刪除其他用戶創建的同義詞,則要具有DROP ANY SYNONYM 系統權限。
DBA 可以刪除所有的公共同義詞,普通用戶需要具有DROP PUBLIC SYNONYM系統權限,才能刪除公共同義詞。
同義詞被刪除以後,它的相關信息也將從數據字典中刪除。
索引分類
按存儲方法分類
B*樹索引:B*樹索引是最常用的索引,其存儲結構類似書的索引結構,有分支和葉兩種類型的存儲數據塊,分支塊相當於書的大目錄,葉塊相當於索引到的具體的書頁。一般索引及唯一約束索引都使用B*樹索引。
位圖索引:位置索引儲存在主要用來節省空間,減少Oracle對數據塊的訪問,它采用位圖偏移方式來與表的行ID對應,采用位圖索引一般是重復值太多的表字段。位圖索引在實際密集型OLTP(數據事務處理)中用得比較少,因為OLTP會對表進行大量的刪除、修改、新建操作,Oracle每次進行操作都會對要操作的數據塊加鎖,所以多人操作很容易產生數據塊鎖等待甚至死鎖現象。在OLAP(數據分析處理)中應用位圖有優勢,因為OLAP中大部分是對數據庫的查詢操作,而且一般采用數據倉庫技術,所以大量數據采用位圖索引節省空間比較明顯。
按功能分類
唯一索引:唯一索引有兩個作用,一個是數據約束,一個是數據索引。其中數據約束主要用來保證數據的完整性,唯一索引產生的索引記錄中每一條記錄都對應一個唯一的ROWID。
主關鍵字索引:主關鍵字索引產生的索引同唯一索引,只不過它是在數據庫建立主關鍵字時系統自動建立的。
一般索引:一般索引不產生數據約束作用,其功能主要是對字段建立索引表,以提高數據查詢速度。
按索引對象分類
單列索引(表單個字段的索引)
多列索引(表多個字段的索引)
函數索引(對字段進行函數運算的索引)
數據庫的索引分為:聚集索引,非聚集索引,唯一索引。
2. 索引優點
優點:方便了查詢,在數據量大時排序更易查詢
3. 索引缺點
缺點:查詢時需要進行重新排序,減少了效率。
物理索引缺點:建立索引效率低,只能建一個
4. 索引作用
為什麽要創建索引呢?這是因為,創建索引可以大大提高系統的性能。
第一,通過創建唯一性索引,可以保證Oracle數據庫表中每一行數據的唯一性。
第二,可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。
第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。
第四,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。
第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
表分區的優缺點
Oracle允許用戶把一個表中的所有行為分為幾個部分,並將這些部分存儲在不同的位置。被分區的表成為分區表,分成的每個部分稱為一個分區。
表分區有以下優點:
1) 增強可用性:如果表的某個分區出現故障,表在其他分區的數據仍然可用;
2) 維護方便:如果表的某個分區出現故障,需要修復數據,只修復該分區即可;
3) 均衡I/O:可以把不同的分區映射到磁盤以平衡I/O,改善整個系統性能;
4) 改善查詢性能:對分區對象的查詢可以僅搜索自己關心的分區,提高檢索速度。
缺點:
分區表相關:已經存在的表沒有方法可以直接轉化為分區表。
什麽時候使用分區表:
1、表的大小超過2GB。
2、表中包含歷史數據,新的數據被增加都新的分區中。
分區方法包括範圍分區、散列分區、列表分區、復合分區、間隔分區、虛擬列分區。
三、PL/SQL編程
PL/SQL是結合了Oracle過程語言和結構化查詢語言的一種擴展語言。
PL/SQL的優點:
(1)PL/SQL具有編程語言的特點,他能把一組SQL語句放到一個模塊中,使其更具模塊化程序的特點。
(2)PL/SQL可以采用過程性語言控制程序的結構。
(3)同其他的編程語言一樣,PL/SQL可以對程序中的錯誤進行自動處理,使程序能夠在遇到錯誤時不會中斷,即他的異常處理機制。
(4)PL/SQL程序塊具有更好的可移植性,可以移植到另一個Oracle數據庫中。
(5)PL/SQL程序減少了網絡的交互,,有助於提高程序性能。
一個PL/SQL塊由三部分組成,即聲明部分、執行部分、異常處理部分。
PL/SQL語言支持的操作符包含關系運算符、一般運算符、邏輯運算符。
PL/SQL數據類型
1.標量數據類型
標量數據類型包含單個值,沒有內部組件。標量數據類型包含數字、字符、布爾值和日期時間值四類。
2.LOB數據類型
Oracle提供了LOB數據類型,用於存儲大的數據對象的類型。
3.屬性類型
屬性用於引用變量或數據庫列的數據類型,以及表示表中一行的記錄類型。
1)%TYPE
定義一個變量,其數據類型與已經定義的某個數據變量的數據類型相一致,這是可以使用%TYPE。
優點:
(1)可以不必知道所引用的數據庫列的數據類型。
(2)所引用的數據庫列的數據類型可以實時改變,容易保持一致,不用修改PL/SQL程序。
2)%ROWTYPE
返回一個記錄類型,其數據類型和數據庫表的數據結構相一致,這時可以使用%ROWTYPE。
優點:
(1)可以不必知道所引用的數據庫中列的個數和數據類型。
(2)所引用的數據庫中列的個數和數據類型可以實時改變,容易保持一致,不用修改PL/SQL。
PL/SQL控制語句
PL/SQL程序可通過控制結構來控制命令執行的流程。
控制結構共有三種類型:條件控制、循環控制、順序控制。
異常處理
在運行程序時出現的錯誤叫異常。
異常情況處理用來處理正常執行過程中未預料的事件。
用戶自定義異常步驟:
(1)在PL/SQL塊的定義部分定義異常情況。
(2)拋出異常情況。
(3)在PL/SQL塊的異常情況處理部分對 異常情況做出相應的處理。
遊標
1.什麽是遊標
為了處理SQL語句,ORACLE必須分配一片內存區域,這就是上下文區域(context area)。上下文區域包含了完成該處理所必需的信息,其中包括語句要處理的行的數目、一個指向語句被分析後產生的表示形式的指針,以及查詢的活動集(active set,這是查詢返回的行的集合)。
遊標(cursor)就是一個指向上下文區域的句柄(handle)或指針。通過遊標,PL/SQL程序可以控制上下文區域和在處理語句時上下文區域會發生些什麽事情。
2.顯式遊標
處理顯式遊標包括四個PL/SQL步驟
1)聲明遊標
2)為查詢打開遊標
3)將結果提取(fetch)到PL/SQL變量中
4)關閉遊標
fetch語句有兩種形式
1) fetch cursor_name into list_of_variables;
2) fetch cursor_name into PL/SQL_record;
這裏cursor_name標識了已經被聲明並且被打開的遊標,list_of_variables是已經被聲明的PL/SQL變量的列表(變量之間用逗號隔開),而PL/SQL_record是已經被聲明的PL/SQL記錄。
遊標的四個屬性
1)%FOUND 一個布爾屬性。如果前一個FETCH語句返回一個行,那麽它就會返回TRUE,否則的話,它會返回FALSE。如果在未打開遊標以前就設置了%FOUND,那麽會返回ORA-1001(無效的遊標)。
2)%NOTFOUND 行為方式和上面的%FOUND正好相反。如果前一個FETCH語句返回一個行,那麽%NOTFOUND就會返回FALSE。僅當前一個FETCH語句沒有返回任何行,%NOTFOUND才會返回TRUE。
3)%ISOPEN 此布爾屬性用來決定相關的遊標是否被打開了。如果被打開了則返回TRUE,否則返回FALSE。
4)%ROWCOUNT 此數字屬性返回到目前為止由遊標返回的行的數目。如果在相關的遊標還未打開的時候進行引用,那麽會返回ORA-1001錯誤。
四、Hibernate入門
Hibernate框架的優點:
1) 對象/關系數據庫映射(ORM), 使用時只需操縱對象,使開發更加面向對象化;
2) 無入侵性;
3) 簡潔的HQL語句,減少了JDBC與SQL操作數據庫的代碼量;
4) 移植性好;
Hibernate框架的缺點:
1)不適合以數據為中心大量使用存儲過程的應用。
2)大規模的批量插入、修改和刪除不適合用Hibernate。
1、什麽是hibernate
hibernate是免費開源的框架,是一個OR-Mapping映射工具, 將實體類和數據庫表形成映射關系,是一個優秀的持久層解決方案,hibernate對jdbc進行了封裝,我們不需要再關心底層實現,只需要關系具體的業務實現即可。
hibernate核心類和接口
Configuration類: 加載hibernate.cfg.xml配置文件
SessionFactory接口:會話工廠,可以得到會話
Session接口: 會話,操作CRUD增刪改查
Transaction接口: 事務,開啟事務,提交事務,關閉事務
2、hibernate工作原理
通過Configuration對象加載hibernate.cfg.xml配置文件,
hibernate.cfg.xml配置文件主要管理數據庫連接相關信息與實體類和數據庫表的映射關系,所以當加載hibernate.cfg.xml配置文件的時候把實體類和數據庫表之間建立了映射關系,然後調用buildSessionFactory()方法得到數據庫連接的會話工廠sessionFactory,再通過會話工廠得到session會話,通過session會話開啟事務,然後執行CRUD操作,再進行事務提交,最後關閉session會話。
3、為什麽要用hibernate
hibernate是一個優秀的持久層解決方案,提供了標準化模版,能夠為開發人員提高開發效率。
4、hibernate和jdbc的區別
查詢效率:jdbc因為直接操作數據庫,所以查詢效率相比hibernate要高,
hibernate要對實體類和數據庫表字段之間做映射關系的維護,所以查詢效率相對來說要低。
開發效率:jdbc相當於手動式,SQL代碼和封裝都需要手動完成,而hibernate相當於自動化,由於對jdbc進行封裝,所以底層代碼不需要開發人員編寫,所以開發效率hibernate要高。
5、Hibernate和MyBatis的區別?
1.Hibernate是全自動的ORM框架 而MyBatis是半自動的ORM框架
2.MyBatis 是一個基於DAO層處理的ORM框架 SQL語句和實體映射
Hibernate 是一個基於DAO層處理的ORM框架 表和實體的映射
3.Hibernate是一個重量級框架 適用於大中型項目
MyBatis是一個輕量級框架 適用於中小型項目 尤其是當下的互聯網項目
4.Hibernate封裝的比較好,而MyBatis比較靈活
主鍵生成策略
常用主鍵的生成策略如下:
4.1.increment:對類型為long short 或 int的主鍵,以自動增長的方式生成主鍵的值。主鍵按數值順序遞增,增量為1.
4.2.identity:對如SQLServer、DB2、MySQL等支持標識列的數據庫,課使用該主鍵生成策略生成自動增長主鍵,但要在數據庫中將該主鍵設置為標識列。
4.3.sequence:對如Oracle、DB2等支持序列的數據庫,可使用該主鍵生成策略生成自動增長主鍵,通過子元素param傳入數據庫中序列的名稱。
4.4.native:由Hibernate根據底層數據庫自行判斷采用何種主鍵生成策略,即由使用的數據庫生成主鍵的值。
4.5.assigned:主鍵由應用程序負責生成,無需Hibernate參與
Hibernate中java對象的三種狀態
Hibernate框架通過Session來管理Java對象的狀態
瞬時狀態 new對象/delete
通過new創建對象後,沒有存儲到數據庫,此時java對象的狀態為瞬時狀態。
持久狀態 get、load/save/update
當對象與Session關聯,被Session管理時,他就處於持久狀態。
對象與Session關聯:
1.通過Session查詢接口,或者get()|load()
2.通過調用Session的save()|SaveOrUpdate()
遊離狀態 evict、clear、close
處於持久狀態的對象,脫離與其關聯的Session管理後,對象就處於遊離狀態。
Session提供兩個方法(update() merge())將處於遊離狀態的對象與一個新的Session發生關聯
三種狀態之間的轉換
1.瞬時狀態轉換為持久狀態
使用Session對象的save()或saveOrUpdate()方法保存對象後,該對象的狀態由瞬時狀態轉換為持久狀態
使用Session對象的get()或load()方法獲取對象,該對象的狀態是持久狀態
2.持久狀態轉換為瞬時狀態
執行Session對象的delete()方法後,對象由原來的持久狀態變為瞬時狀態,因為此時該對象沒有與任何的數據庫數據關聯
3.持久狀態轉為遊離狀態
執行了Session對象的evict()、clear()或close()方法,對象由原來的持久狀態轉為遊離狀態
4.遊離狀態轉為持久狀態
重新獲取Session對象,執行Session對象的update()或saveOrUpdate()方法,對象由遊離狀態轉為持久狀態,該對象再次與Session對象關聯
5.遊離狀態轉為瞬時狀態
執行Session對象的delete()方法,對象由遊離狀態轉為瞬時狀態。
處於瞬時狀態或遊離狀態的對象不再被其他對象引用時,會被Java虛擬機安裝垃圾回收機制處理。
臟檢查和刷新緩存
臟檢查:session中的對象信息與數據庫不一致
刷新緩存:解決session中的對象信息與數據庫不一致的情況
實現:flush()、commit()
Session是Hibernate向應用程序提供的操縱數據庫的主要接口,它提供了基本的保存、更新、刪除和加載Java對象的方法。Session具有一個緩存,可以管理和跟蹤所有持久化對象,對象和數據庫中的相關記錄對應。在某些時間點,Session會根據緩存中對象的變化來執行相關SQL語句,將對象包含的編號數據更新到數據庫中,這一過程稱為刷新緩存,換句話說就是將Session緩存同步刷新為與數據庫一致。
1.臟檢查
在Hibernate中,狀態前後發生變化的對象,稱為臟對象。
當事務提交時,Hibernate會對Session中持久狀態的對象進行檢測,判斷對象的數據時候發生了改變,這種判斷稱為臟檢查。
Hibernate為什麽要進行臟檢查呢?
因為如果對象發生了改變,就需要將改變更新到數據庫中,以確保內存中的對象與數據庫中的數據保持一致。
Session是如何進行臟檢查的呢?
當一個Dept對象被加入到Session緩存中時,Session會為Dept對象的值類型的屬性復制一份快照。當Session刷新緩存是,會先進行臟檢查,即比較Dept對象的當前屬性與它的快照,來判斷Dept對象的屬性是否發生了變化。如果發生了變化,Session會根據臟對象的最新屬性值來執行相關的SQL語句,將變化更新到數據庫中。
2.刷新緩存機制
當Session緩存中對象的屬性每次發生變化時,Session並不會立即刷新緩存和執行相關的SQL語句,而是在特定的時間點才刷新緩存。這使得Session能夠把幾條相關的SQL語句合並為一條或者一批SQL語句,減少了訪問數據庫的次數,從而提高應用程序的數據訪問性能。
Session在何時刷新緩存呢?
1.當應用程序調用Transcation的commit()方法時,commit()方法先調用Session的刷新緩存方法flush(),然後向數據庫提交事務。Hibernate之所以把刷新緩存時間點安排在事務快結束時,一方面是因為可以減少訪問數據庫的頻率,林一方面是因為可以盡可能縮短當前事務對數據庫中相關資源的鎖定時間。
2.當應用程序顯示調用Session的flush()方法時,刷新緩存。
Session的flush()方法和Transaction的commit()方法的區別?
flush()方法進行刷新緩存的操作,執行一系列的SQL語句,但不會提交事務;commit()方法會先調用flush()方法,然後提交事務。提交事務意味著對數據庫所做的更新被永久保存下來。
sava、update、savaOrUpdate、merge的區別?
save()方法用於將一個臨時對象轉變為持久化對象,也就是將一個新的業務實體保存到數據庫中;
update()方法用於將一個遊離對象重新轉變為持久化對象,也就是更新一個已經存在的業務實體到數據庫中;
saveOrUpdate()兼具了save()和update()方法的功能,該方法根據傳入參數的狀態執行不同的操作,當為臨時狀態時,調用save()方法;當為持久化狀態時,則直接返回;當為遊離狀態時,調用update()方法。
merge()方法主要用於更新和保存實體,當實體不存在時,則執行保存操作,當實體已經存在時,執行更新操作,其實同saveOrUpdate()的功能是類似的。
update 和 merge的區別
首先在執行更新操作的時候,兩者都必須要有id
update是直接執行update 語句,執行後狀態為持久化狀態
而merge則不一樣:
1. 如果session中有與之對應的對象,也就是主鍵相同,則會把要保存的obj的值copy給session中的對象,然後update被復制後的session中的對象
2. 如果session中沒有,則會先從數據庫中select,然後把obj給查出來的對象copy,則update查出來的對象。
3. 所以merge會先select 再update
4. 所以merge後原來的對象狀態為遊離。
save 和update區別
把這一對放在第一位的原因是因為這一對是最常用的。
save的作用是把一個新的對象保存
update是把一個脫管狀態的對象或自由態對象(一定要和一個記錄對應)更新到數據庫
update 和saveOrUpdate區別
這個是比較好理解的,顧名思義,saveOrUpdate基本上就是合成了save和update,而update只是update;引用hibernate reference中的一段話來解釋他們的使用場合和區別
通常下面的場景會使用update()或saveOrUpdate():
程序在第一個session中加載對象,接著把session關閉
該對象被傳遞到表現層
對象發生了一些改動
該對象被返回到業務邏輯層最終到持久層
程序創建第二session調用第二個session的update()方法持久這些改動
saveOrUpdate(po)做下面的事:
如果該po對象已經在本session中持久化了,在本session中執行saveOrUpdate不做任何事
如果savaOrUpdate(新po)與另一個與本session關聯的po對象擁有相同的持久化標識(identifier),拋出一個異常
五、HQL實用技術
Hibernate支持三種查詢方式:HQL查詢、Criteria查詢及原生 SQL查詢。
HQL是面向對象的查詢語句,在Hibernate提供的各種查詢方式中,HQL是使用最廣的一種查詢方式。
執行HQL語句需要使用Query接口,Query也是Hibernate的核心接口之一,執行HQL的兩種常用方法是list()方法和iterate()方法。
執行HQL語句的步驟:
(1)獲取Session對象
(2)編寫HQL語句
(3)創建Query對象
(4)執行查詢,得到查詢結果
HQL的參數綁定有以下兩種形式:
1.按參數位置綁定
2.按參數名稱綁定
通過Query接口的setFirstResult(int firstResult)方法和setMaxResults(int maxResults)方法實現分頁。
投影查詢就是想查詢某一字段的值或者某幾個字段的值
六、Hibernate關聯映射
對象間的關聯分為一對多、多對一和多對多等幾種情況,關聯是有方向的,可以是雙向的關聯,也可以是單向的關聯。
Hibernate通過配置的方式,將對象見的關聯關系映射到數據庫上,方便完成多表的持久化操作。
使用<set>元素和<one-to-many>元素配置一對多關系,<set>元素常用屬性如下:
1.name:關聯類屬性的名稱,是必須填寫,沒有默認值。
2.table:關聯類的目標數據庫表,可以不關聯數據表,沒有默認值。
3.lazy:指定關聯對象延遲加載策略,默認為true.
4.fetch:設置抓取數據的策略,默認為select.
5.inverse:描述對象之間關聯關系的維護方式,默認為false.
<set>節點的inverse屬性描述了由哪一方負責維系關系聯系;cascade屬性描述了級聯操作的規則。
cascade屬性:
1.all :對象所有操作進行級聯操作 save,update,delete
2.save-update : 執行保存和更改操作時進行級聯操作
3.delete : 執行刪除操作時進行級聯操作
4.none : 對所有操作不進行級聯操作 默認
Hibernate提供了延遲加載策略,主要分為類級別、一對多和多對多關聯,以及多對一關聯加載策略。
Open Session In View模式的主要思想是:在用戶的每次請求過程中,始終保持一個Session對象處於開啟狀態。
七、HQL連接查詢和註解
HQL支持左外連接、迫切左外連接、內連接、迫切內連接及右外連接等連接查詢。
連接類型:
內連接 inner join 或join
迫切內鏈接 inner join fetch
左外聯結 left outer join 或 join
迫切左外連接 left outer join fetch 或 left join fetch
右外連接 right outer join 或 right join
Hibernate查詢優化策略:
1.使用迫切左外連接或迫切內連接查詢緩存方式,減少select語句的數目,降低訪問數據庫的頻率。
2.使用延遲加載策略方式避免加載多余的不需要訪問的數據。
3.使用Query接口的iterator()方法減少select語句中的字段,從而降低訪問數據庫的數據量。
HQL優化:
HQL優化是Hibernate程序性能優化的一個方面,HQL的語法與SQL非常相似。HQL是基於SQL的,只是增加了面向對象的封裝。如果拋開HQL同Hibernate本身一些緩存機制的關聯,HQL的優化技巧同SQL的優化技巧一樣。在編寫HQL時,需註意以下幾個原則:
(1)避免or操作的使用不當
(2)避免使用not
(3)避免使用like的特殊形式,例如 “%”或者”_”開頭
(4)避免having字句
(5)避免distinct
(6)索引在以下情況下失效,應註意使用
1.只要對字段使用函數,該字段的索引將不起作用,如substring(aa,1,2)=’xx’
2.只要對字段進行計算,該字段的索引將不起作用,如Price+10
HQL常用聚合函數:
(1)count():統計記錄條數
(2)sum():求和
(3)min():求最小值
(4)max():求最大值
(5)avg():求平均值
HQL查詢語句使用group by子句進行 分組查詢,使用having子句篩選分組結果。
使用Hibernate註解的步驟如下:
(1)使用註解配置持久化類及對象關聯關系。
(2)在Hibernate配置文件(hibernate.cfg.xml)中聲明持久化類。
配置持久化類的常用註解:
@Entity 將一個類聲明為一個持久化類
@Id 聲明了持久化類的標識屬性(相當於數據表的主鍵)
@GeneratedValue 定義標識屬性值的生成策略
@Table 為持久化類映射指定表(table)。目錄(catalog)和schema的名稱。默認值:持久化類名,不帶包名
@UniqueConstraint 定義表的唯一約束
@Lob 表示屬性將被持久化為Blob或者Clob類型
@Column 將屬性映射到列
@Transient 忽略這些字段和屬性,不用持久化到數據庫
@GeneratedValue 定義標識屬性值的生成策略,JPA提供了4種標準用法
(1) AUTO:根據不同的數據庫選擇不同的策略
(2) TABLE:使用表保存id值
(3) INDENTITY:使用數據庫自動生成主鍵
(4) SEQUENCE:使用序列創建主鍵
註解配置對象關聯關系:
@OneToOne 建立持久化類之間的一對一關聯關系
@OneToMany 建立持久化類之間的一對多關聯關系
@ManyToOne 建立持久化類之間的多對一關聯關系
@ManyToMany 建立持久化類之間的多對多關聯關系
cascade屬性指定級聯操作
1.CascadeType.remove:連接刪除
2.CascadeType.persist:persist()方法級聯
3.CascadeType.merge:級聯更新
4.CascadeType.refresh:級聯刷新
5.CascadeType.all:包含所欲有級聯操作
八、Struts 2入門
Struts 2是以WebWork設計思想為核心,在吸收了Struts 1部分優點的基礎上設計出來的新一代MVC框架。
Struts 2 相比Struts 1的優點:
1、在軟件設計上Struts 2 沒有像Struts 1那樣跟Servlet API 和 struts API 有著緊密的耦合。Struts 2的應用可以不依賴於Servlet API和Struts API 。
2、Struts 2 提供了攔截器,利用攔截器可以進行AOP編程。
3、Struts 2 提供了類型轉換器。
4、Struts 2 提供支持多種表現層技術,如:JSP 、 freeMarker等。
5、Struts 2 的輸入校驗可以指定方法進行校驗。
6、Struts 2 提供了全局範圍、包範圍和Action範圍的國際化資源文件管理實現。
Struts 2 體系結構 :
1、Web瀏覽器請求一個資源。
2、過濾器Dispatcher查找方法,確定適當的Action。
3、攔截器自動對請求應用通用功能,如驗證和文件上傳操作。
4、Action的execute方法通常用來存儲和重新獲得信息。
5、結果被返回到瀏覽器。
基本簡要流程:
1、客戶端瀏覽器發出HTTP請求。
2、根據web.xml配置,該請求被FilterDispatcher接收。
3、根據struts.xml配置,找到需要調用的Action類和方法, 並通過IoC方式,將值註入給Aciton。
4、Action調用業務邏輯組件處理業務邏輯,這一步包含表單驗證。
5、Action執行完畢,根據struts.xml中的配置找到對應的返回結果result,並跳轉到相應頁面。
6、返回HTTP響應到客戶端瀏覽器。
與Servlet API解耦的訪問方式:
1.通過ActionContext類進行訪問。
2.Struts 2向Action註入。
與Servlet API耦合的訪問方式:
1.通過ServletActionContext類進行訪問。
2.Struts 2向Action註入。
Struts 2數據校驗:
1. 用validate()方法實現數據校驗
繼承ActionSupport類,該類實現了Validateable接口,該接口中定義了一個validate()方法,在自定義的Action類中重寫validate()方法,如果校驗表單輸入域出現錯誤,則將錯誤添加到ActionSupport類的fieldErrors域中,然後通過OGNL表達式負責輸出。
2.用execute()方法實現數據校驗
繼承自ActionSupport類,重寫execute()。繼承該類是因為它實現了Validateable接口,才能實現數據校驗
相對於Validate()方法不同之處就是對hasErrors進行了判定,判定FieldError對象中是否有錯誤信息,若有錯誤信息,返回input
3.用validateXxx()方法實現數據校驗
在validate()方法中對數據驗證是可以工作的,如果在字段非常多的情況下,而且每個字段又有很復雜的驗證,那麽我們的validate方法中的代碼會越來越多。 針對特定的方法輸入的數據的驗證我們把他放到validateXxx方法中,Xxx是方法名的首字母大寫形式。
一般在字段判定比較多的情況下,可以使用這種方式實現數據校驗。
Struts 2標簽主要分為兩大類:即UI標簽和通用標簽。
Struts 2的UI標簽可分為三類:表單標簽、非表單標簽、Ajax標簽。
通用標簽用來在頁面表示的時候控制代碼執行的過程,這些標簽也允許從Action或者值堆棧中取得數據。
九、Struts 2配置詳解
1.在Struts 2框架中,控制器由兩部分組成:
核心控制器:用於攔截用戶請求,對請求進行處理 ------StrutsPrepareAndExecuteFilter
業務控制器:調用相應的Model類實現業務處理,返回結果
2.Result
作用:實現結果視圖的調用,並決定視圖以哪種形式展現給客戶端
3.Struts 2的執行過程
(1)當Web容器接收到請求後,將請求交由在web.xml中配置的Struts 2框架的控制器 StrutsPrepareAndExecuteFilter(核心控制器)。
(2)由StrutsPrepareAndExecuteFilter確定請求對應的Action(業務控制器)。
(3)框架根據Action返回的結果字符串,由StrutsPrepareAndExecuteFilter(核心控制器 )選擇對應的result,將結果呈現給用戶。
4.處理中文亂碼
<constant name = "struts.il8n.encoding" value = "UTF-8"/>
5.在struts.xml中使用package元素定義包。package元素包含多種屬性,其中:
name屬性為必需的並且是唯一的,用來指定包的名稱(被其他包引用)。
extends屬性類似java的extends關鍵字,指定要擴展的包。
6.namespace是一個可選屬性,該屬性定義該包中action的命名空間。
默認的命名空間用“”表示,也可以使用“/”定義一個根命名空間。
區別:當請求Web應用程序根路徑下的action,框架在根命名空間中查看相應的action,如果在根路徑下未找到,則再到默認的命名空間中去查找
7.Action的作用:
(1)Action最重要的作用是為給定的請求封裝需要做的實際工作(調用特定的業務處理類)
(2)為數據的轉移提供場所
(3)幫助框架決定由哪個結果呈現請求相應
8.Struts 2在根據action元素的method屬性查找執行方法時有兩種途徑
(1)查找與method屬性值完全一致的方法
(2)查找doMethod()形式的方法
9.Result的配置由兩部分組成:
一部分是Result所代表的實際資源的位置及Result名稱;
另一部分是Result的類型,由 result元素的type屬性進行設定;
10.對Result配置中常用的三種結果類型總結如下
dispatcher類型:Action默認的結果類型,采用轉發的形式請求指定的視圖資源,請求中的數據信息不會丟失;
redirect類型:采用重定向的方式指定的視圖資源,通過HttpServletResponse對象的sendRedirect()方法重新生成一個請求,原請求中的數據信息會丟失;
redirectAction類型:采用重定向的方式請求一個新的Action,原請求中的數據信息會丟失;
11.Struts 2的配置文件:
struts.xml:Struts 2的核心配置文件。
struts-plugin.xml:Struts 2插件使用的配置文件。
struts-default.xml:Struts 2的默認配置文件。
12.struts.xml文件的各項內容如下。
Action配置:
動態方法:actionName!methodName.action。
通配符:使用星號(*)表示0個或多個字符串。
默認Action:使用<default-action-ref/>完成。
Result配置:
常用結果類型:dispatcher類型、redirect類型、redirectAction類型。
動態結果:使用${attributeName}該問Action中的屬性,實現動態結果配置。
全局結果:在global-results元素中嵌套result元素實現全局結果配置。
十、OGNL
OGNL的全稱是Object Graph Navigation Language,即對象圖導航語言。它是一個開源項目,工作在視圖層,用來取代頁面中的Java腳本,簡化數據的訪問操作。
OGNL在框架中主要做兩件事:表達式語言和類型轉換器。
ValueStack值棧
定義:是內存中的一塊空間,棧和堆之外的空間,它具有棧的特征,可以存放多個對象,如果存放多個對象,他們是按照先後順序壓入堆棧的。框架在處理每個請求時,都會創建該請求對應的運行環境,這時會創建值棧和請求對應的Action實例,並將Action實例壓入值棧中。
Struts 2提供了非常強大的類型轉換功能,提供了多種內置類型轉換器,支持開發自定義類型轉換器。
Struts 2提供了兩種方式來配置轉換器,即應用於全局範圍的類型轉換器和應用於特定類的類型轉換器。
Struts2內置的類型轉換:
String和boolean 完成字符串與布爾值之間的轉換。
String和char 往常字符串與字符之間的轉換。
String和int、Integer 完成字符串與整型之間的轉換。
String和Long 完成字符串與長整型值之間的轉換。
String和double、Double 完成字符串與雙精度浮點值的轉換。
String和Float 完成字符串和單精度浮點之間的轉換。
String和Date 完成字符串和日期類型之間的轉換,日期格式使用格式用戶請求所在Locale的SHORT格式。
String和數組 在默認的情況,數組元素是字符串,如果用戶定義類型轉換器,也可以是其它復合數據類型。
Struts 2框架使用OGNL作為默認的表達式語言。
OGNL相對其它表達式語言具有下面幾大優勢:
1、支持對象方法調用,如xxx.doSomeSpecial();
2、支持類靜態的方法調用和值訪問,表達式的格式: @[類全名(包括包路徑)]@[方法名 | 值名],例如: @[email protected](‘foo %s‘, ‘bar‘) 或@[email protected]_NAME;
3、支持賦值操作和表達式串聯,如price=100, discount=0.8, calculatePrice(),這個表達式會返回80;
4、訪問OGNL上下文(OGNL context)和ActionContext;
5、操作集合對象。
ActionContext中包含多個對象。如果訪問根對象,可直接書寫對象的屬性,而要使用其他對象必須使用“#key”前綴來訪問。
URL標簽和日期標簽:
URL標簽的作用是構建一個URL地址,在該標簽中借助param子元素可以指定在跳轉URL的同時傳遞的參數。
日期標簽用於格式化輸出一個日期,還可以計算指定日期和當前日期時刻之間的時差。
十一、攔截器
Struts 2體系結構的核心就是攔截器。
什麽是Struts 2攔截器?
從軟件構架上來說,攔截器是實現了面向方面編程的組件。它將影響了多個業務對象的公共行為封裝到一個個可重用的模塊,減少了系統的重復代碼,實現功能的高度內聚,確保了業務對象的整潔和純度。
從Java代碼上來說,它就是一個普度的Java對象,它只需要實現一個名為Interceptor的接口。
為什麽要使用攔截器?
攔截器消除了動作組件中的橫切任務(cross-cutting task)。例如,日誌記錄是一個典型的橫切關註。以前,我們可能需要為每個動作組件準備一些記錄日誌的代碼。雖然這樣看上去也沒什麽錯誤,但是一個不可以忽視的事實是——這些用於記錄日誌的代碼並不是動作組件與模型交互的一部分。並且,日誌記錄是我們想為系統處理的每一個請求完成的管理性任務,它不是一個動作組件所特有的,而是貫穿了所有動作組件。Struts 2將這個功能放在了更高的層次上,我們可以能把日誌記錄的代碼轉移到動作組件之外,從而讓動作組件更加簡潔清晰。
攔截器組件提供了一個不錯的場所,來將不同的橫切關註點邏輯分成有層次的、可重用的部件。
攔截器的工作原理?
Struts2攔截器圍繞Action和Result的執行而執行。其實現原理和Servlet Filter差不多,以鏈式執行,對真正要執行的方法(execute())進行攔截。首先執行Action配置的攔截器,在Action和Result執行之後,攔截器在一次執行(與先前的執行順序相反),在此以鏈式的執行過程中,任何一個攔截器都可以直接返回,從而終止余下的攔截器、Action及Result的執行。
當ActionInvocation的invoke()方法被調用時,開始執行Action配置的第一個攔截器,攔截器作出相應的處理後會在此調用ActionInvocation的invoke()方法,ActionInvocation對象負責跟蹤執行過程的狀態,並且把控制權交給合適的攔截器。ActionInvocation通過調用攔截器的intercept()方法將控制轉交給攔截器。因此,攔截器的執行過程可以看做是一個遞歸的過程,後續攔截器繼續執行,直到最後一個攔截器,invoke()方法會執行Action的execut()方法。
攔截器觸發時能夠做些什麽?
1. 做一些預處理。在這個階段攔截器可以用來準備、過濾、改變或者操作任何可以訪問的重要數據。這些數據包括所有與當前請求相關的關鍵對象和數據,也包括動作。
2. 通過調用invoke()方法將控制轉移給後續的攔截器,直到動作。或者通過返回一個控制字符串中斷執行。在這個階段,如果攔截器決定請求不應該繼續,他可以不調用ActionInvocation實例上的invoke()方法,而是直接返回一個控制字符串。通過這種方式可以停止後續的執行,並且決定哪個結果被呈現。
3. 做一些後加工。在這個階段,任何一個返回的攔截器可以修改可以訪問的對象的數據作為後加工,但是此時結果已經確定了。
Struts 2內置攔截器
params攔截器 :將請求中的數據設置到Action的屬性上。
servletConfig攔截器:將源於Servlet API的各種對象註入Action。
staticParams攔截器:將在配置文件中配置的參數註入Action。
fileUpload攔截器:將文件和元數據從多重請求轉換為常規的請求數據。
validation攔截器:執行數據校驗。
workdation攔截器:當數據校驗錯誤時,提供終止流程的功能。
exception攔截器:用於捕獲異常。
自定義攔截器:
實現Interceptor接口。
繼承AbstractInterceptor類。
Struts 2框架實現文件上傳時需要添加commons-fileupload-x.x.x.jar和commons-io-x.x.x.jar文件。在Action中使用三個屬性封裝文件信息:
File類型的xxx屬性。
String類型的xxxFileName。
String類型的xxxContentType。
使用Struts 2框架實現文件下載時,需要經過stream結果類型來實現,參數設置包括:
contentType:下載文件的文件類型。
contentLength:設置文件的大小。
inputName:對應實現的InputStream屬性。
contentDisposition:一方面表示文件的處理方式,另一方面指定下載文件的顯示文件名稱。
bufferSize:指定下載文件時的緩沖區大小。
SSH入門筆記