麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 開發 > 綜合 > 正文

[置頂] 關于JDBC和一些持久化框架SQL預編譯的理解整理

2024-07-21 02:51:19
字體:
來源:轉載
供稿:網友

預編譯就是把格式固定的SQL編譯后,存放在內存池中即數據庫緩沖池,當我們再次執行相同的SQL語句時就不需預編譯的過程。

1.

JDBC的話使用PReparedStatement代替Statement實現預編譯,會加快訪問數據庫的速度

使用PreparedStatement對象可以大大提高代碼的可讀性和可維護性

使用PreparedStatement對象的方法

String  sql ="insert into student values(null,?,?)";

java.sql.PreparedStatement pstmt=conn.preparedStatement(sql);

pstmt.setString(1,var1);pstmt.setString(2,var2);pstmt.executeUpdate();

使用占位符?代替

將參數與SQL語句分離出來,這樣就可以方便對程序的更改和延續,同樣,也可以減少不必要的錯誤。

最后就是安全性了。以下轉自百度文庫:傳遞給PreparedStatement對象的參數可以被強制進行類型轉換,使開發人員可以確保在插入或查詢數據時與底層的數據庫格式匹配。

2.

首先Mybatis,指定了傳入的參數類型parameterType來防止Sql注入,

另外自帶預編譯功能,sql注入只能對編譯過程起作用,

<select id=“getBlogById“ resultType=“Blog“ parameterType=”int”><br>       select id,title,author,content from blog where id=#{id}</select>

其實在框架底層,是jdbc中的PreparedStatement類在起作用,

另外內聯參數的格式由“#{xxx}”變為了${xxx}是不能防止SQL注入的

<select id=“orderBlog“ resultType=“Blog“ parameterType=”map”>       select id,title,author,content from blog order by ${orderParam} </select>在mybatis中,”${xxx}”這樣格式的參數會直接參與sql編譯,從而不能避免注入攻擊。但涉及到動態表名和列名時,只能使用“${xxx}”這樣的參數格式,所以,這樣的參數需要我們在代碼中手工進行處理來防止注入。

如何處理?

對于like語句,難免要使用$寫法,

 1. 對于Oracle可以通過'%'||'#param#'||'%'避免;

 2. 對于MySQL可以通過CONCAT('%',#param#,'%')避免;

 3. MSSQL中通過'%'+#param#+'% 。 

如下3種SQL語句:

123mysql: select * from user where name like concat('%',#name #,'%')      oracle: select * from user where name like '%'||#name #||'%'      SQL Server:select * from user where name like '%'+#name #+'%

3.Hibernate關于實現預編譯的SQL寫法,有四種

 A、 按參數名稱綁定:  在HQL語句中定義命名參數要用”:”開頭,形式如下:  Query query=session.createQuery(“from User user where user.name=:customername and user: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(“pansl”);  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=’zhaoxin’ or ‘x’=’x’ and user.password=’admin’ ”;  顯然這條HQL語句的where字句將會永遠為真,而使用戶口令的作用失去意義,這就是SQL Injection攻擊的基本原理。  而使用綁定參數方式,就可以妥善處理這問題,當使用綁定參數時,會得到下面的HQL語句:  from User user where user.name=’’zhaoxin’’ or ‘’x=’’x’’ ‘ and user.password=’admin’;由此可見使用綁定參數會將用戶名中輸入的單引號解析成字符串(如果想在字符串中包含單引號,應使用重復單引號形式),所以參數綁定能夠有效防止SQL Injection安全漏洞。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 日韩精品中文字幕一区二区三区 | 国内精品一级毛片免费看 | 国产精品久久久毛片 | 亚洲精品久久久久www | 黄色成人av在线 | 欧美a黄| 一区二区三区日韩在线观看 | 视频一区国产精品 | 在线成人免费视频 | www国产成人免费观看视频 | 澳门一级淫片免费视频 | 最新av免费网址 | 中文字幕欧美亚洲 | 国产91久久精品一区二区 | 久久av免费观看 | 操碰| 日韩视频在线观看免费 | 国产午夜精品一区二区三区嫩草 | 国毛片 | 久久在线免费视频 | 免费在线观看毛片视频 | 国产亚洲精品综合一区 | 久久精品视频7 | 国产成人精品区一区二区不卡 | 国产精品区一区二区三区 | 黄色片免费看看 | 娇喘视频在线观看 | 精品国产一区二区三区四区在线 | 伊人在线视频 | 亚洲午夜久久久精品一区二区三区 | 2019中文字幕在线播放 | 欧美一级毛片欧美一级成人毛片 | 欧美色性 | 成人激情视频网 | 久久久一区二区 | 97久久精品一区二区三区观看 | 久久另类视频 | 久久久成人动漫 | 牛牛a级毛片在线播放 | 特级黄一级播放 | 久久精品亚洲一区 |