Servlet 数据库访问

本教程假定您已经了解了 JDBC 应用程序的工作方式。在您开始学习 Servlet 数据库访问之前,请访问 Java MySQL 连接 来设置相关驱动及配置。

注意:你可以下载本站提供的 jar 包:mysql-connector-java-5.1.39-bin.jar在 java 项目中,只需要在 Eclipse 中引入 mysql-connector-java-5.1.39-bin.jar 就可以运行java项目。但是在 Eclipse web 项目中,当执行 Class.forName("com.mysql.jdbc.Driver");时 不会去查找驱动的。所以本实例中我们需要把 mysql-connector-java-5.1.39-bin.jar 拷贝到 tomcat 下 lib 目录。

从基本概念下手,让我们来创建一个简单的表,并在表中创建几条记录。

创建测试数据

接下来我们在 MySQL 中创建 RUNOOB 数据库,并创建 websites 数据表,表结构如下:

  1. CREATE TABLE `websites` (
  2. `id` int(11) NOT NULL AUTO_INCREMENT,
  3. `name` char(20) NOT NULL DEFAULT '' COMMENT '站点名称',
  4. `url` varchar(255) NOT NULL DEFAULT '',
  5. `alexa` int(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名',
  6. `country` char(10) NOT NULL DEFAULT '' COMMENT '国家',
  7. PRIMARY KEY (`id`)
  8. ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

插入一些数据:

  1. INSERT INTO `websites` VALUES ('1', 'Google', 'https://www.google.cm/', '1', 'USA'), ('2', '淘宝', 'https://www.taobao.com/', '13', 'CN'), ('3', 'baidu', 'http://www.baidu.com', '5892', ''), ('4', '微博', 'http://weibo.com/', '20', 'CN'), ('5', 'Facebook', 'https://www.facebook.com/', '3', 'USA');

访问数据库

下面的实例演示了如何使用 Servlet 访问 RUNOOB 数据库。

  1. package com.servlet.test;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.sql.*;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.annotation.WebServlet;
  7. import javax.servlet.http.HttpServlet;
  8. import javax.servlet.http.HttpServletRequest;
  9. import javax.servlet.http.HttpServletResponse;
  10. /**
  11. * Servlet implementation class DatabaseAccess
  12. */
  13. @WebServlet("/DatabaseAccess")
  14. public class DatabaseAccess extends HttpServlet {
  15. private static final long serialVersionUID = 1L;
  16. // JDBC 驱动名及数据库 URL
  17. static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
  18. static final String DB_URL = "jdbc:mysql://localhost:3306/servlet";
  19. // 数据库的用户名与密码,需要根据自己的设置
  20. static final String USER = "root";
  21. static final String PASS = "123456";
  22. /**
  23. * @see HttpServlet#HttpServlet()
  24. */
  25. public DatabaseAccess() {
  26. super();
  27. // TODO Auto-generated constructor stub
  28. }
  29. /**
  30. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
  31. */
  32. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  33. Connection conn = null;
  34. Statement stmt = null;
  35. // 设置响应内容类型
  36. response.setContentType("text/html;charset=UTF-8");
  37. PrintWriter out = response.getWriter();
  38. String title = "Servlet Mysql 测试 - Servlet教程";
  39. String docType = "<!DOCTYPE html>\n";
  40. out.println(docType +
  41. "<html>\n" +
  42. "<head><title>" + title + "</title></head>\n" +
  43. "<body bgcolor=\"#f0f0f0\">\n" +
  44. "<h1 align=\"center\">" + title + "</h1>\n");
  45. try{
  46. // 注册 JDBC 驱动器
  47. Class.forName("com.mysql.jdbc.Driver");
  48. // 打开一个连接
  49. conn = DriverManager.getConnection(DB_URL,USER,PASS);
  50. // 执行 SQL 查询
  51. stmt = conn.createStatement();
  52. String sql;
  53. sql = "SELECT id, name, url FROM websites";
  54. ResultSet rs = stmt.executeQuery(sql);
  55. // 展开结果集数据库
  56. while(rs.next()){
  57. // 通过字段检索
  58. int id = rs.getInt("id");
  59. String name = rs.getString("name");
  60. String url = rs.getString("url");
  61. // 输出数据
  62. out.println("ID: " + id);
  63. out.println(", 站点名称: " + name);
  64. out.println(", 站点 URL: " + url);
  65. out.println("<br />");
  66. }
  67. out.println("</body></html>");
  68. // 完成后关闭
  69. rs.close();
  70. stmt.close();
  71. conn.close();
  72. } catch(SQLException se) {
  73. // 处理 JDBC 错误
  74. se.printStackTrace();
  75. } catch(Exception e) {
  76. // 处理 Class.forName 错误
  77. e.printStackTrace();
  78. }finally{
  79. // 最后是用于关闭资源的块
  80. try{
  81. if(stmt!=null)
  82. stmt.close();
  83. }catch(SQLException se2){
  84. }
  85. try{
  86. if(conn!=null)
  87. conn.close();
  88. }catch(SQLException se){
  89. se.printStackTrace();
  90. }
  91. }
  92. }
  93. /**
  94. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
  95. */
  96. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  97. // TODO Auto-generated method stub
  98. doGet(request, response);
  99. }
  100. }

现在让我们来编译上面的 Servlet,并在 web.xml 文件中创建以下条目:

  1. ....
  2. <servlet>
  3. <servlet-name>DatabaseAccess</servlet-name>
  4. <servlet-class>com.runoob.test.DatabaseAccess</servlet-class>
  5. </servlet>
  6. <servlet-mapping>
  7. <servlet-name>DatabaseAccess</servlet-name>
  8. <url-pattern>/TomcatTest/DatabaseAccess</url-pattern>
  9. </servlet-mapping>
  10. ....

现在调用这个 Servlet,输入链接:http://localhost:8080/TomcatTest/DatabaseAccess,将显示以下响应结果:

  1. Servlet Mysql 测试 - Servlet教程
  2. ID: 1, 站点名称:Google,站点 URL: https://www.google.com/
  3. ID: 2, 站点名称:淘宝,站点 URL: https://www.taobao.com/
  4. ID: 3, 站点名称:baidu,站点 URL: https://www.baidu.com/
  5. ID: 4, 站点名称:微博,站点 URL: https://weibo.com/
  6. ID: 5, 站点名称:Facebook,站点 URL:https://www.facebook.com/

PreparedStatement

进行数据库插入操作的时候使用 PreparedStatement 更好,好处如下:

  • 1.PreparedStatement可以写动态参数化的查询;
  • 2.PreparedStatement比 Statement 更快;
  • 3.PreparedStatement可以防止SQL注入式攻击

实例:

  1. //编写预处理 SQL 语句
  2. String sql= "INSERT INTO websites1 VALUES(?,?,?,?,?)";
  3. //实例化 PreparedStatement
  4. ps = conn.prepareStatement(sql);
  5. //传入参数,这里的参数来自于一个带有表单的jsp文件,很容易实现
  6. ps.setString(1, request.getParameter("id"));
  7. ps.setString(2, request.getParameter("name"));
  8. ps.setString(3, request.getParameter("url"));
  9. ps.setString(4, request.getParameter("alexa"));
  10. ps.setString(5, request.getParameter("country"));
  11. //执行数据库更新操作,不需要SQL语句
  12. ps.executeUpdate();
  13. sql = "SELECT id, name, url FROM websites1";
  14. ps = conn.prepareStatement(sql);
  15. //获取查询结果
  16. ResultSet rs = ps.executeQuery();

MySQL8.0

由于更新的 MySQL8.0,所以本网站提供的 jar 包:mysql-connector-java-5.1.39-bin.jar 就不能用了,连接时会报:

  1. com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server

这个异常。

需要重新下载,下载地址 https://dev.mysql.com/downloads/file/?id=484819,暂时我下载到的是 mysql-connector-java-8.0.15 替换这个 jar 包后,又出现异常 java.sql.SQLException: The server time zone value,只需在数据库地址后边添加 serverTimezone=UTC 即可,例如:

  1. DB_URL = "jdbc:mysql://localhost:3306/servlet_db?serverTimezone=UTC";

还有注册 jdbc 的驱动也换了。

注册 JDBC 驱动器:

  1. Class.forName("com.mysql.cj.jdbc.Driver");