刚刚学了 JSP 和 MySQL,兴致勃勃的做了一个博客系统,现将实现要点总结如下:
一、编写数据库管理类,实现数据库操作安全、便捷
如果没有数据库管理类,我们就需要在每个 JSP 文件中使用多行代码重复的连接数据库,繁琐,而且不易改动,也不符合 JAVA 的封装特性。于是,我写了一个数据库工具类,管理数据库操作,代码如下:
1: package com.mzule.db;
2:
3: import java.sql.Connection;
4: import java.sql.DriverManager;
5: import java.sql.ResultSet;
6: import java.sql.SQLException;
7:
8: public class DB {
9: private Connection cnn;
10:
11: /**
12: * 获得数据库连接
13: *
14: */
15: private void getConnection() {
16: try {
17: Class.forName("com.mysql.jdbc.Driver");
18: cnn = DriverManager
19: .getConnection("jdbc:mysql://localhost:3306/myblog?user=root&password=nevertellyou");
20: } catch (ClassNotFoundException e) {
21: e.printStackTrace();
22: } catch (SQLException e) {
23: e.printStackTrace();
24: }
25: }
26:
27: /**
28: * 断开连接
29: *
30: */
31: private void close() {
32: if (cnn != null) {
33: try {
34: cnn.close();
35: } catch (SQLException e) {
36: e.printStackTrace();
37: }
38: }
39: }
40:
41: /**
42: * 执行数据库查询
43: *
44: * @param sql
45: * @return ResultSet
46: */
47: public static ResultSet executeQuery(String sql) {
48: DB db = new DB();
49: if (db.cnn == null) {
50: db.getConnection();
51: }
52: try {
53: return db.cnn.createStatement().executeQuery(sql);
54: } catch (SQLException e) {
55: e.printStackTrace();
56: return null;
57: } finally {
58: db.close();
59: db.cnn = null;
60: }
61: }
62:
63: /**
64: * 执行数据库更新
65: *
66: * @param sql
67: * @return -1 代表更新失败
68: */
69: public static int executeUpdate(String sql) {
70: DB db = new DB();
71: if (db.cnn == null) {
72: db.getConnection();
73: }
74: try {
75: return db.cnn.createStatement().executeUpdate(sql);
76: } catch (SQLException e) {
77: e.printStackTrace();
78: return -1;
79: } finally {
80: db.close();
81: db.cnn = null;
82: }
83: }
84: }
此类中只有两个对外公开的方法:executeQuery(String) 和 executeUpdate(String),这两个方法都是静态的,方便调用。以前是把整个类的所有方法和属性都设定为静态的,后来想想,这样不妥,要不又很多个客户访问页面就会共用一个 connection ,就会引发杯具。
二、设定 request.setCharacterEncoding("GBK"); 避免页面乱码
这个乱码问题困扰了我很久,就是在每次发布中文博客得到的都是乱码,当时以为是数据库安装的时候没有设定好编码造成的,还专门写了一个转码方法:
1: /**转码,由 UTF-8 转到 GBK
2: * @param str
3: * @return String encoding with GBK
4: */
5: public static String toGBK(String str){
6: try {
7: return new String(str.getBytes("UTF-8"),"GBK");
8: } catch (UnsupportedEncodingException e) {
9: e.printStackTrace();
10: return null;
11: }
12: }
后来发现在数据库中就是可以插入中文的,自己郁闷的好久。想起来在 Servlet 中的那句 request.setCharacterEncoding("GBK");,兴奋的试试,结果还是不行,崩溃。其实这里是我的犯低级错误了。 request.setCharacterEncoding("GBK"); 应该写在第一个 request.getParameter() 的前面,我没看到我的第一个 request.getParameter() 语句竟然在 if() 语句中,耽误了好久。
三、MySQL 的 auto_increment
数据库中的表一般都要求要有主键,方便管理,一般都选择一个不断增长的 id 作为主键,在 MySQL 中可以设定自动递增的,就是 auto_increment ,代码参考如下:
1: CREATE TABLE mytable (
2: id INT PRIMARY KEY AUTO_INCREMENT,
3: --code omitted here
4: )
为了各个数据库系统之间的兼容性,我们还可以使用 JAVA 代码实现递增,就是得到 id 的最大值,再加 1。或者使用静态域,使用静态域貌似还得固化数据。
四、避免在 URL 上面传递中文
网页中经常会用这样的情形,首先是一个文章标题为名的超级链接,点击这个超级链接会得到文章的全部内容,是使用下面类似的代码实现的:
1: <a href=<%="blogview.jsp?id=" + rs.getString("id")%>><%=rs.getString("title")%> a>
页面传递的是 id ,不是文章标题,因为 id 是主键,主键不可能重复,所以永远只会找出一篇文章,但是如果以 title 作为参数传递,则可能会搜索出所有同名文章。(⊙o⊙)…尴尬。
避免在 URL 上面传递中文,也是避免乱码的一种有效方式。
五、准备好错误页面
因为各种各样的错误和 bugs,我们得备好错误页面。因 executeUpdate() 返回 -1 的错误页面则应该单独设计。