构建 Java Web 应用程序:从 Servlet 到数据库交互(Eclipse使用JDBC连接Mysql数据库)

第 1 部分:环境设置
  1. 安装 Java Development Kit (JDK):下载并安装 JDK。
  2. 设置 IDE:安装并配置 IDE(如 IntelliJ IDEA 或 Eclipse)。
  3. 安装数据库:下载并安装 MySQL 数据库。
  4. 配置数据库:创建数据库和用户,设置权限。
  5. 确保MySQL数据库服务正在运行。
  6. 使用数据库管理工具(如终端命令行或Navicat)测试连接。
第 2 部分:创建 Web 应用程序项目
  1. 创建新项目:在 IDE 中创建新的 Java Web 项目。
  2. 配置项目结构:设置 src/main/java 和 src/main/webapp 目录。
  3. 添加依赖:如果使用 Maven 或 Gradle,添加 MySQL JDBC 驱动程序依赖。

第 3 部分:设计实体类
  1. 创建 Student 实体类:定义学生的属性和方法。
package  ; // 定义了该类所属的包名 根据自己的项目进行补充

/**
 * Student 类用于表示一个学生实体,包含学生的基本信息和相关操作。
 */
public class Student {
    private int id; // 学生的ID,唯一标识一个学生
    private int age; // 学生的年龄
    private String name; // 学生的姓名
    private String gender; // 学生的性别
    private String password; // 学生的密码,用于系统登录
    private String email; // 学生的电子邮件地址
    private String hobbies; // 学生的兴趣爱好,以字符串形式存储
    private String introduction; // 学生的自我介绍

    // 无参构造函数,创建一个Student对象时不初始化任何属性
    public Student() {}

    // Getter 和 Setter 方法,用于获取和设置Student对象的属性

    // ID相关的Getter和Setter
    public int getId() {
        return id; // 返回学生ID
    }
    public void setId(int id) {
        this.id = id; // 设置学生ID
    }

    // 年龄相关的Getter和Setter
    public int getAge() {
        return age; // 返回年龄
    }
    public void setAge(int age) {
        this.age = age; // 设置年龄
    }

    // 姓名相关的Getter和Setter
    public String getName() {
        return name; // 返回姓名
    }
    public void setName(String name) {
        this.name = name; // 设置姓名
    }

    // 性别相关的Getter和Setter
    public String getGender() {
        return gender; // 返回性别
    }
    public void setGender(String gender) {
        this.gender = gender; // 设置性别
    }

    // 密码相关的Getter和Setter
    public String getPassword() {
        return password; // 返回密码
    }
    public void setPassword(String password) {
        this.password = password; // 设置密码
    }

    // 电子邮件相关的Getter和Setter
    public String getEmail() {
        return email; // 返回电子邮件地址
    }
    public void setEmail(String email) {
        this.email = email; // 设置电子邮件地址
    }

    // 兴趣爱好相关的Getter和Setter
    public String getHobbies() {
        return hobbies; // 返回兴趣爱好
    }
    public void setHobbies(String hobbies) {
        this.hobbies = hobbies; // 设置兴趣爱好
    }

    // 自我介绍相关的Getter和Setter
    public String getIntroduction() {
        return introduction; // 返回自我介绍
    }
    public void setIntroduction(String introduction) {
        this.introduction = introduction; // 设置自我介绍
    }
}
第 4 部分:数据库连接服务
  1. 创建 DBConnection 类:实现获取数据库连接的方法。
package  ; // 指定该类所在的包名  根据自己的项目进行更改

import java.sql.Connection; // 导入Java SQL Connection接口
import java.sql.DriverManager; // 导入 DriverManager 类,用于加载数据库驱动
import java.sql.SQLException; // 导入 SQLException,用于捕获获数据库异常

/**
 * DBConnection 类用于建立和管理与MySQL数据库的连接。
 * 提供一个静态方法 getConnection() 用于获取数据库连接实例。
 */
public class DBConnection {
    // 定义数据库驱动类名,用于Class.forName() 方法加载驱动
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    // 定义数据库连接URL,包括数据库地址、端口、数据库名以及连接参数
    private static final String URL = "jdbc:mysql://localhost:3306/student?useSSL=false&serverTimezone=UTC";
    // 定义数据库的用户名
    private static final String USERNAME = "root";
    // 定义数据库的密码
    private static final String PASSWORD = "123456";

    // 私有成员变量 conn 用于存储数据库连接对象
    private Connection conn;

    /**
     * 获取数据库连接的方法。
     * 首先尝试加载数据库驱动,然后使用 DriverManager 获取数据库连接。
     * @return 返回一个 Connection 对象,表示与数据库的连接。
     */
    public Connection getConnection() {
        try {
            // 加载并注册 MySQL JDBC 驱动
            Class.forName(DRIVER);
            // 通过 DriverManager 获取数据库连接
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            // 如果连接成功,打印确认信息
            System.out.println("MySQL JDBC driver is loaded and connection is established.");
            
        } catch (ClassNotFoundException e) {
            // 如果找不到 JDBC 驱动类,打印错误信息并输出堆栈跟踪
            System.out.println("MySQL JDBC driver is not found.");
            e.printStackTrace();
        } catch (SQLException e) {
            // 如果数据库连接失败,输出堆栈跟踪
            e.printStackTrace();
        }
        // 返回数据库连接对象
        return conn;
    }
}
  1. 创建 DatabaseService 类:封装数据库连接逻辑。
第 5 部分:数据访问对象 (DAO)
  1. 创建 StudentDAO 类:实现插入学生信息到数据库的方法。
package  ; // 指定该类所在的包名 根据自己的项目进行更改

import java.sql.Connection; // 导入Java的数据库连接接口
import java.sql.PreparedStatement; // 导入PreparedStatement,用于预编译SQL语句
import java.sql.SQLException; // 导入SQLException,用于捕获数据库异常
import java.util.logging.Level; // 导入日志记录级别
import java.util.logging.Logger; // 导入Java的日志记录器

/**
 * StudentDAO类用于处理与学生相关的数据库操作。
 */
public class StudentDAO {
    // 获取Logger实例,用于记录日志
    private static final Logger logger = Logger.getLogger(StudentDAO.class.getName());
    // 数据库连接服务,用于获取数据库连接
    private DBConnection dbService = new DBConnection(); 

    /**
     * 将学生信息插入数据库的方法。
     * @param student 要插入的学生对象
     * @return 操作结果,包含是否成功和消息
     */
    public Result insertStudent(Student student) {
        // 定义SQL插入语句
        String sql = "INSERT INTO info (name, email, age, gender, password, hobbies, introduction) VALUES (?, ?, ?, ?, ?, ?, ?)";
        try (Connection conn = dbService.getConnection(); // 获取数据库连接
             PreparedStatement pstmt = conn.prepareStatement(sql)) { // 创建PreparedStatement对象

            // 设置PreparedStatement参数
            pstmt.setString(1, student.getName());
            pstmt.setString(2, student.getEmail());
            pstmt.setInt(3, student.getAge());
            pstmt.setString(4, student.getGender());
            pstmt.setString(5, student.getPassword());
            pstmt.setString(6, student.getHobbies());
            pstmt.setString(7, student.getIntroduction());

            // 打印接收到的学生数据
            logger.log(Level.INFO, "接收到的学生数据: 名字={0}, 邮箱={1}, 年龄={2}, 性别={3}, 爱好={4}, 简介={5}",
                       new Object[]{student.getName(), student.getEmail(), student.getAge(), student.getGender(),
                                    student.getHobbies(), student.getIntroduction()});

            int affectedRows = pstmt.executeUpdate(); // 执行SQL语句
            if (affectedRows > 0) {
                logger.log(Level.INFO, "数据插入成功,影响行数:{0}", affectedRows);
                return new Result(true, "注册成功");
            } else {
                logger.log(Level.WARNING, "数据插入失败,没有行受到影响");
                return new Result(false, "注册失败");
            }
        } catch (SQLException e) {
            logger.log(Level.SEVERE, "数据库错误: " + e.getMessage(), e); // 记录数据库异常
            return new Result(false, "数据库错误: " + e.getMessage());
        }
    }
}
  1. 异常处理:在 DAO 类中添加异常处理逻辑。
第 6 部分:Servlet 处理 HTTP 请求
  1. 创建 RegServlet 类:处理用户注册请求。
package   ; // 定义了该Servlet类所属的包名 根据自己的项目进行补充

import jakarta.servlet.ServletException; // 导入Servlet异常处理类
import jakarta.servlet.annotation.WebServlet; // 用于定义Servlet的注解
import jakarta.servlet.http.HttpServlet; // 扩展HttpServlet以创建Servlet
import jakarta.servlet.http.HttpServletRequest; // 用于获取客户端请求
import jakarta.servlet.http.HttpServletResponse; // 用于发送响应客户端
import java.io.IOException; // 导入IOException类

// 使用@WebServlet注解将此Servlet映射到"/RegServlet"路径
@WebServlet("/RegServlet")
public class RegServlet extends HttpServlet {
    private static final long serialVersionUID = 1L; // 用于序列化

    // 处理POST请求的方法
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 从请求中获取表单数据
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        String password = request.getParameter("password");
        String gender = request.getParameter("gender");
        String ageStr = request.getParameter("age");
        String[] hobbiesArray = request.getParameterValues("hobby"); // 获取兴趣爱好数组
        String introduction = request.getParameter("introduction");

        // 将兴趣爱好数组转换为逗号分隔的字符串
        String hobbies = (hobbiesArray != null) ? String.join(", ", hobbiesArray) : "";

        // 创建Student对象并设置属性
        Student student = new Student();
        student.setName(name);
        student.setEmail(email);
        student.setGender(gender);
        student.setPassword(password);
        student.setAge(Integer.parseInt(ageStr)); // 将年龄字符串转换为整数
        student.setHobbies(hobbies);
        student.setIntroduction(introduction);

        // 创建StudentDAO对象处理数据库操作
        StudentDAO studentDAO = new StudentDAO();
        // 调用insertStudent方法尝试将学生信息插入数据库
        Result result = studentDAO.insertStudent(student);

        // 根据数据库操作结果重定向到相应页面
        if (result.isSuccess()) { 
            response.sendRedirect("success.jsp"); // 成功则跳转到成功页面
        } else {
            response.sendRedirect("error.jsp"); // 失败则跳转到错误页面
        }
    }

    // 处理GET请求的方法,可以选择显示注册表单或重定向到注册页面
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendRedirect("index.jsp"); // 默认重定向到注册页面
    }
}
  1. 获取请求参数:从 HTTP 请求中获取用户输入。
  2. 调用 DAO 方法:使用获取的数据调用 DAO 类的方法。
  3. 重定向:根据操作结果重定向到成功或错误页面。
第 7 部分:创建 JSP 页面
  1. 创建 index.jsp:用户注册表单页面。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <title>用户注册页面</title>
    <style>
        body {
            /* 设置页面主体样式,使用Arial字体,居中显示,背景白色 */
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin:  return 0;
            background-color: #fff;
        }
        .background-image {
            /* 设置背景图片样式,固定在底部,覆盖背景 */
            position: fixed;
            bottom: 0;
            left: 0;
            width: 500px;
            height: 320px;
            background-image: url('bg.png');
            background-size: cover;
            z-index: -1;
        }
        .container {
            /* 设置表单容器样式,半透明背景,圆角,阴影效果 */
            width: 600px;
            padding: 20px;
            background-color: rgba(255, 255, 255, 0.9);
            border-radius: 8px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(10px);
            display: flex;
            flex-direction: column;
        }
        /* 其他样式类定义,如.form-group, .hobbies, .register-btn 等,用于设置表单元素的布局和外观 */
    </style>
</head>
<body>
    <div class="background-image"></div>
    <div class="container">
        <h2>用户注册</h2>
        <form action="RegServlet" method="post">
            <!-- 昵称输入框 -->
            <div class="form-group">
                <label for="name">昵称:</label>
                <input type="text" id="name" name="name" required>
            </div>
            <!-- 邮箱输入框 -->
            <div class="form-group">
                <label for="email">注册邮箱:</label>
                <input type="email" id="email" name="email" required>
            </div>
            <!-- 密码输入框 -->
            <div class="form-group">
                <label for="password">密码:</label>
                <input type="password" id="password" name="password" required>
            </div>
            <!-- 性别单选按钮 -->
            <div class="form-group">
                <label>性别:</label>
                <input type="radio" id="male" name="gender" value="male">
                <label for="male">男</label>
                <input type="radio" id="female" name="gender" value="female">
                <label for="female">女</label>
            </div>
            <!-- 年龄输入框 -->
            <div class="form-group">
                <label for="age">年龄:</label>
                <input type="number" id="age" name="age" required>
            </div>
            <!-- 兴趣爱好多选框 -->
            <div class="form-group">
                <label>兴趣爱好:</label>
                <div class="hobbies">
                    <!-- 爱好1 -->
                    <input type="checkbox" id="hobby1" name="hobby" value="hobby1">
                    <label for="hobby1">爱好1</label>
                    <!-- 爱好2 -->
                    <input type="checkbox" id="hobby2" name="hobby" value="hobby2">
                    <label for="hobby2">爱好2</label>
                    <!-- 爱好3 -->
                    <input type="checkbox" id="hobby3" name="hobby" value="hobby3">
                    <label for="hobby3">爱好3</label>
                </div>
                <div class="hobbies">
                    <!-- 爱好4 -->
                    <input type="checkbox" id="hobby4" name="hobby" value="hobby4">
                    <label for="hobby4">爱好4</label>
                    <!-- 爱好5 -->
                    <input type="checkbox" id="hobby5" name="hobby" value="hobby5">
                    <label for="hobby5">爱好5</label>
                    <!-- 爱好6 -->
                    <input type="checkbox" id="hobby6" name="hobby" value="hobby6">
                    <label for="hobby6">爱好6</label>
                </div>
            </div>
            <!-- 自我介绍文本域 -->
            <div class="form-group">
                <label for="introduction">自我介绍:</label>
                <textarea id="introduction" name="introduction" maxlength="100" required></textarea>
            </div>
            <!-- 注册按钮 -->
            <button type="submit" class="register-btn">立即注册</button>
        </form>
    </div>
</body>
</html>
  1. 创建 success.jsp:注册成功页面。
  2. 创建 error.jsp:注册失败页面。
第 8 部分:测试应用程序
  1. 部署应用程序:将应用程序部署到服务器(如 Tomcat)。
  2. 测试注册功能:填写表单并提交,检查是否正确重定向。
  3. 检查数据库:确认数据已正确插入数据库。
第 9 部分:调试和错误处理
  1. 查看日志:了解如何查看和解读日志文件。
  2. 常见问题解决:提供一些常见问题的解决方案。
第 10 部分:项目优化和扩展
  1. 使用连接池:介绍如何使用连接池来优化数据库连接。
  2. 添加更多功能:提供思路如何添加更多功能到应用程序。

结语

一个迷茫的大学生

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/923249.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C 语言面向对象

面向对象的基本特性&#xff1a;封装&#xff0c;继承&#xff0c;多态 1.0 面向过程概念 当我们在编写程序时&#xff0c;通常采用以下步骤&#xff1a; 1. 将问题的解法分解成若干步骤 2. 使用函数分别实现这些步骤 3. 依次调用这些函数 这种编程风格的被称作 面向过程…

aws服务--机密数据存储KMS(1)介绍和使用

在AWS(Amazon Web Services)中存储机密数据时,安全性和合规性是最重要的考虑因素。AWS 提供了多个服务和工具,帮助用户确保数据的安全性、机密性以及合规性。AWS Secrets Manager、KMS(Key Management Service)是推荐的存储机密数据的AWS服务和最佳实践。这里先看KMS。 …

ArcGIS应用指南:ArcGIS制作局部放大地图

在地理信息系统&#xff08;GIS&#xff09;中&#xff0c;制作详细且美观的地图是一项重要的技能。地图制作不仅仅是简单地将地理数据可视化&#xff0c;还需要考虑地图的可读性和美观性。局部放大图是一种常见的地图设计技巧&#xff0c;用于展示特定区域的详细信息&#xff…

【案例学习】如何使用Minitab实现包装过程的自动化和改进

Masimo 是一家全球性的医疗技术公司&#xff0c;致力于开发和生产各种行业领先的监控技术&#xff0c;包括创新的测量、传感器和患者监护仪。在 Masimo Hospital Automation 平台的助力下&#xff0c;Masimo 的连接、自动化、远程医疗和远程监控解决方案正在改善医院内外的护理…

【JavaEE初阶】多线程初阶下部

文章目录 前言一、volatile关键字volatile 能保证内存可见性 二、wait 和 notify2.1 wait()方法2.2 notify()方法2.3 notifyAll()方法2.4 wait 和 sleep 的对比&#xff08;面试题&#xff09; 三、多线程案例单例模式 四、总结-保证线程安全的思路五、对比线程和进程总结 前言…

【小白学机器学习33】 大数定律python的 pandas.Dataframe 和 pandas.Series基础内容

目录 0 总结 0.1pd.Dataframe有一个比较麻烦琐碎的地方&#xff0c;就是引号 和括号 0.2 pd.Dataframe关于括号的原则 0.3 分清楚几个数据类型和对应的方法的范围 0.4 几个数据结构的构造关系 list → np.array(list) → pd.Series(np.array)/pd.Dataframe 1 python 里…

《用Python画蔡徐坤:艺术与编程的结合》

简介 大家好&#xff01;今天带来一篇有趣的Python编程项目&#xff0c;用代码画出知名偶像蔡徐坤的形象。这个项目使用了Python的turtle库&#xff0c;通过简单的几何图形和精心设计的代码来展示艺术与编程的结合。 以下是完整的代码和效果介绍&#xff0c;快来试试看吧&…

OSG开发笔记(三十三):同时观察物体不同角度的多视图从相机技术

​若该文为原创文章&#xff0c;未经允许不得转载 本文章博客地址&#xff1a;https://blog.csdn.net/qq21497936/article/details/143932273 各位读者&#xff0c;知识无穷而人力有穷&#xff0c;要么改需求&#xff0c;要么找专业人士&#xff0c;要么自己研究 长沙红胖子Qt…

数据结构(Java版)第二期:包装类和泛型

目录 一、包装类 1.1. 基本类型和对应的包装类 1.2. 装箱和拆箱 1.3. 自动装箱和自动拆箱 二、泛型的概念 三、引出泛型 3.1. 语法规则 3.2. 泛型的优点 四、类型擦除 4.1. 擦除的机制 五、泛型的上界 5.1. 泛型的上界的定义 5.2. 语法规则 六、泛型方法 6.1…

ffmpeg 视频滤镜:高斯模糊-gblur

滤镜描述 gblur 官网地址 > FFmpeg Filters Documentation 这个滤镜会将视频变得模糊。 滤镜使用 参数 gblur AVOptions:sigma <float> ..FV.....T. set sigma (from 0 to 1024) (default 0.5)steps <int> ..FV.....T…

vue中路由缓存

vue中路由缓存 问题描述及截图解决思路关键代码及打印信息截图 问题描述及截图 在使用某一平台时发现当列表页码切换后点击某一卡片进入详情页后&#xff0c;再返回列表页时页面刷新了。这样用户每次看完详情回到列表页都得再重新输入自己的查询条件&#xff0c;或者切换分页到…

eclipse-git项目提示NO-HEAD

1、出现该问题的过程 本人在用eclipse拉取git代码&#xff0c;刚拉取完&#xff0c;可能还没来得及跟本地的分支合并&#xff0c;电脑就卡动了。无奈只能重启电脑&#xff0c;打开eclipse&#xff0c;maven项目后面就出现了xxx NO-HEAD的提示。 2、问题解决 根据错误提示&am…

网络安全与加密

1.Base64简单说明描述&#xff1a;Base64可以成为密码学的基石&#xff0c;非常重要。特点&#xff1a;可以将任意的二进制数据进行Base64编码结果&#xff1a;所有的数据都能被编码为并只用65个字符就能表示的文本文件。65字符&#xff1a;A~Z a~z 0~9 / 对文件进行base64编码…

goframe开发一个企业网站 在vue-next-admin 显示验证码 19

index.go 文件中的代码&#xff0c;我将为该文件中的主要功能和方法添加注释&#xff0c;并生成一篇 Markdown 格式的文章。这将包括对每个函数的用途、输入参数和返回值的简要说明。 index.go 包和导入 package adminimport ("context""errors""gf…

数据库的联合查询

数据库的联合查询 简介为什么要使⽤联合查询多表联合查询时MYSQL内部是如何进⾏计算的构造练习案例数据案例&#xff1a;⼀个完整的联合查询的过程 内连接语法⽰例 外连接语法 ⽰例⾃连接应⽤场景示例表连接练习 ⼦查询语法单⾏⼦查询多⾏⼦查询多列⼦查询在from⼦句中使⽤⼦查…

Oracle 23ai 对应windows版本安装配置PLSQL导入pde文件navicat连接Oracle

因为有一个pde文件需要查看里面的数据&#xff0c;所以这次需要配置本地oracle数据库&#xff0c;并且导入数据&#xff0c;因为还有navicat&#xff0c;所以就想用navicat去连接查看。 1、找到官网。 Get Started with Oracle Database 23ai | Oracle 2、下载windows版本。…

Juc01_多线程概述、四种实现方式、常用方法API、生命周期、买票案例、synchronized锁

目录 本章讲述内容&#xff1a;多线程概述、四种实现方式、常用方法API、生命周期、买票案例、synchronized锁 ①. 多线程的概述 ②. 多线程的实现方式 ①. 继承Thread ②. 实现Runnable接口 ③. Callable接口(创建线程) ④. 线程池 ③. 设置和获取线程名称 ④. 线程…

一个高度可扩展的 Golang ORM 库【GORM】

GORM 是一个功能强大的 Golang 对象关系映射&#xff08;ORM&#xff09;库&#xff0c;它提供了简洁的接口和全面的功能&#xff0c;帮助开发者更方便地操作数据库。 1. 完整的 ORM 功能 • 支持常见的关系模型&#xff1a; • Has One&#xff08;一对一&#xff09; • …

ubuntu24挂载硬盘记录

1、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff1a; sudo fdisk -l 找到自己硬盘的分区 我的地址/dev/sda 2、显示硬盘及所属分区情况。在终端窗口中输入如下命令&#xff0c;格式化自己硬盘&#xff1a; sudo mkfs -t ext4 /dev/sda 3、在终端窗口中输入如下…

Flink四大基石之Window

为什么要用WIndow 在流处理应用中&#xff0c;数据是连续不断的&#xff0c;有时我们需要做一些聚合类的处理&#xff0c;例如&#xff1a;在过去的1分钟内有多少用户点击了我们的网页。 在这种情况下&#xff0c;我们必须定义一个窗口(window)&#xff0c;用来收集最近1分钟内…