hibernate防sql注入
⑴ hibernate操作資料庫,用佔位符有什麼好處與直接拼字元串相比有什麼好處
1.層次清晰,HQL長了之後代碼也不顯得亂
2.確實可以提高一定效率
3.安全性考慮,防止一些注入性攻擊, 舉個例子如果你的租含ruleCode變數從jsp頁面獲得,是客戶手動輸入的,那麼客戶如果惡意的輸入一些特殊的字元 如 'or'='or' 那麼你的HQL解析成sql就變成
select * from CategoryRule vc where vc.ruleCode = 『嘩握or』='or' ,如果這是用戶名或者密碼, 這樣可能就能非法登錄系統 ,或者獲得後台一些數據錯誤信息的反饋。
採用setString就會把'or'='or' 整體當成一個串,就弊蘆笑不會出現這種問題
⑵ java怎樣過濾危險字元,該怎麼解決
就WEB應用來說,所謂危險的字元一般就是兩種
一個是SQL注入,一個是HTML語法注入
SQL注入主流的框架都可以搞定,JDBC永遠都使用preparedstatement就可以防止所有的sql注入,關鍵是用戶輸入都要通過佔位符往裡放,就自動的替換掉了特殊字元了。hibernate等orm框架都會搞定這個問題
HTML語法注入是指用戶輸入的html代碼回顯出來,這樣如果不轉義就可以破壞頁面的結構或者注入腳本。所以現在的網站都不允許用戶直接輸入html代碼了,現在都是一些UBB標簽來完成一些效果。HTML主要最好的解決辦法是在回顯的時候進行轉義,所有的MVC框架或者展示層框架都有HTML轉義的支持,包括struts,spring,volicty等,注意觀察他們用於顯示的標簽
⑶ java拼接sql怎麼防止注入
使用Hibernate框架的SQL注入防範 Hibernate是目前使用最多的ORM框架,在Java Web開發中,很多時候不直接使用JDBC,而使用Hibernate來提高開發效率。
在Hibernate中,仍然不應該通過拼接HQL的方式,而應使用參數化的方式來防範SQL注入。有兩種方式,一種仍然是使用JDBC一樣的佔位符「?」,但更好的方式是使用Hibernate的命名參數,例如檢測用戶名和密碼是否正確,使用Hibernate可以寫成:
String queryStr = 「from user where username=:username 」+」password=:password」;
List result = session.createQuery(queryStr).setString("username", username).setString("password", password).list();
⑷ hibernate的setParameter()方法有什麼用
setParameter() 方法設置一個樣悄喊式表參數。
說明:這個方法為指定啟塌野的樣衫譽式表參數指定一個值。
語法::setParameter(namespaceURI,localName,value)
⑸ hibernate 通過session.createCriteria方法進行查詢,是否可防止sql注入
不能阻止,hibernate也是替換,它怎麼能防止你SQL注入。
如:sql:select * from emp where ename like '%abc%';——hibernate也是組裝的sql,替換屬性值。
'%abc%':這個是你的某個bean的一個屬性,如果改成'%%' or 1=1
這樣不是不管你什麼條件都把表中所有的記錄都檢索出來了。
⑹ 開發人員筆試題
開發人員筆試題
開發人員筆試題大家去面試的時候相信都會做過一些。下面是我整理的開發人員筆試題,歡迎大家閱讀。
開發人員筆試題一
一、填空禪巧姿題(本大題10小題,每空1分,共20分) 。
1.Java語言的三大特性即是、寬肢、
2.在Java中,char 型採用____unicode_______編碼方案,這樣,無論是中文字元還是英文字元,都是佔用__2___個位元組的內存空間。
3. 形式參數指的是方法被__定義____ 時的參數行,實際參數是方法被__調用___ 時所傳遞進去的變數或值。
4.JSP
對象則是每個客戶專用的。
介面 。
6.程序中實現多線程的方法有兩種:繼承Thread類和實現
介面。
對優先順序。
8.面向對象編程的五大設計原則,分別是、 、、
9.通過Ajax,客戶端獲取的數據主要有兩種類型:文本型和 10. Socket通常也稱為套接字 ,用於描述 和
二、選擇題(本大題 20 小題,每小題2分.共40分)。
1.在JAVA中,如果父類中某些方法不包含任何邏輯,並且需要由子類重寫.應該使用( )關鍵字來聲明父類的這些方法:
A) final B) static C) abstract D) void
2.在JAVA中,已定義兩個介面B和C,要定義一個實現這兩個介面的類,以下語句正確的是( )。
賀絕A) interface A extend B,C B) interface A implements B,C
C) class A implements B,C D) class A implements B, implements C
3.在JAVA介面中可以定義( )。
A) 靜態方法 B) 常量 C) 構造方法 D) 抽象方法
4.假設A有構造方法A (int a),則在類A的其他構造方法中調用該構造方法和語句格式應為( )。
A) A(X) B) this.A(x) C) this(x) D) super(x)
5.設 x = 1 ,y = 2 , z = 3, 則表達式 y+=z--/++x 的值是( )。
A) 3 B) 3.5 C) 4 D) 5
6.下列關於繼承的說法哪個正確?( )。
A)子類只繼承父類public方法和屬性:
B)子類繼承父類的非私有屬性和方法:
C)子類繼承父類的方法,而不繼承父類的屬性:
D) 子類將繼承的所有的屬性和方法.
7.在java中.在使用JDBC時。對於多次調用同一條SQL語句的情況, 使用( )通常會提高效。
A) Statement B) CallableStatement
C) PreparedStatement D) PrarmeterStatement
8.下列不能控制一個Servlet的生命周期方的法是:
A) service B) destroy C) doPost D) init
9.能夠給一個byte型變數賦值的范圍是( )。
A) 0~65535 B) (-128)~127
C)(-32, 768)~32, 767 D) (-256)~255
10.java語言中int類型數據佔用多少位?( )。
A) 32 B) 64 C) 16 D) 20
11. ServletContext對象是如何創建的?( )。
A) 由 Servlet容器創建,對於每個HTTP請求.Servlet容器都會創建 一個ServletContext對象
B)由JavaWeb 應用本身為自己創建一個ServletContext對象
C)由Servlet容器創建,對於每個JaveWeb應用,在啟動時,Servlet容器都會創建一個ServletContext對象
12.在JSP中不能在不同用戶之間共享數據的方法是( )。
A) 通過cookie B) 利用文件系統
C) 利用資料庫 D) 通過ServletContext對象
13.以下哪個不是Collection的子介面?( )。
A) List B) Set C) Map D) SortedSet
14. 下面正確的創建 Socket 的語句是( )。
A) Socket a = new Soeket(80):
B) Socket b = new Socket("130. 3. 4. 5", 80):
C) ServerSocket c = new Socket(80)
D) ServerSocket d = new Socket ("130. 3. 4, 5", 80)
15.下面的說法正確的是( )。
A)帶有頁作用域的對象在一個web應用程序的每個JSP中都存在.
B)指令指定與一個特定的JSP 請求不相關的全局信息。
C)當JSP容器遇到開始定製標簽和結束定製標簽時,分別調用 doInitBody方法和doAfterBody方法。
D) 動作只在翻譯時處理一次。
16.為了區分重載多態中同名的不同方法,要求:( )。
A)參數名不同 B) 採用不同的形式參數列表
C)返回值類型不同 D) 選項A, B, C都對
17.下面是有關子類調用父類構造函數的描述正確的是:( )。
A)子類定義了自己的構造函數.就不會調用父類的構造函數
B)子類必須通過Super關鍵字調用父類有參數的構造函數
C)如果子類的構造沒有通過super調用父類構造函數,那麼子類會 先調用子類自己的構造函數,再調用父類不含參數的構造函數。
D)創建子類的對象時,先調用子類自己的構造函數,然後調用父 類的構造函數
18.在Java中,負責對位元組代碼解釋執行的是( )。
A) 垃圾回收器 B) 虛擬機 C) 編譯器 D) 多線程機制
19.一個java程序運行從上到下的環境次序是( )。
A) 操作系統、Java程序、jre/jvm、硬體
B) jre/jvm、Java程序、硬體、操作系統
C) java程序、jre/jvm、操作系統、硬體
D) java程序、操作系統、jre/jvm、硬體
20.對於從Employee表中選擇記錄的'以下代碼片段,識別其遺漏的代碼行。( ) Connection con = null:
Class. forName("sun.jdbc.odbc.JdbcOdbcDriver"):
con=DriverManager.getConnection("jdbc:odbc:ss" , "sa" , "");
ResultSet rs=stat.executeQuery("select * from Employee");
A) Statement stat=createStatement();
B) Statement stat=con.createStatement ();
C) PreparedStatement stat=con.createStatement():
D) PreparedStatement stat=createPreparedStatement();
三、問答題(本大題6小題,共40分)。
1.請說出 ArrayList , Vector , LinkedList 的存儲性能和特性。(6分)
2.什麼是單例模式(Singleton) ? 請在下面寫出一個單例模式類,並支持多線程調用。(6分)
3.請描述一下JVM載入class文件的原理機制?(6分)
4.請談談對SQL注入的理解,請給出你知道的防止SQL注入的方法。(6分)
5.請談談對hibernate的理解,並簡要敘述Hibernate的一級緩存和二級緩存(8分)。
6.請寫出你知道的排序方法,並使用Java語言寫出其中一種。(8分)
三、簡答題(參考答案)
1. ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以索引數據快而插入數據慢,Vector由於使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或後向遍歷,但是插入數據時只需要記錄本項的前後項即可,所以插入速度較快。
2. 創建某類對象時,無論創建多少次該類對象只有一份在內存中,這就是單例模式。支持多線程調用,考慮線程安全,只需要加鎖即可。
public class Singleton{
private static Singleton instance = null;
private Singleton(){}
private static synchronized void syncInit(){
if(instance == null){
instance = new Singleton();
}
}
public static Singleton getInstance(){
if(instance == null){
syncInit();
}
return instance;
}
}
3. JVM中類的裝載是由ClassLoader和它的子類來實現的,Java ClassLoader是一個重要的Java運行時系統組件。它負責在運行時查找和裝入類文件的類。
4.解決辦法:a. 利用JavaScript,在客戶端進行校驗。
b.程序判斷 c.使用PreparedStatement連接資料庫。(參數化) d.利用框架技術
5. Hibernate是一個開放源代碼的對象關系映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱資料庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用。
一級緩存就是Session級別的緩存,一個Session做了一個查詢操作,它會把這個操作的結果放在一級緩存中,如果短時間內這個
session(一定要同一個session)又做了同一個操作,那麼hibernate直接從一級緩存中拿,而不會再去連資料庫,取數據;
二級緩存就是SessionFactory級別的緩存,顧名思義,就是查詢的時候會把查詢結果緩存到二級緩存中,如果同一個sessionFactory
創建的某個session執行了相同的操作,hibernate就會從二級緩存中拿結果,而不會再去連接資料庫;
6.插入排序、希爾排序、冒泡排序、快速排序、直接排序、歸並排序 下面以快速排序為例:
public class quickSort {
inta[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51};
public quickSort(){
quick(a);
for(int i=0;i
System.out.println(a[i]);
}
}
public int getMiddle(int[] list, int low, int high) {
int tmp =list[low]; //數組的第一個作為中軸
while (low < high){
while (low < high&& list[high] >= tmp) {
high--;
}
list[low] =list[high]; //比中軸小的記錄移到低端
while (low < high&& list[low] <= tmp) {
low++;
. }
list[high] =list[low]; //比中軸大的記錄移到高端
}
list[low] = tmp; //中軸記錄到尾
return low; //返回中軸的位置
}
public void _quickSort(int[] list, int low, int high) {
if (low < high){
int middle =getMiddle(list, low, high); //將list 數組進行一分為二
_quickSort(list, low, middle - 1); //對低字表進行遞歸排序
_quickSort(list,middle + 1, high); //對高字表進行遞歸排序
}
}
public void quick(int[] a2) {
if (a2.length > 0) { //查看數組是否為空
_quickSort(a2,0, a2.length - 1);
}
}
}
開發人員筆試題二
1、簡述 private、 protected、 public、 internal 修飾符的訪問許可權。
2、列舉ASP.NET 頁面之間傳遞值的幾種方式。
5、如果在一個B/S結構的系統中需要傳遞變數值,但是又不能使用Session、
Cookie、Application,您有幾種方法進行處理?
6、什麼是裝箱和拆箱?
8、ASP.net的身份驗證方式有哪些?分別是什麼原理?
9、在C#中,string str = null 與 string str = “” 請盡量使用文字或圖
象說明其中的區別。
10、SQLSERVER伺服器中,給定表 table1 中有兩個欄位 ID、LastUpdateDate,
ID表示更新的事務號, LastUpdateDate表示更新時的伺服器時間,請使用一句 SQL語句獲得最後更新的事務號
11、寫出一條Sql語句:取出表A中第31到第40記錄(SQLServer,以自動增長的ID作為主鍵,注意:ID可能不是連續的。
12、能用foreach遍歷訪問的對象需要實現 ________________介面或聲明
________________方法的類型。
14、介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可
繼承實體類(concrete class)?
15、try {}里有一個return語句,那麼緊跟在這個try後的finally {}里的code會不會被執行,什麼時候被執行,在return前還是後?
16、如何處理幾十萬條並發數據?
17、Session有什麼重大BUG,微軟提出了什麼方法加以解決?
18、向伺服器發送請求有幾種方式?
19、DataReader與Dataset有什麼區別?
20、需要實現對一個字元串的處理,首先將該字元串首尾的空格去掉,如果字元串中
間還有連續空格的話,僅保留一個空格,即允許字元串中間有多個空格,但連續的空 格數不可超過一個.
21、什麼叫做SQL注入,如何防止?請舉例說明。
22、ADO.net中常用的對象有哪些?分別描述一下。
23、什麼是SOAP,有哪些應用?
25、float f=-123.567F; int i=(int)f;i的值現在是_____?
26、使用過那幾種框架?數據持久層框架,業務層框架。
⑺ SQL注入怎麼防範
SQL注入攻擊的危害很大,而且防火牆很難對攻擊行為進行攔截,主要的SQL注入攻擊防範方法,具體有以下幾個方面:
1、分級管理
對用戶進行分級管理,嚴格控制用戶的許可權,對於普通用戶,禁止給予資料庫建立、刪除、修改等相關許可權,只有系統管理員才具有增、刪、改、查的許可權。
2、參數傳值
程序員在書寫SQL語言時,禁止將變數直接寫入到SQL語句,必須通過設置相應的參數來傳遞相關的變數。從而抑制SQL注入。數據輸入不能直接嵌入到查詢語句中。同時要過濾輸入的內容,過濾掉不安全的輸入數據。或者採用參數傳值的方式傳遞輸入變數,這樣可以最大程度防範SQL注入攻擊。
3、基礎過濾與二次過濾
SQL注入攻擊前,入侵者通過修改參數提交and等特殊字元,判斷是否存在漏洞,然後通過select、update等各種字元編寫SQL注入語句。因此防範SQL注入要對用戶輸入進行檢查,確保數據輸入的安全性,在具體檢查輸入或提交的變數時,對於單引號、雙引號、冒號等字元進行轉換或者過濾,從而有效防止SQL注入。
當然危險字元有很多,在獲取用戶輸入提交參數時,首先要進行基礎過濾,然後根據程序的功能及用戶輸入的可能性進行二次過濾,以確保系統的安全性。
4、使用安全參數
SQL資料庫為了有效抑制SQL注入攻擊的影響。在進行SQLServer資料庫設計時設置了專門的SQL安全參數。在程序編寫時應盡量使用安全參數來杜絕注入式攻擊,從而確保系統的安全性。
5、漏洞掃描
為了更有效地防範SQL注入攻擊,作為系統管理除了設置有效的防範措施,更應該及時發現系統存在SQL攻擊安全漏洞。系統管理員可以采購一些SQL漏洞掃描工具,通過專業的掃描工具,可以及時的掃描到系統存在的相應漏洞。
6、多層驗證
現在的網站系統功能越來越龐大復雜。為確保系統的安全,訪問者的數據輸入必須經過嚴格的驗證才能進入系統,驗證沒通過的輸入直接被拒絕訪問資料庫,並且向上層系統發出錯誤提示信息。同時在客戶端訪問程序中驗證訪問者的相關輸入信息,從而更有效的防止簡單的SQL注入。但是如果多層驗證中的下層如果驗證數據通過,那麼繞過客戶端的攻擊者就能夠隨意訪問系統。因此在進行多層驗證時,要每個層次相互配合,只有在客戶端和系統端都進行有效的驗證防護,才能更好地防範SQL注入攻擊。
7、資料庫信息加密
傳統的加解密方法大致分為三種:對稱加密、非對稱加密、不可逆加密。
⑻ 存儲過程如何使用
問題一:SQL 中存儲過程怎麼使用? sql存儲過程及應用
一、簡介:
存儲過程(Stored Procere), 是一組為了完成特定功能的SQL 語句,集經編譯後
存儲在資料庫中,用戶通過指定存儲過程的名字並給出參數,如果該存儲過程帶有參數來執行
它,
在SQL Server 的系列版本中,存儲過程分為兩類:系統提供的存儲過程和用戶自定義存儲過程
。
系統SP,主要存儲master 資料庫中,並以sp_為前綴並且系統存儲過程主要是從系統表中獲取
信息,從而為系統管理員管理SQL Server。用戶自定義存儲過程是由用戶創建,並能完成
某一特定功能,如:查詢用戶所需數據信息的存儲過程。
存儲過程具有以下優點
1.存儲過程允許標准組件式編程(模塊化設計)
存儲過程在被創建以後,可以在程序中被多次調用,而不必重新編寫該存儲過程的SQL語句,而
且數
據庫專業人員可隨時對存儲過程進行修改,但對應用程序源代碼毫無影響。因為應用程序源代
碼只包含存
儲過程的調用語句,從而極大地提高了程序的可移植性。
2.存儲過程能夠實現快速的執行速度
如果某一操作包含大量的Transaction-SQL 代碼,,或分別被多次執行,那麼存儲過程要比批處理
的
執行速度快很多,因為存儲過程是預編譯的,在首次運行一個存儲過程時,查詢優化器對其進
行分析優
化,並給出最終被存在系統表中的執行計劃,而批處理的Transaction-SQL 語句在每次運行時
都要進行
編譯和優化,因此速度相對要慢一些。
3.存儲過程能夠減少網路流量
對於同一個針對數據資料庫對象的操作,如查詢修改,如果這一操作所涉及到的Transaction-SQL
語句被組織成一存儲過程,那麼當在客戶計算機上調用該存儲過程時,網路中傳送的只是該調
用語句,否
則將是多條SQL 語句從而大大增加了網路流量降低網路負載。
4.存儲過程可被作為一種安全機制來充分利用
系統管理員通過,對執行某一存儲過程的許可權進行限制,從而能夠實現對相應的數據訪問許可權的
限
制。
二、變數
@I
三、流程式控制制語句(if else | select case | while )
Select ... CASE 實例
DECLARE @iRet INT, @PKDisp VARCHAR(20)
SET @iRet = '1'
Select @iRet =
CASE
WHEN @PKDisp = '一' THEN 1
WHEN @PKDisp = '二' THEN 2
WHEN @PKDisp = '三' THEN 3
WHEN @PKDisp = '四' THEN 4
WHEN @PKDisp = '五' THEN 5
ELSE 100
END
四、存儲過程格式
創建存儲過程
Create Proc dbo.存儲過程名
存儲過程參數
AS
執行語句
RETURN
執行存儲過程
GO
*********************************************************/
-- 變數的聲明,sql裡面聲明變數時必須在變數前加@符號
DECLARE @I INT
-- 變數的賦值,變數賦值時變數前必須加set
SET @I = 30
-- 聲明多個變數
DECLARE @s varchar(10),@a INT
-- Sql 里if語句
IF 條件 BEGIN
執行語句
END
ELSE BEGIN
......>>
問題二:為什麼要使用存儲過程? 幾個去 IBM 面試的兄弟回來抱怨:去了好幾個不同的 IBM項目組,幾乎每個面試官問到資料庫的時候都要問用沒用過存儲過程,煩人不?大家去面的程序員,又不是筆者認為,存儲過程說白了就是一堆 SQL 的合並。中間加了點邏輯控制。但是存儲過程處理比較復雜的業務時比較實用。比如說,一個復雜的數據操作。如果你在前台處理的話。可能會涉及到多次資料庫連接。但如果你用存儲過程的話。就只有一次。從響應時間上來說有優勢。也就是說存儲過程可以給我們帶來運行效率提高的好處。另外,程序容易出現 BUG數據量小的,或者和錢沒關系的項目不用存儲過程也可以正常運作。mysql 的存儲過程還有待實際測試。如果是正式項目,建議你用 sqlserver 或 oracle的存儲過程。數據與數據之間打交道的話,過程會比程序來的快的多。面試官問有沒有用存儲,實際上就是想知道前來面試的程序員到底做過數據量大的項目沒。如果是培訓出來的,或者小項目小公司出來的,對存儲肯定接觸的少了。所以,要想進大公司,沒有豐富存儲過程經驗,是不行的。錯。存儲過程不僅僅適用於大型項目,對於中小型項目,使用存儲過程也是非常有必要的。其威力和優勢主要體現在:1.存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯,而一般 SQL語句每執行一次就編譯一次,所以使用存儲過程可提高資料庫執行速度。2.當對資料庫進行復雜操作時(如對多個表進行Update,Insert,Query,Delete時),可將此復雜操作用存儲過程封裝起來與資料庫提供的事務處理結合一起使用。這些操作,如果用程序來完成,就變成了一條條的 SQL語句,可能要多次連接資料庫。而換成存儲,只需要連接一次資料庫就可以了。3.存儲過程可以重復使用,可減少資料庫開發人員的工作量。4.安全性高,可設定只有某此用戶才具有對指定存儲過程的使用權。存儲過程的缺點1:調試麻煩,但是用 PL/SQL Developer 調試很方便!彌補這個缺點。 2:移植問題,資料庫端代碼當然是與資料庫相關的。但是如果是做工程型項目,基本不存在移植問題。 3:重新編譯問題,因為後端代碼是運行前編譯的,如果帶有引用關系的對象發生改變時,受影響的存儲過程、包將需要重新編譯(不過也可以設置成運行時刻自動編譯)。4:如果在一個程序系統中大量的使用存儲過程,到程序交付使用的時候隨著用戶需求的增加會導致數據結構的變化,接著就是系統的相關問題了,最後如果用戶想維護該系統可以說是很難很難、而且代價是空前的。維護起來更加麻煩!
問題三:oracle中的存儲過程,有什麼作用,以及怎麼在代碼中使用? 樓上也不知道從哪扒下來的,一看LZ就是初學,舉點例子不行嗎?
比如建立個測試表
create table test(id int,name varchar2(10),counts int); insert into test values (1,'張三',100);insert into test values (2,'李四',200); mit;
現在給你出個題目是
查詢所有人加在一起的counts是多少
創建存儲過程
create or replace p_test --創建存儲過程,asv_counts int;--定義變數begin --開始select sum(counts) into v_counts from test;--將得到的結果放到變數里DBMS_OUTPUT.PUT_LINE(v_counts);--將結果列印輸出end;--結束
執行這種不帶輸入參數的
begin p_test;end;
然後你檢查下結果
再給你創建一個帶輸入參數的
題目是,查詢id為1的人名是什麼
create or replace p_test1(v_id int)asv_name varchar2(10);beginselect name into v_name from test where id=v_id;DBMS_OUTPUT.PUT_LINE(v_name);end;
執行時這樣
beginp_test1(1);end;
第2個我沒給你寫注釋,你看你自己應該能理解吧
補充一下,存儲過程不一定只是執行查詢,也可以做刪除或者修改等sql語句,總體來說就是幾個或N個sql語句的 *** ,來完成系統內某些特定的需求,這些需求可以是一個sql搞定的,也可以是多個sql組合的
問題四:SQL 存儲過程建立和使用方法? Sql Server的存儲過程是一個被命名的存儲在伺服器上的Transacation-Sql語句 *** ,是封裝重復性工作的一種方法,它支持用戶聲明的變數、條件執行和其他強大的編程功能。 存儲過程相對於其他的資料庫訪問方法有以下的優點: (1)重復使用。存儲過程可以重復使用,從而可以減少資料庫開發人員的工作量。 (2)提高性能。存儲過程在創建的時候就進行了編譯,將來使用的時候不用再重新編譯。一般的SQL語句每執行一次就需要編譯一次,所以使用存儲過程提高了效率。 (3)減少網路流量。存儲過程位於伺服器上,調用的時候只需要傳遞存儲過程的名稱以及參數就可以了,因此降低了網路傳輸的數據量。 (4)安全性。參數化的存儲過程可以防止SQL注入式的攻擊,而且可以將Grant、Deny以及Revoke許可權應用於存儲過程。 存儲過程一共分為了三類:用戶定義的存儲過程、擴展存儲過程以及系統存儲過程。 其中,用戶定義的存儲過程又分為Transaction-SQL和CLR兩種類型。 Transaction-SQL 存儲過程是指保存的Transaction-SQL語句 *** ,可以接受和返回用戶提供的參數。 CLR存儲過程是指對.Net Framework公共語言運行時(CLR)方法的引用,可以接受和返回用戶提供的參數。他們在.Net Framework程序集中是作為類的公共靜態方法實現的。(本文就不作介紹了) 創建存儲過程的語句如下:Code
CREATE { PROC | PROCEDURE } [schema_name.] procere_name [ ; number ]
[ { @parameter [ type_schema_name. ] data_type }
[ VARYING ] [ = default ] [ [ OUT [ PUT ]
] [ ,n ]
[ WITH [ ,n ]
[ FOR REPLICATION ]
AS { [;][ n ] | }
[;]
::=
[ ENCRYPTION ]
[ REPILE ]
[ EXECUTE_AS_Clause ]
::=
{ [ BEGIN ] statements [ END ] }
::=
EXTERNAL NAME assembly_name.class_name.method_name [schema_name]: 代表的是存儲過程所屬的架構的名稱 例如: Create Schema yangyang8848
Go
Create Proc yangyang8848.AllGoods
As Select * From Master_Goods
Go 執行:Exec AllGoods 發生錯誤。 執......>>
問題五:資料庫中的存儲過程怎麼用 啊!!求解..... 10分 關鍵字:procere
例子:
SQL> create [or replace] procere procere_name is
begin
--開始執行
insert into test('10001','Visket');
end;
/
以上操作就能為test表添加一條信息
執行存儲過程procere用的命令是exec
記住存儲過程中,語句結尾一定要有分號
問題六:存儲過程是多用還是少用? 做項目的時候我們有時候會面臨一個選擇,我們到底是應該多寫存儲過程還是少寫存儲過程了?這個問題的爭論也是由來已久,在不同的公司以及不同的技術負責人那裡往往會得到不同的答案。在實際項目中我們最後所採取的方式,往往不外乎以下三種方式。
第一種方式是要求所有資料庫操作不使用任何的存儲過程,所有操作都採用標准sql語句來完成,即便是一個動作需要完成多步資料庫操作,也不使用任何存儲過程,而是在程序代碼中採用事務的方式來完成;第二種方式就是就要求所有的資料庫操作都用存儲過程封裝起來,哪怕是一個最簡單的insert 操作。在程序代碼看不到一行 sql語句,如果採用分工合作的方式,程序員甚至都可以不懂sql語法。第三種方式是一般相對簡單的資料庫操作採用標准sql語句來完成,一些相對比較復雜的商務邏輯用存儲過程來完成。
當然系統如果採用了hibernate或nhibernate之類的框架,不需要寫sql語句的時候,我想還是應該屬於第三種方式,因為在開發的時候hibernate框架允許我們在適當的時候,拋開其框架自己寫存儲過程和sql語句來完成資料庫操作。其實這三種方式都各有所長,也各有不足。
第一種方式是所有的資料庫操作都採用標准sql語句來完成的方式,在程序的執行效率上是肯定不如後面兩種方式,系統如果是一個大型的ERP,這種方式就是絕對不可取的。因為在開發基本結束後,系統如果需要優化或者希望得到優化時,那對開發人員來說就是一件非常麻煩的事情了,因為優化的重點基本上都是集中資料庫操作上,開發人員所能做的就是一個個sql語句去檢查,是不是還能進一步優化,尤其是一些相對比較復雜的查詢語句是我們所檢查的重點。分頁顯示就是一個典型的存儲過程提高程序效率的例子。如果使用存儲過程來進行分頁操作,就是利用存儲過程從系統中提取我們所需要的記錄集,分頁的效率就大大提高了。反過來如果我們不用存儲過程進行分頁操作,是利用sql語句的方式把所有記錄集都讀入內存中,然後再從內存中獲取我們所需要的記錄 *** ,這樣分頁效率自然就降低了。當然利用sql語句也能得到我們所需要的記錄,而不是所有記錄,但是那樣麻煩多了,不在我們討論范圍之內。
這種方式另外還有一個不足之處,一個系統或一個項目總會或多或少地存在有一些容易變化而又復雜的商務邏輯,如果把這些復雜的商務邏輯封裝到存儲過程中,商務邏輯的變化都只涉及存儲過程變化,而與程序代碼不 *** ,那麼不用存儲過程太可惜了。
這種方式雖然有不足,但是一旦採用這種方式的話,我們如果對該項目進行資料庫移植的時候,開發人員就會覺得當時的決策人是多麼的偉大與英明。而且我們知道access和mysql的以前版本是不提供存儲過程支持的,所有一些中小項目在這個方面的選擇往往也是不得已而為之。不用存儲過程有一個優點,調試代碼的時候沒有存儲過程可是要方便很多很多的哦,所以在很多很多的項目中都是採用標準的sql語句而不使用任何的存儲過程。這可是大多程序員用標准sql而不用存儲過程的直接原因,說白了,就是嫌麻煩。
第二種方式是所有的資料庫操作全部採用存儲過程封裝的方式,如果採用這種方式,程序的執行效率相對要高,尤其面對在一些復雜的商務邏輯時候,不僅在效率方面有明顯的提高,而且當商務邏輯發生變化時,我們開發人員做相應的修改的時候,往往都不用修改程序代碼,僅僅修改存儲過程就能滿足系統變化了。
還有一個好處就是當我們開發好的一個系統後,如果發現一種模式或語言在某些方面難以滿足需求時,我們就可以很快的用兩外一種語言來重新開發,那個時候就非常方便了。比如在02年中科院下屬的一個公司就用ASP開......>>
問題七:在SQL中存儲過程的一般語法是什麼? sql server存儲過程語法
存儲過程就是作為可執行對象存放在資料庫中的一個或多個SQL命令。
定義總是很抽象。存儲過程其實就是能完成一定操作的一組SQL語句,只不過這組語句是放在資料庫中的(這里我們只談SQL Server)。如果我們通過創建存儲過程以及在ASP中調用存儲過程,就可以避免將SQL語句同ASP代碼混雜在一起。這樣做的好處至少有三個:
第一、大大提高效率。存儲過程本身的執行速度非常快,而且,調用存儲過程可以大大減少同資料庫的交互次數。
第二、提高安全性。假如將SQL語句混合在ASP代碼中,一旦代碼失密,同時也就意味著庫結構失密。
第三、有利於SQL語句的重用。
在ASP中,一般通過mand對象調用存儲過程,根據不同情況,本文也介紹其它調用方法。為了方便說明,根據存儲過程的輸入輸出,作以下簡單分類:
1. 只返回單一記錄集的存儲過程
假設有以下存儲過程(本文的目的不在於講述T-SQL語法,所以存儲過程只給出代碼,不作說明):
/*SP1*/
CREATE PROCEDURE dbo.getUserList
as
set nocount on
begin
select * from dbo.[userinfo]
end
go
以上存儲過程取得userinfo表中的所有記錄,返回一個記錄集。通過mand對象調用該存儲過程的ASP代碼如下:
'**通過mand對象調用存儲過程**
DIM Mym,MyRst
Set Mym = Server.CreateObject(ADODB.mand)
Mym.ActiveConnection = MyConStr 'MyConStr是資料庫連接字串
Mym.mandText = getUserList '指定存儲過程名
Mym.mandType = 4 '表明這是一個存儲過程
Mym.Prepared = true '要求將SQL命令先行編譯
Set MyRst = Mym.Execute
Set Mym = Nothing
存儲嘩程取得的記錄集賦給MyRst,接下來,可以對MyRst進行操作。
在以上代碼中,mandType屬性表明請求的類型,取值及說明如下:
-1 表明mandText參數的類型無法確定
1 表明mandText是一般的命令類型
2 表明mandText參數是一個存在的表名稱
4 表明mandText參數是一個存儲過程的名稱
還可以通過Connection對象或Recordset對象調用存儲過程,方法分別如下:
'**通過Connection對象調用存儲過程**
DIM MyConn,MyRst
Set MyConn = Server.CreateObject(&qu......>>
問題八:如何使用Oracle存儲過程的一個簡單例子 樓主您好
---創建表
create table TESTTABLE
(
id1 VARCHAR2(12),
name VARCHAR2(32)
)
select t.id1,t.name from TESTTABLE t
insert into TESTTABLE (ID1, NAME)
values ('1', 'zhangsan');
insert into TESTTABLE (ID1, NAME)
values ('2', 'lisi');
insert into TESTTABLE (ID1, NAME)
values ('3', 'wangwu');
insert into TESTTABLE (ID1, NAME)
values ('4', 'xiaoliu');
insert into TESTTABLE (ID1, NAME)
values ('5', 'laowu');
---創建存儲過程
create or replace procere test_count
as
v_total number(1);
begin
select count(*) into v_total from TESTTABLE;
DBMS_OUTPUT.put_line('總人數:'||v_total);
end;
--准備
--線對scott解鎖:alter user scott account unlock;
--應為存儲過程是在scott用戶下。還要給scott賦予密碼
---alter user scott identified by tiger;
---去命令下執行
EXECUTE test_count;
----在ql/spl中的sql中執行
begin
-- Call the procere
test_count;
end;
create or replace procere TEST_LIST
AS
---是用游標
CURSOR test_cursor IS select t.id1,t.name from TESTTABLE t;
begin
for Test_record IN test_cursor loop---遍歷游標,在列印出來
DBMS_OUTPUT.put_line(Test_record.id1||Test_record.name);
END LOOP;
test_count;--同時執行另外一個存儲過程(TEST_LIST中包含存儲過程test_count)
end;
-----執行存儲過程TEST_LIST
begin
TEST_LIST;
END;
---存儲過程的參數
---IN 定義一個輸入參數變數,用於傳遞參數給存儲過程
--OUT 定義一個輸出參數變數,用於從存儲過程獲取數據
---IN OUT 定義一個輸入、輸出參數變數,兼有以上兩者的功能
......>>
問題九:如何使用sql語句查看存儲過程 --下面這條語句可以查看存儲過程具體代碼exec sp_helptext 存儲過程名--下面這條語句查看資料庫中有哪些存儲過程select * from sysobjects where type='P'
問題十:存儲過程中怎麼使用row 一般分為十種情況,每種語法各不相同: 1、 創建語法create proc | procere pro_name [{@參數數據類型} [=默認值] [output], {@參數數據類型} [=默認值] [output], .... ]as SQL_statements2、 創建不帶參數存儲過程--創建存儲過程if (exists (select * from sys.objects where name = 'proc_get_student')) drop proc proc_get_studentgocreate proc proc_get_studentas select * from student;--調用、執行存儲過程exec proc_get_student;3、 修改存儲過程--修改存儲過程alter proc proc_get_studentasselect * from student;4、 帶參存儲過程--帶參存儲過程if (object_id('proc_find_stu', 'P') is not null) drop proc proc_find_stugocreate proc proc_find_stu(@startId int, @endId int)as select * from student where id between @startId and @endIdgoexec proc_find_stu 2, 4;5、 帶通配符參數存儲過程--帶通配符參數存儲過程if (object_id('proc_findStudentByName', 'P') is not null) drop proc proc_findStudentByNamegocreate proc proc_findStudentByName(@name varchar(20) = '%j%', @nextName varchar(20) = '%')as select * from student where name like @name and name like @nextName;goexec proc_findStudentByName;exec proc_findStudentByName '%o%', 't%';6、 帶輸出參數存儲過程if (object_id('proc_getStudentRecord', 'P') is not null) drop proc proc_getStudentRecordgocreate proc proc_getStudentRecord( @id int, --默認輸入參數 @name varchar(20) out, --輸出參數 @age varchar(20) output--輸入輸出參數)as select @name = name, @age = age from student where id = @id and sex = @age;go-- declare @id int, @name varchar(20), @temp varchar(20)......>>
⑼ Hibernate中CriteriaQuery可以使用原生sql作為排序條件么
Hibernate對原生SQL查詢的支持和控制是通過SQLQuery介面虧喚芹實現的,這種銷畢方式彌補了HQL、Criterion查詢的不足,在操作和使用上往往更加的自由和靈活,如果使用得當,資料庫操作的效率還會得到不同程度的提升。
Hibernate對原生
SQL查詢的支持和控制是通過SQLQuery介面實現的。通過Session介面,我們能夠很方便的創建一個SQLQuery(SQLQuery是一個介面,在Hibernate4.2.2之前,默認返回的是SQLQuery的實現類——SQLQueryImpl對象,在下文中出現的SQLQuery如非註明,都是指該子類)對象來進行原生SQL查詢:
session.createSQLQuery(String sql);
SQLQuery實現了Query介面,因此你可以使用Query介面中提供的API來獲取數據。
最簡單的示例
//獲取所有查詢結果
session.createSQLQuery("select * from note").list();
//僅獲取第一條結果
session.createSQLQuery("select * from note where id = 1").uniqueResult();
使用預處理SQL
預處理SQL的好處自然不必多說,除了眾所周知的能夠防止SQL注入攻擊外,還能夠在一定程度上提高SQL的查詢效率。SQLQuery提供了眾多的介面來分別設置不同類型的參數,諸如setBigDecimal、setBinary、setDouble等,詳參SQLQuery的JavaDoc,此處不再贅述。這里僅重點說一下通用的SQL參數設置介面setParameter。
如下代碼示範了如何使用SQLQuery執行預處理SQL:
SQLQuery query = session.createSQLQuery("select * from note where id = ?");
//設置第一個參數的值為12,即查詢ID=12的note
query.setParameter(0, 12);
List list = query.list();
...
這里需要註明一點,無論是通過不同類型參數的設置介面來設置SQL參數,還是通過setParameter來設置參數,下標都是從0開始的,而不是從1開始的!
使用自定義的結果轉換器處理查詢結果
SQLQuery
介面預留了setResultTransformer介面以實現使用用戶自定義的ResultTransformer結果集轉換器處理查詢結果。
ResultTransformer介面非常簡單,只有兩個方法,分別用來轉換單行數據和所有結果數據。經過自定義ResultTransformer生成的實體,並未加入Session,因此是非受管實體。
如下代碼,示範了如何將單行數據裝入LinkedHashMap對象中:
query.setResultTransformer(new ResultTransformer() {
@Override
public Object transformTuple(Object[] values, String[] columns) {
Map<String, Object> map = new LinkedHashMap<String, Object>(1);
int i = 0;
for(String column : columns){
map.put(column, values[i++]);
}
return map;
}
@Override
public List transformList(List list) {
return list;
}
});
如果不設置自定義的ResultTransformer轉換器,則Hibernate將每行返回結果的數據按照結果列的順序裝入Object數組中。
這里介紹一個工具類:Transformers,它提供了一些常用的轉換器,能夠幫助我們快速轉換結果集,如Transformers.aliasToBean(Note.class)能夠將查詢結果依別名注入到Note實體中。
使用標量
使用鏈沖SQLQuery執行原生SQL時,Hibernate會使用ResultSetMetadata來判定返回的標量值的實際順序和類型。如果要避免過多的使用ResultSetMetadata,或者只是為了更加明確的指名返回值,可以使用addScalar()。
session.createSQLQuery("select * from note where id = 1")
.addScalar("id", LongType.INSTANCE)
.addScalar("name", StringType.INSTANCE)
.addScalar("createtime", DateType.INSTANCE);
這個查詢指定了SQL查詢字元串,要返回的欄位和類型.它仍然會返回Object數組,但是此時不再使用ResultSetMetdata,而是明確的將id,name和
createtime按照Long,
String和Date類型從resultset中取出。同時,也指明了就算query是使用*來查詢的,可能獲得超過列出的這三個欄位,也僅僅會返回這三個欄位。
對全部或者部分的標量值不設置類型信息也是可以的:
session.createSQLQuery("select * from note where id = 1")
.addScalar("id")
.addScalar("name")
.addScalar("createtime", DateType.INSTANCE);
沒有被指定類型的欄位將仍然使用ResultSetMetdata獲取其類型。注意,欄位不區分大小寫,同時不能夠指定不存在的欄位!
關於從ResultSetMetaData返回的java.sql.Types是如何映射到Hibernate類型,是由方言(Dialect)控制的。假若某個指定的類型沒有被映射,或者不是你所預期的類型,你可以通過Dialet的registerHibernateType調用自行定義。
如果僅指定了一個scalar,那麼...
Date createTime = (Date)session.createSQLQuery("select * from note where id = 1")
.addScalar("createtime", DateType.INSTANCE)
.uniqueResult();
如果我們的SQL語句使用了聚合函數,如count、max、min、avg等,且返回結果僅一個欄位,那麼Hibernate提供的這種提取標量結果的方式就非常便捷了。
實體查詢
上面的查詢都是返回標量值的,也就是從resultset中返回的「裸」數據。下面展示如何通過addEntity()讓原生查詢返回實體對象。
session.createSQLQuery("select * from note where id = 1").addEntity(Note.class);
session.createSQLQuery("select id,name,createtime from note where id = 1").addEntity(Note.class);
這個查詢指定SQL查詢字元串,要返回的實體。假設Note被映射為擁有id,name和createtime三個欄位的類,以上的兩個查詢都返回一個List,每個元素都是一個Note實體。
假若實體在映射時有一個many-to-one的關聯指向另外一個實體,在查詢時必須也返回那個實體,否則會導致發生一個"column
not found"的資料庫錯誤。這些附加的欄位可以使用*標注來自動返回,但我們希望還是明確指明,看下面這個具有指向Dog的many-to-one的例子:
session.createSQLQuery("select id,note,createtime,author from note where id = ?").addEntity(Note.class);
author欄位即為Note實體和Author實體的關聯欄位,只需在查詢時得到該欄位的值,Hibernate即可使用該值找到對應的關聯實體。如上例中,note.getAuthor()即可返回當前Note所屬的Author對象。
處理關聯和集合類
通過提前抓取將Author連接獲得,而避免初始化proxy帶來的額外開銷也是可能的。這是通過addJoin()方法進行的,這個方法可以讓你將關聯或集合連接進來。
session.createSQLQuery("select {note.*}, {author.*} from note note, user author where note.author = author.id")
.addEntity("note", Note.class)
.addJoin("author", "note.author");
上面的例子是多對一的關聯查詢,反過來做一對多的關聯查詢也是可以的。如下的例子中,author.notes表示該用戶發表的所有日記(Note),Set集合類型:
session.createSQLQuery("select {author.*},{note.*} from note note, user author where author.id = ? and note.author = author.id")
.addEntity("author", User.class)
.addJoin("note", "author.notes");
注意:join查詢會在每行返回多個實體對象,處理時需要注意。
別名和屬性引用
假若SQL查詢連接了多個表,同一個欄位名可能在多個表中出現多次,這會導致SQL錯誤。不過在我們可以通過使用佔位符來完美地解決這一問題。
其實在上例中已經用到了佔位符:
session.createSQLQuery("select {note.*}, {author.*} from note note, user author where note.author = author.id")
.addEntity("note", Note.class)
.addJoin("author", "note.author");
這個查詢指明SQL查詢語句,其中包含佔位附來讓Hibernate注入欄位別名,查詢並返回的實體。
上面使用的{note.*}和{author.*}標記是作為「所有屬性」的簡寫形式出現的,當然你也可以明確地羅列出欄位名。但如下的範例代碼中我們讓Hibernate來為每個屬性注入SQL欄位別名,欄位別名的佔位符是表別名
+ . + 屬性名。
注意:屬性名區分大小寫,而且不能夠在where子句中使用佔位符。
SQLQuery query = session.createSQLQuery("select note.id as {note.id},note as {note.note},createtime as {note.createTime},author as {note.author}, {author.*} from note, user author where note.id = ? and note.author = author.id");
query.addEntity("note", Note.class);
query.addJoin("author", "note.author");
大多數情況下,上面的別名注入方式可以滿足需要,但在使用更加復雜的映射,比如復合屬性、通過標識符構造繼承樹,以及集合類等等情況下,則需要更加復雜的別名注入方式。
下表列出了使用別名注射參數的不同方式:
⑽ struts2怎麼防止sql注入
sql注入大家都不陌生,是一種常見的攻擊方式,攻擊者在界面的表單信息或url上輸入一些奇怪的sql片段,例如「or 『1』=』1』」這樣的語句,有可能入侵參數校驗不足的應用程序。所以在我們的應用中需要做一些工作,來防備這樣的攻擊方式。在一些安全性很高的應用中,比如銀行軟體,經常使用將sql語句全部替換為存儲過程這樣的方式,來防止sql注入,這當然是一種很安全的方式,但我們平時開發中,可能不需要這種死板的方式。
一起jquery,17jquery
mybatis框架作為一款半自動化的持久層框架,其sql語句都要我們自己來手動編寫,這個時候當然需要防止sql注入。其實Mybatis的sql是一個具有「輸入+輸出」功能,類似於函數的結構,如下:
一起jquery,17jquery
<</span>select id="getBlogById" resultType="Blog" parameterType=」int」>
17jquery.com
select id,title,author,content 內容來自17jquery
from blog where id=#{id} 一起jquery,17jquery
</</span>select> 內容來自17jquery
這里,parameterType標示了輸入的參數類型,resultType標示了輸出的參數類型。回應上文,如果我們想防止sql注入,理所當然地要在輸入參數上下功夫。上面代碼中高亮部分即輸入參數在sql中拼接的部分,傳入參數後,列印出執行的sql語句,會看到sql是這樣的:
內容來自17jquery
select id,title,author,content from blog where id = ?
一起jquery,17jquery
不管輸入什麼參數,列印出的sql都是這樣的。這是因為mybatis啟用了預編譯功能,在sql執行前,會先將上面的sql發送給資料庫進行編譯,執行時,直接使用編譯好的sql,替換佔位符「?」就可以了。因為sql注入只能對編譯過程起作用,所以這樣的方式就很好地避免了sql注入的問題。
一起jquery,17jquery
mybatis是如何做到sql預編譯的呢?其實在框架底層,是jdbc中的PreparedStatement類在起作用,PreparedStatement是我們很熟悉的Statement的子類,它的對象包含了編譯好的sql語句。這種「准備好」的方式不僅能提高安全性,而且在多次執行一個sql時,能夠提高效率,原因是sql已編譯好,再次執行時無需再編譯。 一起jquery,17jquery
話說回來,是否我們使用mybatis就一定可以防止sql注入呢?當然不是,請看下面的代碼:
17jquery.com
<</span>select id="orderBlog" resultType="Blog" parameterType=」map」>
17jquery.com
select id,title,author,content 一起jquery,17jquery
from blog order by ${orderParam}
17jquery.com
</</span>select>
內容來自17jquery
仔細觀察,內聯參數的格式由「#{xxx}」變為了${xxx}。如果我們給參數「orderParam」賦值為」id」,將sql列印出來,是這樣的:
內容來自17jquery
select id,title,author,content from blog order by id
一起jquery,17jquery
顯然,這樣是無法阻止sql注入的。在mybatis中,」${xxx}」這樣格式的參數會直接參與sql編譯,從而不能避免注入攻擊。但涉及到動態表名和列名時,只能使用「${xxx}」這樣的參數格式,所以,這樣的參數需要我們在代碼中手工進行處理來防止注入。 一起jquery,17jquery
結論:在編寫mybatis的映射語句時,盡量採用「#{xxx}」這樣的格式。若不得不使用「${xxx}」這樣的參數,要手工地做好過濾工作,來防止sql注入攻擊。