參數綁定

參數綁定:
  Hibernate中對動態查詢參數綁定提供了豐富的支持,那麼什麼是查詢參數動態綁定呢?其實若是咱們熟悉傳統JDBC編程的話,咱們就不難理解查詢參數動態綁定,以下代碼傳統JDBC的參數綁定:
  PrepareStatement pre=connection.prepare(「select * from User where user.name=?」);
  pre.setString(1,」lyp」);
  ResultSet rs=pre.executeQuery();
  在Hibernate中也提供了相似這種的查詢參數綁定功能,並且在Hibernate中對這個功能還提供了比傳統JDBC操做豐富的多的特性,在Hibernate中共存在4種參數綁定的方式,下面咱們將分別介紹:
  A、 按參數名稱綁定:
  在HQL語句中定義命名參數要用」:」開頭,形式以下:
  Query query=session.createQuery(「from User user where user.name=:customernameanduser:customerage=:age 」);
  query.setString(「customername」,name);
  query.setInteger(「customerage」,age);

  上面代碼中用:customername和:customerage分別定義了命名參數customername和customerage,而後用Query接口的setXXX()方法設定名參數值,setXXX()方法包含兩個參數,分別是命名參數名稱和命名參數實際值。
  B、 按參數位置邦定:
  在HQL查詢語句中用」?」來定義參數位置,形式以下:
  Query query=session.createQuery(「from User user where user.name=? and user.age =? 」);
  query.setString(0,name);
  query.setInteger(1,age);

  一樣使用setXXX()方法設定綁定參數,只不過這時setXXX()方法的第一個參數表明邦定參數在HQL語句中出現的位置編號(由0開始編號),第二個參數仍然表明參數實際值。
  注:在實際開發中,提倡使用按名稱邦定命名參數,由於這不但能夠提供很是好的程序可讀性,並且也提升了程序的易維護性,由於當查詢參數的位置發生改變時,按名稱邦定名參數的方式中是不須要調整程序代碼的。
  C、 setParameter()方法:
  在Hibernate的HQL查詢中能夠經過setParameter()方法邦定任意類型的參數,以下代碼:
  String hql=」from User user where user.name=:customername 」;
  Query query=session.createQuery(hql);
  query.setParameter(「customername」,name,Hibernate.STRING);
  如上面代碼所示,setParameter()方法包含三個參數,分別是命名參數名稱,命名參數實際值,以及命名參數映射類型。對於某些參數類型setParameter()方法能夠根據參數值的Java類型,猜想出對應的映射類型,所以這時不須要顯示寫出映射類型,像上面的例子,能夠直接這樣寫:
  query.setParameter(「customername」,name);可是對於一些類型就必須寫明映射類型,好比java.util.Date類型,由於它會對應Hibernate的多種映射類型,好比Hibernate.DATA或者Hibernate.TIMESTAMP。
  D、 setProperties()方法:(setEntity())
  在Hibernate中能夠使用setProperties()方法,將命名參數與一個對象的屬性值綁定在一塊兒,以下程序代碼:
  Customer customer=new Customer();
  customer.setName(「lyp」);
  customer.setAge(80);
  Query query=session.createQuery(「from Customer c where c.name=:name and c.age=:age 」);
  query.setProperties(customer);
  setProperties()方法會自動將customer對象實例的屬性值匹配到命名參數上,可是要求命名參數名稱必需要與實體對象相應的屬性同名
  這裏還有一個特殊的setEntity()方法,它會把命名參數與一個持久化對象相關聯,以下面代碼所示:
  Customer customer=(Customer)session.load(Customer.class,」1」);
  
Query query=session.createQuery(「from Order order where order.customer=:customer 」);
  query. setEntity(「customer」,customer);
  
List list=query.list();
  上面的代碼會生成相似以下的SQL語句:
  Select * from order where customer_ID=’1’;
  E、 使用綁定參數的優點:
  咱們爲何要使用綁定命名參數?任何一個事物的存在都是有其價值的,具體到綁定參數對於HQL查詢來講,主要有如下兩個主要優點:
  ①、 能夠利用數據庫實施性能優化,由於對Hibernate來講在底層使用的是PrepareStatement來完成查詢,所以對於語法相同參數不一樣的SQL語句,能夠充分利用預編譯SQL語句緩存,從而提高查詢效率。
  ②、 能夠防止SQL Injection安全漏洞的產生:
  SQL Injection是一種專門針對SQL語句拼裝的攻擊方式,好比對於咱們常見的用戶登陸,在登陸界面上,用戶輸入用戶名和口令,這時登陸驗證程序可能會生成以下的HQL語句:
  「from User user where user.name=’」+name+」’ and user.password=’」+password+」’ 」
  這個HQL語句從邏輯上來講是沒有任何問題的,這個登陸驗證功能在通常狀況下也是會正確完成的,可是若是在登陸時在用戶名中輸入」zhaoxin or ‘x’=’x」,這時若是使用簡單的HQL語句的字符串拼裝,就會生成以下的HQL語句:
  「from User user where user.name=’lyp’ or ‘x’=’x’ and user.password=’admin’ 」;
  顯然這條HQL語句的where字句將會永遠爲真,而使用戶口令的做用失去意義,這就是SQL Injection攻擊的基本原理。
  而使用綁定參數方式,就能夠妥善處理這問題,當使用綁定參數時,會獲得下面的HQL語句:
  from User user where user.name=’’lyp’’ or ‘’x=’’x’’ ‘ and user.password=’admin’;因而可知使用綁定參數會將用戶名中輸入的單引號解析成字符串(若是想在字符串中包含單引號,應使用重複單引號形式),因此參數綁定可以有效防止SQL Injection安全漏洞。java

相關文章
相關標籤/搜索