Java Web实现简易CRUD操作笔记

Java Web实现简易CRUD操作笔记(基于Servlet+MySQL)

一、项目概述

本次上课练习的代码是一套基于 Java Servlet + MySQL 实现的简易CRUD(增删改查)系统,核心围绕animal(动物)、person(人员)、student(学生)三张数据库表,通过Servlet接收前端HTTP请求,调用封装的数据库工具类完成数据操作,并返回JSON格式的响应结果。

整体技术栈:Servlet 3.0+(注解式配置)、JDBC(数据库连接)、MySQL(存储数据)、原生JSON字符串拼接(响应数据)。

二、核心工具类解析

2.1 DBConnection:数据库连接工具类

作用:封装MySQL数据库的连接创建与关闭逻辑,是所有数据库操作的基础。

java 复制代码
package com.qcby.sql;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConnection {
    // 数据库连接参数(硬编码)
    String driver = "com.mysql.jdbc.Driver";
    String url = "jdbc:mysql://localhost:3306/may7?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false";
    String user = "root";
    String password = "123456";
    public Connection conn;

    // 构造方法:创建连接
    public DBConnection() {
        try {
            Class.forName(driver);
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 关闭连接
    public void close() {
        try {
            this.conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

关键笔记

  • 采用DriverManager方式获取JDBC连接,驱动类为MySQL 5.x的com.mysql.jdbc.Driver(MySQL 8.x需改用com.mysql.cj.jdbc.Driver);
  • 连接参数(URL、用户名、密码)硬编码在代码中,后续可优化为配置文件(如db.properties);
  • 构造方法自动创建连接,提供close()方法释放连接资源。

2.2 MysqlUtil:数据库操作封装类

作用:基于DBConnection封装通用的增、删、改、查方法,简化Servlet层的数据库操作,同时提供查询结果转JSON的工具方法。

核心方法分类
方法名 作用 返回值
add(sql) 执行INSERT语句 int(1成功)
update(sql) 执行UPDATE语句 int(1成功)
del(sql) 执行DELETE语句 int(1成功)
getJsonBySql(sql, columns) 执行SELECT并转JSON String(JSON串)
listToJson(list, columns) 把查询结果集转标准JSON String(JSON串)

关键笔记

  • 增/删/改方法逻辑一致:获取连接→创建PreparedStatement→执行SQL→关闭资源→返回执行结果;
  • 查询方法会将ResultSet结果集转为ArrayList<String[]>,再通过listToJson拼接成固定格式的JSON(包含codemsgdata字段);
  • JSON拼接时处理了null值和双引号转义,避免JSON格式错误。

三、Servlet层CRUD实现(按功能分类)

Servlet是前端与数据库之间的中间层,通过@WebServlet注解配置访问路径,重写doGet方法处理GET请求,核心逻辑:接收请求参数→拼接SQL→调用MysqlUtil→返回JSON响应。

3.1 查询操作(ShowXXXServlet)

ShowStudentServlet为例:

java 复制代码
@WebServlet("/showStudent1")
public class ShowStudentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 拼接查询SQL
        String sql = "select * from student order by id desc";
        // 2. 指定数据库字段(与查询结果列对应)
        String[] columns = {"id","name","sex","age","sno","class_num"};
        // 3. 调用工具类获取JSON数据
        String data = MysqlUtil.getJsonBySql(sql, columns);
        // 4. 设置响应格式(UTF-8编码+JSON类型)
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF-8");
        // 5. 返回JSON数据
        resp.getWriter().append(data);
    }
}

通用规律

  • 所有查询Servlet(ShowAnimal/ShowPerson/ShowStudent)逻辑一致,仅SQL和字段数组不同;
  • 响应格式固定为application/json,编码UTF-8,避免中文乱码。

3.2 新增操作(AddXXXServlet)

AddAnimalServlet为例:

java 复制代码
@WebServlet("/addAnimal")
public class AddAnimalServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 获取前端传入的参数
        String color = req.getParameter("color");
        String age = req.getParameter("age");
        String type = req.getParameter("type");
        // 2. 拼接INSERT SQL
        String sql = "insert into animal(color,age,type) values('"+color+"','"+age+"','"+type+"')";
        // 3. 调用工具类执行新增
        int count = MysqlUtil.add(sql);
        // 4. 构造响应JSON(成功/失败)
        String data = count>0 ? "{\"code\":200,\"msg\":\"新增成功\"}" : "{\"code\":999,\"msg\":\"新增失败\"}";
        // 5. 返回响应
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF-8");
        resp.getWriter().append(data);
    }
}

通用规律

  • 通过req.getParameter()获取前端参数;
  • 拼接SQL时注意字符串参数加单引号,数值参数直接拼接;
  • 根据MysqlUtil.add()返回值(1/0)判断新增结果,返回固定格式的JSON。

3.3 修改操作(UpdateXXXServlet)

UpdatePersonServlet为例:

java 复制代码
@WebServlet("/updatePerson")
public class UpdatePersonServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 获取参数(含主键id)
        String id = req.getParameter("id");
        String name = req.getParameter("name");
        // ... 其他参数
        // 2. 拼接UPDATE SQL
        String sql = "update person set name = '"+name+"',... where id = "+id;
        // 3. 执行修改
        int count = MysqlUtil.update(sql);
        // 4. 构造响应JSON
        String data = count>0 ? "{\"code\":200,\"msg\":\"更新成功\"}" : "{\"code\":999,\"msg\":\"更新失败\"}";
        // 5. 返回响应(同新增)
        ...
    }
}

通用规律

  • 必须传入主键id,用于定位要修改的记录;
  • SQL拼接格式:update 表名 set 字段=值 where id=主键
  • 响应逻辑与新增一致,仅提示语不同。

3.4 删除操作(DelXXXServlet)

DelStudentServlet为例:

java 复制代码
@WebServlet("/delStudent")
public class DelStudentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1. 获取主键id
        String id=req.getParameter("id");
        // 2. 拼接DELETE SQL
        String sql="delete from student where id="+id;
        // 3. 执行删除
        int count=MysqlUtil.del(sql);
        // 4. 构造响应JSON
        String data = count>0 ? "{\"code\":200,\"msg\":\"删除成功\"}" : "{\"code\":999\"msg\":\"删除失败\"}";
        // 5. 返回响应(同新增)
        ...
    }
}

注意点

  • 代码中存在语法错误:"code\":999\"msg\"" 缺少逗号,应改为"code\":999,\"msg\":\"删除失败\"}
  • 删除操作仅需主键id,逻辑最简单,但需谨慎(无软删除,直接物理删除)。

四、代码优化建议(重点!)

本次练习代码实现了核心功能,但存在生产环境需优化的问题:

4.1 解决SQL注入问题(最高优先级)

当前SQL通过字符串拼接生成(如where id="+id),存在严重的SQL注入风险。
改进方案 :使用PreparedStatement参数化查询,示例:

java 复制代码
// 原拼接方式(危险)
String sql = "delete from student where id="+id;
// 优化后(参数化)
String sql = "delete from student where id=?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, id); // 绑定参数
pstmt.executeUpdate();

4.2 配置解耦

DBConnection中的数据库连接参数(URL、用户名、密码)抽离到db.properties配置文件,通过类加载器读取:

properties 复制代码
# db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/may7?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
jdbc.user=root
jdbc.password=123456

4.3 规范请求方式

增/删/改操作应使用POST请求(doPost方法),查询用GET,符合HTTP语义规范:

java 复制代码
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 把原doGet中的逻辑移到这里
}

4.4 优化JSON生成方式

手动拼接JSON字符串易出错,建议引入FastJSON/Jackson等工具:

java 复制代码
// 引入FastJSON示例
import com.alibaba.fastjson.JSONObject;

JSONObject result = new JSONObject();
result.put("code", 200);
result.put("msg", "新增成功");
String data = result.toJSONString();

4.5 完善异常处理

当前仅e.printStackTrace()打印异常,应添加日志记录(如SLF4J/Logback),并返回友好的错误提示。

4.6 参数校验

新增/修改时校验参数合法性(如年龄是否为数字、字段是否为空),避免非法参数导致SQL执行失败。

五、总结

本次练习代码完整覆盖了Servlet + JDBC 实现CRUD的核心流程:

  1. 数据库连接封装 → 2. 通用SQL操作封装 → 3. Servlet接收请求/处理业务/返回响应;
  2. 掌握了@WebServlet注解、请求参数获取、JSON响应格式、JDBC基础操作等关键知识点;
  3. 代码虽能运行,但在安全性(SQL注入)、可维护性(硬编码)、规范性(请求方式)等方面仍需优化。

这是Java Web入门的经典练习,理解这套代码的逻辑后,可进一步学习框架(如SSM/Spring Boot),但底层的JDBC和Servlet原理仍是基础。

相关推荐
Shadow(⊙o⊙)1 小时前
qt内详解信号和槽的基本概念+实例演示
开发语言·前端·c++·qt·学习
qq_381338501 小时前
Vue3 组合式函数设计模式:从基础封装到高级复用实战
前端·vue.js·设计模式
步十人1 小时前
【CSS】基础一篇过
前端·css
夕除1 小时前
spring boot 4
java·spring boot·后端
回眸一笑吟离歌1 小时前
edge浏览器更新后打开局域网服务报错:ERR_ADDRESS_UNREACHABLE
前端·edge
幽络源小助理1 小时前
在线图片处理工具源码, 多功能编辑格式转换HTML单文件版
前端·html
三产1 小时前
Hermes 教程 03:Skills 系统
android·java·数据库
starsky762381 小时前
spring boot——前后端分离
java·spring boot·后端
jiayong231 小时前
IDEA 中进行分支双向同步操作指南
java·ide·intellij-idea