JSP + MySQL 实现博客系统笔记

    技术2026-05-11  3

    刚刚学了 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: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    此类中只有两个对外公开的方法: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: } .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    后来发现在数据库中就是可以插入中文的,自己郁闷的好久。想起来在 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: ) .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    为了各个数据库系统之间的兼容性,我们还可以使用 JAVA 代码实现递增,就是得到 id 的最大值,再加 1。或者使用静态域,使用静态域貌似还得固化数据。

    四、避免在 URL 上面传递中文

    网页中经常会用这样的情形,首先是一个文章标题为名的超级链接,点击这个超级链接会得到文章的全部内容,是使用下面类似的代码实现的:

    1: <a href=<%="blogview.jsp?id=" + rs.getString("id")%>><%=rs.getString("title")%> a> .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

    页面传递的是 id  ,不是文章标题,因为 id 是主键,主键不可能重复,所以永远只会找出一篇文章,但是如果以 title 作为参数传递,则可能会搜索出所有同名文章。(⊙o⊙)…尴尬。

    避免在 URL 上面传递中文,也是避免乱码的一种有效方式。

    五、准备好错误页面

    因为各种各样的错误和 bugs,我们得备好错误页面。因 executeUpdate() 返回 -1 的错误页面则应该单独设计。

    最新回复(0)