9.4.3 案例:使用JDBC操作MySQL

使用BAE的MySQL与使用标准的MySQL基本一致,唯一需要注意的就是获取数据库连接。在9.3.3节中介绍过,使用JDBC获取MySQL数据库连接时,需要知道服务器IP、端口、数据库名称、用户名和密码,现在只知道数据库名称是FTGJUvPHrbXsLGsYpwlp,其他4个参数如何获得呢?

9.4.3 案例:使用JDBC操作MySQL - 图1

图9-15 查询user表的记录

1.获取数据库连接参数

当用户访问部署在BAE中的应用时,BAE对访问请求进行了修改,向请求头中加入了当前应用的数据库服务器IP、端口、用户名和密码,因此,开发者可以从请求头中获取到这4个参数,获取代码如下:

  1. // 数据库服务器IP
  2. String host = request.getHeader("BAE_ENV_ADDR_SQL_IP");
  3. // 端口
  4. String port = request.getHeader("BAE_ENV_ADDR_SQL_PORT");
  5. // 数据库用户
  6. String username = request.getHeader("BAE_ENV_AK");
  7. // 密码
  8. String password = request.getHeader(“BAE_ENV_SK”);

除了上面这种方法外,还有另外两种方法能够得到BAE上MySQL数据库的连接参数。

1)指定连接参数。BAE上MySQL数据库的地址是sqld.duapp.com,端口是4050,用户名、密码分别为应用的API Key和Secret Key,在BAE的应用管理中点击应用名称就能看到。

2)从线程变量BaeEnv接口获取,获取方法如下:

  1. // IP
  2. String host = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_ADDR_SQL_IP);
  3. // 端口
  4. String port = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_ADDR_SQL_PORT);
  5. // 用户名
  6. String username = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_AK);
  7. // 密码
  8. String password = BaeEnv.getBaeHeader(BaeEnv.BAE_ENV_SK);

BaeEnv类是Java BAE环境中的内置类,不需要在项目中包含相关JAR包,只需在Java文件中使用import关键字导入com.baidu.bae.api.util.BaeEnv类即可。

2.完整案例

下面通过一个完整案例演示使用JDBC操作BAE中的MySQL数据库。在MyEclipse中新建一个Web项目,然后在项目的src下创建一个Servlet类,该类的代码如下:

  1. 1 package org.liufeng.course.servlet;
  2. 2 
  3. 3 import java.io.IOException;
  4. 4 import java.io.PrintWriter;
  5. 5 import java.sql.Connection;
  6. 6 import java.sql.DriverManager;
  7. 7 import java.sql.PreparedStatement;
  8. 8 import java.sql.ResultSet;
  9. 9 import java.util.ArrayList;
  10. 10 import java.util.HashMap;
  11. 11 import java.util.List;
  12. 12 import javax.servlet.ServletException;
  13. 13 import javax.servlet.http.HttpServlet;
  14. 14 import javax.servlet.http.HttpServletRequest;
  15. 15 import javax.servlet.http.HttpServletResponse;
  16. 16 
  17. 17 /**
  18. 18  * 示例:使用JDBC操作BAE中的MySQL数据库
  19. 19  *
  20. 20  * @author liufeng
  21. 21  * @date 2013-11-18
  22. 22  */
  23. 23 public class UserServlet extends HttpServlet {
  24. 24  private static final long serialVersionUID = 1196941092414541883L;
  25. 25 
  26. 26  public void doGet(HttpServletRequest request, HttpServletResponse response)
  27. 27  throws ServletException, IOException {
  28. 28  request.setCharacterEncoding("gb2312");
  29. 29  response.setCharacterEncoding("gb2312");
  30. 30 
  31. 31  PrintWriter out = response.getWriter();
  32. 32  // 查询user
  33. 33  List<HashMap<String, Object>> userList = queryUser(request);
  34. 34  // 遍历List集合
  35. 35  for (HashMap<String, Object> map : userList) {
  36. 36  out.println(map.get("name") + " " + map.get("age"));
  37. 37  }
  38. 38  out.flush();
  39. 39  out.close();
  40. 40 }
  41. 41 
  42. 42 /**
  43. 43  * 查询BAE MySQL数据库中user表的数据
  44. 44  *
  45. 45  * @param request
  46. 46  * @return
  47. 47  */
  48. 48 private static List<HashMap<String, Object>> queryUser(HttpServletRequest request) {
  49. 49  List<HashMap<String, Object>> userList = new ArrayList<HashMap<String, Object>>();
  50. 50 
  51. 51  // 从request请求头中取出IP、端口、用户名和密码
  52. 52  String host = request.getHeader("BAE_ENV_ADDR_SQL_IP");
  53. 53  String port = request.getHeader("BAE_ENV_ADDR_SQL_PORT");
  54. 54  String username = request.getHeader("BAE_ENV_AK");
  55. 55  String password = request.getHeader("BAE_ENV_SK");
  56. 56  // 数据库名称
  57. 57  String dbName = "FTGJUvPHrbXsLGsYpwlp";
  58. 58  // JDBC URL
  59. 59  String url = String.format("jdbc:mysql://%s:%s/%s", host, port, dbName);
  60. 60 
  61. 61  try {
  62. 62  // 加载MySQL驱动
  63. 63  Class.forName("com.mysql.jdbc.Driver");
  64. 64  // 获取数据库连接
  65. 65  Connection conn = DriverManager.getConnection(url, username, password);
  66. 66  // 定义查询SQL语句
  67. 67  String sql = "select name,age from user";
  68. 68  // 创建PreparedStatement对象(包含已编译的SQL语句)
  69. 69  PreparedStatement ps = conn.prepareStatement(sql);
  70. 70  // 执行查询并获取结果集
  71. 71  ResultSet rs = ps.executeQuery();
  72. 72  // 遍历查询结果集
  73. 73  while (rs.next()) {
  74. 74  HashMap<String, Object> userMap = new HashMap<String, Object>();
  75. 75  userMap.put("name", rs.getString("name"));
  76. 76  userMap.put("age", rs.getInt("age"));
  77. 77  userList.add(userMap);
  78. 78  }
  79. 79 
  80. 80  // 关闭连接,释放资源
  81. 81  rs.close();
  82. 82  ps.close();
  83. 83  conn.close();
  84. 84  } catch (Exception e) {
  85. 85  e.printStackTrace();
  86. 86  }
  87. 87  return userList;
  88. 88  }
  89. 89 }

上述代码中的第33~37行调用queryUser()方法查询云数据库中的数据,并将获取到的结果输出。第52~55行是本示例代码的关键,从request请求头中获取IP、端口、用户名和密码。第57行是指定数据库名称,在图9-13中可以看到当前应用的数据库名称。第59行是根据IP、端口、数据库名称构造JDBC URL。

UserServlet类在web.xml中的配置如下:

  1. <servlet>
  2. <servlet-name>userServlet</servlet-name>
  3. <servlet-class>
  4. org.liufeng.course.servlet.UserServlet
  5. </servlet-class>
  6. </servlet>
  7.  
  8. <servlet-mapping>
  9. <servlet-name>userServlet</servlet-name>
  10. <url-pattern>/userServlet</url-pattern>
  11. </servlet-mapping>

3.运行效果

到这里,整个示例就开发完成了,最后,将项目打成WAR包,部署到BAE上。在浏览器中访问UserServlet,正常情况下,页面上会显示我们之前往user表中插入的5条数据,如图9-16所示。

9.4.3 案例:使用JDBC操作MySQL - 图2

图9-16 示例运行结果


注意 ①BAE环境中已经内置了MySQL驱动,因此,上面的项目中不需要包含MySQL驱动。②上面的项目必须部署到BAE才能正常运行,在本机或其他服务器上无法连接BAE的MySQL。