首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> JSP 程式設計 >> JSP 入門

JSP 資料庫連線完整實戰:JSTL SQL 標籤庫 CRUD 操作、連線池設定與中文編碼解決方案

     編輯:JSP 入門

JSP 資料庫連線完整實戰指南


掌握 JSP 使用 JSTL SQL 標籤庫進行資料庫操作:環境建置、連線設定、CRUD 完整範例、參數化查詢、中文編碼處理與連線池最佳實務。


環境建置與驅動安裝

MySQL JDBC 驅動

  • 下載:mysql-connector-java-5.1.39-bin.jar (或更新版本)
  • 部署:複製至 Tomcat/lib/ 目錄 (所有 Web 應用共用)
  • 或專案部署:WEB-INF/lib/ (僅單一應用)

測試資料庫準備

-- 建立資料庫
CREATE DATABASE RUNOOB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- 建立資料表
CREATE TABLE `websites` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` CHAR(20) NOT NULL DEFAULT '' COMMENT '站點名稱',
    `url` VARCHAR(255) NOT NULL DEFAULT '',
    `alexa` INT(11) NOT NULL DEFAULT '0' COMMENT 'Alexa 排名',
    `country` CHAR(10) NOT NULL DEFAULT '' COMMENT '國家',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- 插入測試資料
INSERT INTO `websites` VALUES 
(1, 'Google', 'https://www.google.com/', 1, 'USA'),
(2, '淘寶', 'https://www.taobao.com/', 13, 'CN'),
(3, '菜鳥教程', 'https://www.runoob.com', 5892, ''),
(4, '微博', 'https://weibo.com/', 20, 'CN'),
(5, 'Facebook', 'https://www.facebook.com/', 3, 'USA');

資料表結構


JSTL SQL 標籤庫基礎設定

引入標籤庫

<%@ taglib prefix="sql" uri="https://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>

資料來源設定 (含中文編碼參數)

<sql:setDataSource var="ds" 
    driver="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/RUNOOB?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Taipei"
    user="root"
    password="123456" />

連線 URL 參數解析

參數值用途
useUnicodetrue使用 Unicode 字元集
characterEncodingutf-8指定字元編碼,解決中文亂碼
useSSLfalse關閉 SSL (本地開發環境)
serverTimezoneAsia/Taipei設定時區,避免時區警告
autoReconnecttrue自動重連 (生產環境建議)

CRUD 完整操作範例

共用頁面範本

<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="sql" uri="https://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<html><head><title>JSP 資料庫範例</title></head><body>
<sql:setDataSource var="ds" driver="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/RUNOOB?useUnicode=true&characterEncoding=utf-8"
    user="root" password="123456"/>

<!-- 具體操作放在此處 -->

<h1>JSP 資料庫範例 - 菜鳥教程</h1>
<table border="1" width="100%">
    <tr><th>ID</th><th>站點名</th><th>站點網址</th></tr>
    <c:forEach var="row" items="${result.rows}">
        <tr>
            <td><c:out value="${row.id}"/></td>
            <td><c:out value="${row.name}"/></td>
            <td><c:out value="${row.url}"/></td>
        </tr>
    </c:forEach>
</table>
</body></html>

SELECT 查詢操作

<sql:query dataSource="${ds}" var="result">
    SELECT * FROM websites ORDER BY alexa ASC;
</sql:query>

查詢結果

INSERT 新增操作

<sql:update dataSource="${ds}" var="count">
    INSERT INTO websites (name, url, alexa, country) 
    VALUES ('菜鳥教程行動站', 'https://m.runoob.com', 5093, 'CN');
</sql:update>

<!-- 新增後查詢驗證 -->
<sql:query dataSource="${ds}" var="result">
    SELECT * FROM websites;
</sql:query>

新增結果

DELETE 刪除操作 (參數化查詢)

<sql:update dataSource="${ds}" var="count">
    DELETE FROM websites WHERE id = ?
    <sql:param value="${11}" />
</sql:update>

<sql:query dataSource="${ds}" var="result">
    SELECT * FROM websites;
</sql:query>

刪除結果

UPDATE 修改操作 (參數化查詢)

<c:set var="siteId" value="3"/>

<sql:update dataSource="${ds}" var="count">
    UPDATE websites SET name = 'RUNOOB' WHERE id = ?
    <sql:param value="${siteId}" />
</sql:update>

<sql:query dataSource="${ds}" var="result">
    SELECT * FROM websites;
</sql:query>

修改結果


進階查詢技巧

條件查詢與參數化

<c:set var="keyword" value="${param.search}"/>
<c:set var="minAlexa" value="${param.minAlexa}"/>

<sql:query dataSource="${ds}" var="result">
    SELECT * FROM websites 
    WHERE name LIKE ?
    AND alexa >= ?
    ORDER BY alexa ASC
    <sql:param value="%${keyword}%" />
    <sql:param value="${minAlexa}" />
</sql:query>

分頁查詢

<c:set var="pageSize" value="10"/>
<c:set var="pageNum" value="${param.pageNum gt 0 ? param.pageNum : 1}"/>
<c:set var="offset" value="${(pageNum - 1) * pageSize}"/>

<sql:query dataSource="${ds}" var="result" maxRows="${pageSize}" startRow="${offset + 1}">
    SELECT * FROM websites ORDER BY id DESC
</sql:query>

<!-- 總筆數查詢 -->
<sql:query dataSource="${ds}" var="countResult">
    SELECT COUNT(*) as total FROM websites
</sql:query>
<c:set var="totalRecords" value="${countResult.rows[0].total}"/>
<c:set var="totalPages" value="${(totalRecords + pageSize - 1) / pageSize}"/>

交易控制 (多重更新)

<sql:transaction dataSource="${ds}">
    <sql:update var="count1">
        UPDATE accounts SET balance = balance - 100 WHERE id = 1
    </sql:update>
    <sql:update var="count2">
        UPDATE accounts SET balance = balance + 100 WHERE id = 2
    </sql:update>
</sql:transaction>

連線池最佳實務 - 生產環境必備

Tomcat JNDI 連線池設定 (context.xml)

<Context>
    <Resource name="jdbc/RUNOOB"
              auth="Container"
              type="javax.sql.DataSource"
              maxTotal="20"
              maxIdle="10"
              maxWaitMillis="10000"
              username="root"
              password="123456"
              driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql://localhost:3306/RUNOOB?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Taipei"
              validationQuery="SELECT 1"
              testOnBorrow="true"
              testWhileIdle="true"
              timeBetweenEvictionRunsMillis="300000"
              minEvictableIdleTimeMillis="600000"
              removeAbandonedOnBorrow="true"
              removeAbandonedTimeout="60"
              logAbandoned="true" />
</Context>

web.xml 資源參考宣告

<resource-ref>
    <description>MySQL Connection Pool</description>
    <res-ref-name>jdbc/RUNOOB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

JSP 使用 JNDI 連線池

<sql:setDataSource dataSource="java:comp/env/jdbc/RUNOOB" var="ds"/>

連線池參數調優指南

參數建議值調整依據
maxTotal20-50根據伺服器 CPU 核心數、預期並發數
maxIdlemaxTotal 的 50%保持熱連線減少建立開銷
maxWaitMillis10000-30000避免請求無限等待
validationQuerySELECT 1輕量驗證連線有效性
testOnBorrowtrue借用時驗證,確保連線可用
removeAbandonedOnBorrowtrue回收洩漏連線

常見問題與解決方案

問題原因解決
中文亂碼連線未指定 characterEncoding、資料表非 utf8mb4URL 加參數、資料表轉 utf8mb4、JSP pageEncoding=UTF-8
ClassNotFoundExceptionJDBC 驅動未放入 Tomcat/lib複製 jar 至 Tomcat/lib、重啟 Tomcat
Communications link failureMySQL 服務未啟動、port 錯誤、防火牆阻擋啟動 MySQL、確認 3306 port、開放防火牆
Connection refused連線池耗盡、MySQL max_connections 限制調大連線池、調大 MySQL max_connections、檢查洩漏
SSL 連線錯誤MySQL 8.0+ 預設要求 SSLURL 加 useSSL=false 或配置 SSL 憑證
時區警告伺服器時區未設定URL 加 serverTimezone=Asia/Taipei

安全性最佳實務

  1. 參數化查詢:絕對使用 <sql:param>,防止 SQL Injection
  2. 最小權限原則:資料庫帳號僅授予必要權限 (SELECT/INSERT/UPDATE/DELETE)
  3. 敏感資料加密:密碼、身分證號、信用卡號必須加密儲存
  4. 審計日誌:關鍵操作記錄操作者、時間、前後值
  5. 錯誤訊息不外洩:生產環境隱藏 SQL 錯誤細節,記錄至日誌
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved