[Servlet&JSP] 使用JDBC连接数据库

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: JDBC(Java DataBase Connectivity)时用于运行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行实现,这样开发人员就可以无需接触底层数据库驱动程序的差异性。JDBC简介厂商在实现JDBC驱动程序时,依方式可将驱动程序分为四种类型:JDBC-ODBC Bridge Driver 将JDBC调用转换为ODBC调

JDBC(Java DataBase Connectivity)时用于运行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行实现,这样开发人员就可以无需接触底层数据库驱动程序的差异性。

JDBC简介

厂商在实现JDBC驱动程序时,依方式可将驱动程序分为四种类型:

  1. JDBC-ODBC Bridge Driver
    将JDBC调用转换为ODBC调用
  2. Native API Driver
    将JDBC调用转换为原生链接库中的相关API调用。特点:与平台相依,是四种类型中最快的驱动程序。
  3. JDBC-Net Driver
    将JDBC调用转换为特定的网络协议调用,目的是与远程数据库特定的中间服务器或组件进行协议操作,而中间件或组建再真正与数据库进行操作。特点:弹性最高。
  4. Native Protocol Driver
    主要作用是将JDBC调用转换为特定的网络协议,所以驱动驱动程序可以使用Java技术来实现,遗传你这类型的驱动程序可以跨平台,在性能上也有不错的表现。在不需要如第3种驱动类型的灵活性时,通常是会使用这类型驱动程序,该类型时最常见的驱动程序类型。

以下编写一个简单的JavaBean来测试可否连接数据库:

package club.chuxing;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DbBean {
    private String url;
    private String username;
    private String password;

    public DbBean(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            Logger.getLogger(DbBean.class.getName()).log(Level.SEVERE, null, e);
        }
    }

    public boolean isConnectedOk() {
        boolean ok = false;
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, username, password);
            if (!conn.isClosed()) {
                ok = true;
            }
        } catch (SQLException e) {
            Logger.getLogger(DbBean.class.getName()).log(Level.SEVERE, null, e);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    Logger.getLogger(DbBean.class.getName())
                        .log(Level.SEVERE, null, e);
                }
            }
        }

        return ok;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setName(String username) {
        this.username = username;
    }
}

之后就可以通过调用isConnectedOK()方法来看看是否可以连接成功。例如,可以写个简单的JSP网页,代码如下:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="db" class="club.chuxing.DbBean" />
<c:set target="${db}" property="url" value="jdbc:mysql://localhost:3306/test" />
<c:set target="${db}" property="username" value="root" />
<c:set target="${db}" property="password" value="123" />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Test Database Connection</title>
    </head>
    <body>
        <c:choose>
            <c:when test="${db.connectedOK}">连接成功</c:when>
            <%-- <c:when test="<%db.isConnectedOK();%>">连接成功</c:when> --%>
            <c:otherwise>连接失败</c:otherwise>
        </c:choose>
    </body>
</html>

使用DataSource取得连接

在Java EE中的环境中,将取得连接等与数据库来源相关的行为规范在javax.sql.DataSource接口,实际如何取得Connection则由实现接口的对象来负责。

为了让应用程序在需要取得某些与系统相关的资源对象时,能与实际的系统配置、实体机器位置、环境架构等无关,在Java应用程序中可以通过JNDI(Java Naming Directory Interface)来取得所需的资源对象。可用如下方式取得DataSource实例:

try {
    Context initContext = new InitialContext();
    Context envContext = (Context)initContext.lookup("java:/comp/env");
    dataSource = (DataSource)envContext.lookup("jdbc/test");
} catch(NamingException ex) {
    //other process
}

在创建Context对象的过程中会收集环境的相关数据,之后根据JNDI名称jdbc/demo向JNDI服务器查找DataSource实例并返回。在这个程序片段中,不会知道实际的资源配置、实体机器位置、环境架构等信息,应用程序不会与这些相依。

之前的DbBean类可以改为如下编写方式:

package club.chuxing;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

public class DatabaseBean {
    private DataSource dataSource;
    public DatabaseBean(){
        try {
            Context initContext = new InitialContext();
            Context envContext = (Context)initContext.lookup("java:/comp/env");
            dataSource = (DataSource)envContext.lookup("jdbc/test");
        } catch(NamingException ex) {
            Logger.getLogger(DatabaseBean.class.getName())
                .log(Level.SEVERE, null, ex);
        }
    }

    public boolean isConnectedOK(){
        boolean ok = false;
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            if (!conn.isClosed()) {
                ok = true;
            }
        } catch(SQLException ex) {
            Logger.getLogger(DatabaseBean.class.getName())
                .log(Level.SEVERE, null, ex);
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch(SQLException ex) {
                    Logger.getLogger(DatabaseBean.class.getName())
                        .log(Level.SEVERE, null, ex);
                }
            }
        }

        return ok;
    }
}

以上代码并不含有驱动程序、数据库用户名、密码等信息,这些都由数据库管理人员或服务器管理人员负责设置,我们唯一需要知道的就是jdbc/test这个JNDI名称,并且告诉web容器,也就是要在web.xml中设置。

web.xml:

<web-app ...>
  <resource-ref>
      <res-ref-name>jdbc/demo</res-ref-name>
      <res-type>javax.sql.DataSource</res-type>
      <res-auth>Container</res-auth>
      <res-sharing-scope>Shareable</res-sharing-scope>
  </resource-ref>
</web-app>

在web.xml中设置的目的,就是让web容器提供JNDI查找时所需的相关环境信息,这样创建Context对象时就不用设置一大堆参数了。接着可以编写一个简单的JSP来使用DatabaseBean。

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<jsp:useBean id="db" class="club.chuxing.DatabaseBean" />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>Test Database Connection</title>
    </head>
    <body>
        <c:choose>
            <c:when test="${db.connectedOK}">连接成功</c:when>
            <%-- <c:when test="<%= db.isConnectedOK()%>">连接成功</c:when> --%>
            <c:otherwise>连接失败</c:otherwise>
        </c:choose>
    </body>
</html>

对于Java开发人员来说,它的工作已经完成了。现在假设你是服务器管理员,职责就是设置JNDI相关资源,但设置的方式并非标准的一部分,而是依应用程序服务器而有所不同。假设应用程序将部署在Tomcat6上,则可以要求web应用程序在封装为war文件时,必须在META-INF文件夹中包括一个context.xml文件。例如:

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/JDBCDemo">
    <Resource name="jdbc/demo" auth="Container" type="javax.sql.DataSource"
    maxActive="100" maxIdle="30" maxWait="1000" username="root" password="123"
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8"/>
</Context>

name属性用来设置JNDI名称,username与password用来设置数据库用户名和密码,driverClassName用来设置驱动程序类名称,url用来设置JDBC URL。其他属性则是与DBCP(Database Connection Pool)有关的,这是内置在Tomcat中的连接池机制。

当应用程序部署后,Tomcat会根据META-INF中context.xml的设置,寻找指定的驱动程序,所以必须将驱动程序的JAR文件放置在Tomcat的lib目录中,接着Tomcat就会为JNDI名称jdbc/demo设置相关的资源。

使用root来操作数据库是不安全的,root账号用于操作数据库的完整权限,应用设置具有适当权限的用户来操作数据库。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
11天前
|
JavaScript 关系型数据库 API
Nest.js 实战 (二):如何使用 Prisma 和连接 PostgreSQL 数据库
这篇文章介绍了什么是Prisma以及如何在Node.js和TypeScript后端应用中使用它。Prisma是一个开源的下一代ORM,包含PrismaClient、PrismaMigrate、PrismaStudio等部分。文章详细叙述了安装PrismaCLI和依赖包、初始化Prisma、连接数据库、定义Prisma模型、创建Prisma模块的过程,并对比了Prisma和Sequelize在Nest.js中的使用体验,认为Prisma更加便捷高效,没有繁琐的配置。
Nest.js 实战 (二):如何使用 Prisma 和连接 PostgreSQL 数据库
|
1天前
|
存储 关系型数据库 分布式数据库
PolarDB产品使用问题之如何使用本地电脑连接PolarDB数据库
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
|
3天前
|
SQL 关系型数据库 MySQL
如何在PHP中连接到数据库?
在PHP中连接MySQL数据库常用的方法是MySQLi与PDO。MySQLi专为MySQL设计,支持面向对象及过程化编程,并提供预处理语句防止SQL注入。
|
10天前
|
缓存 分布式计算 DataWorks
DataWorks操作报错合集之连接数据库时出现了通信链接失败的报错,该如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
10天前
|
SQL DataWorks Java
DataWorks操作报错合集之在与某个数据库服务器建立或保持通信连接时遇到报错,该如何解决
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
17天前
|
ARouter 关系型数据库 MySQL
Django项目同时连接多个不同的数据库(7)
【7月更文挑战第7天】在Django项目中配置连接多个数据库,你需要: 1. 在`settings.py`中配置多个数据库, 2. 在`settings.py`内设置数据库路由,指定每个应用使用的数据库,
36 2
|
22天前
|
前端开发 NoSQL 数据库
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
|
22天前
|
弹性计算 NoSQL 网络安全
软件开发常见之云数据库Redis连接不上如何解决,修改配置后,需要重启下redis服务,配置才能生效呢,是重启,而不是重载配置,最后导致的问题是点击了的重启,配置修改了之后必须点击重启,而不是修改
软件开发常见之云数据库Redis连接不上如何解决,修改配置后,需要重启下redis服务,配置才能生效呢,是重启,而不是重载配置,最后导致的问题是点击了的重启,配置修改了之后必须点击重启,而不是修改
|
3天前
|
Oracle 关系型数据库 MySQL
入职必会-开发环境搭建17-IDEA连接数据库
IntelliJ IDEA集成了众多插件,方便开发者使用,使用IDEA自带的Database模块就可以很方便的配置、连接数据库,在 IntelliJ IDEA 中连接数据库,可以按照以下步骤进行操作。
|
6天前
|
SQL 数据库 数据安全/隐私保护
为什么程序连接不同的数据库要使用不同的账号
为什么程序连接不同的数据库要使用不同的账号