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等作費盡心機的判斷和過慮,