筆記:學習JavaWeb開發第二課

1. 中文返回前臺頁面會出現亂碼html

若是隻在Servlet中設置上面的語句,則會出現以下狀況(動態內容爲亂碼,靜態內容正常)java

req.setCharacterEncoding("utf-8");

因此在前臺頁面中也指定一下編碼mysql

<%@ page contentType="text/html;charset=UTF-8" language="java"%>

這樣前臺頁面就能顯示正常了sql


2. 數據庫查詢中文亂碼數據庫

數據庫鏈接方式緩存

private final String conn_url = "jdbc:mysql://localhost:3306/weixinmybatis";
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(conn_url, "root", "root");

在使用PreparedStatement的setString(int, String)方法的時候,String若是是中文,就會變成?,致使查詢失敗安全

StringBuilder sql = new StringBuilder("select ID,COMMAND,DESCRIPTION,CONTENT from MESSAGE where 1=1");
sql.append("and COMMAND=?");
PreparedStatement ps = conn.prepareStatement(sql.toString());
ps.setString(1, "中文");

生成的查詢語句就變成了mybatis

select ID,COMMAND,DESCRIPTION,CONTENT from MESSAGE where 1=1 and COMMAND='??'

最終解決方案是在鏈接數據庫的時候設置編碼,即在conn_url中添加編碼app

private final String conn_url = "jdbc:mysql://localhost:3306/weixinmybatis?characterEncoding=utf8";


3. 插播一點其餘內容(從其餘地方找來的)性能

3.1 PreparedStatement和Statement的區別

<1>PreparedStatement接口繼承Statement,PreparedStatement實例包含已編譯的SQL語句,因此其執行速度要快於Statement對象。

<2>做爲Statement的子類,PreparedStatement繼承了Statement的全部功能。三種方法execute、executeQuery和executeUpdate已被更改以使之再也不須要參數

<3>在JDBC應用中,若是你已是稍有水平開發者,你就應該始終以PreparedStatement代替Statement.也就是說,在任什麼時候候都不要使用Statement。基於以下緣由:

        |- 代碼的可讀性和可維護性。雖然用PreparedStatement來代替Statement會使代碼多出幾行,但這樣的代碼不管從可讀性仍是可維護性上來講,都比直接用Statement的代碼高不少檔次

//stmt是Statement對象實例
stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");

//prestmt是 PreparedStatement 對象實例
perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
perstmt.setString(1,var1);
perstmt.setString(2,var2);
perstmt.setString(3,var3);
perstmt.setString(4,var4);
perstmt.executeUpdate(); 
//對於第一種方法,別說其餘人去讀你的代碼,就是你本身過一段時間再去讀,都會以爲傷心。

        |- PreparedStatement盡最大可能提升性能。語句在被DB的編譯器編譯後的執行代碼被緩存下來,那麼下次調用時只要是相同的預編譯語句就不須要編譯,只要將參數直接傳入編譯過的語句執行代碼中(至關於一個涵數)就會獲得執行。這並非說只有一個Connection中屢次執行的預編譯語句被緩存,而是對於整個DB中,只要預編譯的語句語法和緩存中匹配。那麼在任什麼時候候就能夠不須要再次編譯而能夠直接執行。而statement的語句中,即便是相同一操做,而因爲每次操做的數據不一樣因此使整個語句相匹配的機會極小,幾乎不太可能匹配,好比:

insert into tb_name (col1,col2) values ('11','22');
insert into tb_name (col1,col2) values ('11','23');
//即便是相同操做但由於數據內容不同,因此整個個語句自己不能匹配,沒有緩存語句的意義。事實是沒有數據庫會對普通語句編譯後的執行代碼緩存。
//固然並非因此預編譯語句都必定會被緩存,數據庫自己會用一種策略,好比使用頻度等因素來決定何時再也不緩存已有的預編譯結果。以保存有更多的空間存儲新的預編譯語句。

        |- 最重要的一點是極大地提升了安全性。即便到目前爲止,仍有一些人連基本的惡義SQL語法都不知道。

String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
//若是咱們把[' or '1' = '1]做爲varpasswd傳入進來.用戶名隨意,看看會成爲何?
//而若是你使用預編譯語句.你傳入的任何內容就不會和原來的語句發生任何匹配的關係。
//只要全使用預編譯語句,你就用不着對傳入的數據作任何過慮。而若是使用普通的statement,有可能要對drop等作費盡心機的判斷和過慮,
相關文章
相關標籤/搜索