原文:http://zetcode.com/java/datasource/

在本教程中,我们学习如何在 Java 中设置数据源。 我们使用 MySQL 数据库系统。 ZetCode 拥有用于 MySQL Java 的完整电子书: MySQL Java 编程电子书

我们使用 MySQL Connector/J 驱动程序。 它是 MySQL 的官方 JDBC 驱动程序。

用 Java 创建到数据库的连接有两种基本方法:a)使用驱动程序管理器,b)使用数据源。 与驱动程序管理器相比,数据源具有几个优点:

  • 它支持分布式事务
  • 它提供了一种连接池技术
  • 它可以由服务器(即应用外部)进行管理

当在 Java 类中创建和关闭连接时,驱动程序管理器会影响应用性能。 驱动程序管理器可用于简单的测试应用中。 对于复杂的应用,始终建议使用数据源。 请参阅 MySQL Java 教程,以了解如何在 Java 应用中使用驱动程序管理器。

通常,将基于 Java 命名和目录接口(JNDI)API 向实现数据源接口的对象注册命名服务。

JDBC

JDBC 是 Java 编程语言的 API,用于定义客户端如何访问数据库。 它提供了查询和更新数据库中数据的方法。 JDBC 面向关系数据库。 从技术角度来看,API 是java.sql包中的一组类。 要将 JDBC 与特定数据库一起使用,我们需要该数据库的 JDBC 驱动程序。

MySQL

MySQL 是领先的开源数据库管理系统。 它是一个多用户,多线程的数据库管理系统。 MySQL 在网络上特别流行。 MySQL 有两个版本:MySQL 服务器系统和 MySQL 嵌入式系统。

  1. mysql> CREATE DATABASE testdb;
  2. Query OK, 1 row affected (0.02 sec)

我们创建一个新的testdb数据库。 在本教程中,我们只需要一个数据库对象。 我们将不使用表格。 我们将使用SELECT VERSION()语句获取 MySQL 数据库的版本。

命令行应用

在此示例中,我们使用命令行 Java 应用连接到数据库。

Java 中的数据源 - 图1

图:项目结构

这就是 NetBeans 中项目结构的样子。

MysqlDataSource是用于创建数据源的类。

db.properties

  1. # mysql properties
  2. mysql.driver=com.mysql.jdbc.Driver
  3. mysql.url=jdbc:mysql://localhost:3306/testdb
  4. mysql.username=testuser
  5. mysql.password=test623

这些是 MySQL 数据库的属性。 db.properties文件位于此项目的src/resources子目录中。

ComLineDSEx.java

  1. package com.zetcode;
  2. import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
  3. import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.IOException;
  7. import java.sql.Connection;
  8. import java.sql.ResultSet;
  9. import java.sql.SQLException;
  10. import java.sql.PreparedStatement;
  11. import java.util.Properties;
  12. public class ComLineDSEx {
  13. public static MysqlDataSource getMySQLDataSource() throws
  14. FileNotFoundException, IOException {
  15. Properties props = new Properties();
  16. FileInputStream fis = null;
  17. MysqlDataSource ds = null;
  18. fis = new FileInputStream("src/resources/db.properties");
  19. props.load(fis);
  20. ds = new MysqlConnectionPoolDataSource();
  21. ds.setURL(props.getProperty("mysql.url"));
  22. ds.setUser(props.getProperty("mysql.username"));
  23. ds.setPassword(props.getProperty("mysql.password"));
  24. return ds;
  25. }
  26. public static void main(String[] args) throws IOException, SQLException {
  27. Connection con = null;
  28. PreparedStatement pst = null;
  29. ResultSet rs = null;
  30. MysqlDataSource ds = getMySQLDataSource();
  31. try {
  32. con = ds.getConnection();
  33. pst = con.prepareStatement("SELECT VERSION()");
  34. rs = pst.executeQuery();
  35. if (rs.next()) {
  36. String version = rs.getString(1);
  37. System.out.println(version);
  38. }
  39. } finally {
  40. if (rs != null) {
  41. rs.close();
  42. }
  43. if (pst != null) {
  44. pst.close();
  45. }
  46. if (con != null) {
  47. con.close();
  48. }
  49. }
  50. }
  51. }

在此示例中,我们使用数据源连接到数据库并获取 MySQL 的版本。

  1. fis = new FileInputStream("src/main/Resources/db.properties");
  2. props.load(fis);

从具有FileInputStream类的db.properties文件中读取数据库属性。

  1. ds = new MysqlConnectionPoolDataSource();
  2. ds.setURL(props.getProperty("mysql.url"));
  3. ds.setUser(props.getProperty("mysql.username"));
  4. ds.setPassword(props.getProperty("mysql.password"));

创建MysqlConnectionPoolDataSource并设置数据源属性。

  1. con = ds.getConnection();

使用getConnection()方法从数据源创建连接对象。

  1. pst = con.prepareStatement("SELECT VERSION()");

创建一条 SQL 语句。 SELECT VERSION()命令返回 MySQL 的版本。

  1. rs = pst.executeQuery();

查询被执行。 它返回一个结果集。

  1. if (rs.next()) {
  2. String version = rs.getString(1);
  3. System.out.println(version);
  4. }

我们从结果集中获取第一个值,并将其打印到控制台。

  1. } finally {
  2. if (rs != null) {
  3. rs.close();
  4. }
  5. if (pst != null) {
  6. pst.close();
  7. }
  8. if (con != null) {
  9. con.close();
  10. }
  11. }

最后,资源被释放。

Tomcat 中的 Web 应用

我们创建了一个 Web 应用,它将检索 MySQL 的版本。 该应用已部署在 Tomcat 上。

Java 中的数据源 - 图2

图:项目库

在我们的项目中,我们使用 JSTL 和 MySQL 驱动程序 JAR。 JavaServer Pages 标准标记库(JSTL) 是有用的 JSP 标记的集合,这些标记提供了许多 JSP 文件所共有的核心功能。

context.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <Context path="/TomcatDSEx">
  3. <Resource name="jdbc/testdb"
  4. auth="Container"
  5. type="javax.sql.DataSource"
  6. username="testuser"
  7. password="test623"
  8. driverClassName="com.mysql.jdbc.Driver"
  9. url="jdbc:mysql://localhost:3306/testdb"
  10. maxActive="10"
  11. maxIdle="4"/>
  12. </Context>

对于 Tomcat Web 服务器,我们在context.xml文件中创建一个新资源。 该文件位于META-INF目录中。

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  5. version="3.1">
  6. <resource-ref>
  7. <description>DB Connection</description>
  8. <res-ref-name>jdbc/testdb</res-ref-name>
  9. <res-type>javax.sql.DataSource</res-type>
  10. <res-auth>Container</res-auth>
  11. </resource-ref>
  12. </web-app>

然后,在web.xml文件中,创建对资源的引用。 在我们的应用中,我们将使用逻辑名称jdbc/testdb引用数据源。

index.jsp

  1. <%@page contentType="text/html" pageEncoding="UTF-8"%>
  2. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>JSP Page</title>
  8. </head>
  9. <body>
  10. <c:redirect url="/Version"/>
  11. </body>
  12. </html>

index.jsp文件重定向到Version Servlet。

showVersion.jsp

  1. <%@page contentType="text/html" pageEncoding="UTF-8"%>
  2. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  3. <!DOCTYPE html>
  4. <html>
  5. <head>
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7. <title>MySQL version</title>
  8. </head>
  9. <body>
  10. MySQL version: <c:out value="${version}"/>
  11. </body>
  12. </html>

showVersion.jsp是一个 UI 元素,用于显示从数据库检索的数据。

  1. MySQL version: <c:out value="${version}"/>

JSTL 的<c:out>标记用于输出响应的值。

Version.java

  1. package com.zetcode.version;
  2. import com.zetcode.version.service.DBVersionService;
  3. import java.io.IOException;
  4. import javax.servlet.RequestDispatcher;
  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. @WebServlet(name = "Version", urlPatterns = {"/Version"})
  11. public class Version extends HttpServlet {
  12. protected void processRequest(HttpServletRequest request, HttpServletResponse response)
  13. throws ServletException, IOException {
  14. response.setContentType("text/html;charset=UTF-8");
  15. String page = "/showVersion.jsp";
  16. String version = DBVersionService.getMySQLVersion();
  17. request.setAttribute("version", version);
  18. RequestDispatcher disp = getServletContext().getRequestDispatcher(page);
  19. disp.forward(request, response);
  20. }
  21. @Override
  22. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  23. throws ServletException, IOException {
  24. processRequest(request, response);
  25. }
  26. @Override
  27. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  28. throws ServletException, IOException {
  29. processRequest(request, response);
  30. }
  31. @Override
  32. public String getServletInfo() {
  33. return "Returns version of MySQL";
  34. }
  35. }

Version Servlet 调用服务方法来获取 MySQL 的版本。 返回的值设置为请求对象的属性。

  1. String page = "/showVersion.jsp";

最后,Servlet 指向showVersion.jsp文件。

  1. String version = DBVersionService.getMySQLVersion();

调用服务方法来获取 MySQL 的版本。

  1. request.setAttribute("version", version);

使用setAttribute()方法将版本值设置为请求对象。

  1. RequestDispatcher disp = getServletContext().getRequestDispatcher(page);
  2. disp.forward(request, response);

我们调度到showVersion.jsp文件。

DBVersionService.java

  1. package com.zetcode.version.service;
  2. import com.zetcode.version.Version;
  3. import com.zetcode.version.util.ServiceLocator;
  4. import java.sql.Connection;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.logging.Level;
  9. import java.util.logging.Logger;
  10. import javax.sql.DataSource;
  11. public class DBVersionService {
  12. public static String getMySQLVersion() {
  13. String version = "no version";
  14. DataSource ds = ServiceLocator.getDataSource("java:comp/env/jdbc/testdb");
  15. Connection con = null;
  16. try {
  17. con = ds.getConnection();
  18. Statement stm = con.createStatement();
  19. ResultSet rs = stm.executeQuery("SELECT VERSION()");
  20. if (rs.next()) {
  21. version = rs.getString(1);
  22. }
  23. } catch (SQLException ex) {
  24. Logger.getLogger(Version.class.getName()).log(Level.SEVERE, null, ex);
  25. } finally {
  26. if (con != null) {
  27. try {
  28. con.close();
  29. } catch (SQLException ex) {
  30. Logger.getLogger(DBVersionService.class.getName()).log(Level.SEVERE, null, ex);
  31. }
  32. }
  33. }
  34. return version;
  35. }
  36. }

DBVersionService是一个服务类,其中包含获取 MySQL 版本的方法。

  1. DataSource ds = ServiceLocator.getDataSource("java:comp/env/jdbc/testdb");

数据源是使用ServiceLocator类创建的。

  1. con = ds.getConnection();
  2. Statement stm = con.createStatement();
  3. ResultSet rs = stm.executeQuery("SELECT VERSION()");
  4. if (rs.next()) {
  5. version = rs.getString(1);
  6. }

在这里,我们有用于连接到数据库并执行 SQL 语句的 JDBC 代码。

ServiceLocator.java

  1. package com.zetcode.version.util;
  2. import java.util.logging.Level;
  3. import java.util.logging.Logger;
  4. import javax.naming.Context;
  5. import javax.naming.InitialContext;
  6. import javax.naming.NamingException;
  7. import javax.sql.DataSource;
  8. public class ServiceLocator {
  9. public static DataSource getDataSource(String jndiName) {
  10. Context ctx = null;
  11. DataSource ds = null;
  12. try {
  13. ctx = new InitialContext();
  14. ds = (DataSource) ctx.lookup(jndiName);
  15. } catch (NamingException ex) {
  16. Logger.getLogger(ServiceLocator.class.getName()).log(Level.SEVERE, null, ex);
  17. }
  18. return ds;
  19. }
  20. }

ServiceLocator通过其给定的 JNDI 名称查找数据源,并将其返回给调用方。

  1. $ curl localhost:8084/TomcatDSEx/Version
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  6. <title>MySQL version</title>
  7. </head>
  8. <body>
  9. MySQL version: 5.5.49-0ubuntu0.14.04.1
  10. </body>
  11. </html>

该应用将响应一个包含 MySQL 版本的 HTML 页面。

这是 Java 教程中的数据源。 您可能也对 JDBI 教程MyBatis 教程SQL 查询标记教程MySQL 教程感兴趣。