一、基础知识

1. 实体类 Entity 到底干嘛?(必背)

  • 全称:实体 JavaBean,用来映射数据库数据表
  • 作用
    • 把数据库表里一行数据,封装成Java 对象(数据库表 → 对应一个 Entity 类)(表字段 → 对应类的成员变量
    • 统一存放数据,在 DAO、Servlet 之间传递数据
    • 规范数据格式,代码可读性极强
  • 规范写法:私有属性 + 无参 / 有参构造 + get/set + toString

2. DAO 层到底干嘛?(必背)

  1. 全称:Data Access Object 数据访问对象
  2. 作用
    • 只负责操作数据库:增删改查 SQL 全部写在这里
    • 分离代码:Servlet 只处理请求,不写 SQL
    • 复用 SQL 代码,一处修改全局生效
  3. 调用流程:Servlet → DAO → JDBC → MySQL

3. Java 注解 零基础详解

① 什么是注解

注解就是代码上的特殊标记,给 JVM / 服务器看,不执行业务逻辑,只做配置

② 项目核心注解

java

运行

@WebServlet("/login")
  • 作用:绑定 Servlet 访问路径
  • 含义:浏览器访问 项目名/login 自动执行当前 Servlet
  • 好处:抛弃繁琐 web.xml 配置,IDEA 开发首选

java

运行

@Override
  • 作用:校验方法是否正确重写
  • 写错方法名 / 参数直接爆红报错,防止低级错误

4. Java 泛型 <> 零基础详解

① 什么是泛型

限定集合中只能存放指定类型的数据,语法:集合<数据类型>

② 无泛型(缺点)

java

运行

List list = new ArrayList();
list.add(123);
list.add("abc"); // 乱存数据,取出强转极易报错

③ 带泛型(项目标准写法)

java

运行

// 只能存放User实体对象
List<User> userList = new ArrayList<>();

④ 泛型优点

  1. 编译阶段检查类型,报错提前发现
  2. 取出数据无需强制类型转换
  3. 代码简洁、安全、企业强制规范

二、项目技术栈 & 功能

  • 后端:Java + Servlet + JDBC + MySQL
  • 前端:HTML + CSS + JS + AJAX
  • 工具:IDEA + Tomcat
  • 功能:登录、用户列表、添加用户、删除用户

三、IDEA 基础操作(初学者一步一步跟着做)

1. 创建 Web 项目

  1. 打开 IDEA
  2. New → Project → Java Enterprise → Web Application
  3. 选择 Tomcat → 下一步 → 命名项目 → Finish

2. 项目目录结构(必须建对)

src

    com

        entity 实体层

        dao 数据库操作

        servlet 控制层

        util 工具类

web

    login.html 登录页

    index.html 主页

    WEB-INF

        lib 放 jar 包

3. 导入 jar 包(必须做)

  1. WEB-INF 下新建 lib
  2. 放入两个 jar:
    • mysql-connector-java-8.0.30.jar
    • gson-2.8.9.jar
  3. 右键 lib → Add as Library

4. 配置 Tomcat

  1. 右上角 Add Configuration → + → Tomcat Server → Local
  2. 选择 Tomcat 路径
  3. Deployment → 点 + → 选项目
  4. 启动项目(绿色三角)

四、MySQL 数据库(直接复制运行)

CREATE DATABASE userdb;
USE userdb;

CREATE TABLE user(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20) NOT NULL,
    password VARCHAR(20) NOT NULL,
    name VARCHAR(10),
    phone VARCHAR(11)
);

INSERT INTO user VALUES(NULL,'admin','123456','管理员','13800138000');

五、后端代码(逐行详细注释

先讲点基础知识:

数据库操作 5 大步骤(万能标准版 必背)

记忆:1 加载  2 连接  3 获取执行器   4 执行 SQL    5 关闭资源

最重要的 3 个对象(必须认识)

  • Connection:连接对象(通道)
  • PreparedStatement:SQL 执行对象(工具)
  • ResultSet:查询结果集(数据表)
try {
    // 1.加载(注册)驱动:告诉 Java 要连接的是 MySQL 数据库
    Class.forName("com.mysql.cj.jdbc.Driver");

    // 2. 获取连接(建立通道):Java 和数据库建立连接通道
    Connection conn = DriverManager.getConnection(url, user, password);

    // 3. 获取执行SQL的对象:拿到发送 SQL 语句的工具
    String sql = "SELECT * FROM user";
    PreparedStatement pstmt = conn.prepareStatement(sql);

    // 4. 执行SQL:执行 SQL 并处理结果
        //查询:executeQuery() → 返回结果集
        //增删改:executeUpdate() → 返回受影响行数
    ResultSet rs = pstmt.executeQuery();

    // 处理数据...

} catch (Exception e) {
    e.printStackTrace();
} finally {
    // 5. 关闭资源:顺序:结果集 → 执行器 → 连接
    try {
        if (rs != null) rs.close();
        if (pstmt != null) pstmt.close();
        if (conn != null) conn.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

1. 工具类 JDBCUtil.java(连接数据库)

package com.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

// JDBC 工具类:统一获取连接、关闭资源
public class JDBCUtil {

    // 数据库驱动 8.0版本
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";

    // 数据库地址:userdb是库名
    private static final String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=UTC&useSSL=false";

    // 数据库账号(改成你自己的)
    private static final String USER = "root";

    // 数据库密码(改成你自己的)
    private static final String PWD = "123456";

    // 静态代码块:项目启动只执行一次,加载驱动
    static {
        try {
            Class.forName(DRIVER);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获取数据库连接对象
    public static Connection getConn() {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(URL, USER, PWD);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    // 关闭 增删改资源
    public static void close(Connection conn, PreparedStatement pstmt) {
        try {
            if (pstmt != null) pstmt.close();
            if (conn != null) conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 关闭 查询资源(多结果集)
    public static void close(Connection conn, PreparedStatement pstmt, ResultSet rs) {
        try {
            if (rs != null) rs.close();
            if (pstmt != null) pstmt.close();
            if (conn != null) conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2. 实体类 User.java(Entity)

package com.entity;

// 实体类:对应数据库user表,封装一行数据
public class User {

    // 表字段 → 私有成员变量
    private Integer id;
    private String username;
    private String password;
    private String name;
    private String phone;

    // 无参构造(必须写,反射要用)
    public User() {}

    // 全参构造
    public User(Integer id, String username, String password, String name, String phone) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.name = name;
        this.phone = phone;
    }

    // get/set方法:外部访问私有变量
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

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

    public String getName() {
        return name;
    }

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

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

3. DAO 层 UserDao.java(数据库操作)

package com.dao;

import com.entity.User;
import com.util.JDBCUtil;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

// DAO层:只做数据库增删改查
public class UserDao {

    // 登录:根据账号密码查询用户
    public User login(String username, String pwd) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        User user = null;

        // SQL语句
        String sql = "SELECT * FROM user WHERE username=? AND password=?";

        try {
            // 获取连接
            conn = JDBCUtil.getConn();
            // 预编译SQL
            pstmt = conn.prepareStatement(sql);
            // 给?赋值
            pstmt.setString(1, username);
            pstmt.setString(2, pwd);
            // 查询,返回结果集
            rs = pstmt.executeQuery();

            // 如果有数据
            if (rs.next()) {
                user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setPassword(rs.getString("password"));
                user.setName(rs.getString("name"));
                user.setPhone(rs.getString("phone"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            JDBCUtil.close(conn, pstmt, rs);
        }

        return user;
    }

    // 查询所有用户
    // 泛型:List<User> 表示只能存User对象
    public List<User> findAll() {
        List<User> list = new ArrayList<>();
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        String sql = "SELECT * FROM user";

        try {
            conn = JDBCUtil.getConn();
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();

            // 遍历结果集
            while (rs.next()) {
                User u = new User();
                u.setId(rs.getInt("id"));
                u.setUsername(rs.getString("username"));
                u.setName(rs.getString("name"));
                u.setPhone(rs.getString("phone"));
                list.add(u);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(conn, pstmt, rs);
        }
        return list;
    }

    // 添加用户
    public int add(User user) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        int rows = 0;

        String sql = "INSERT INTO user VALUES(NULL,?,?,?,?)";

        try {
            conn = JDBCUtil.getConn();
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, user.getUsername());
            pstmt.setString(2, user.getPassword());
            pstmt.setString(3, user.getName());
            pstmt.setString(4, user.getPhone());

            rows = pstmt.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(conn, pstmt);
        }
        return rows;
    }

    // 删除用户
    public int delete(int id) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        int rows = 0;

        String sql = "DELETE FROM user WHERE id=?";

        try {
            conn = JDBCUtil.getConn();
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, id);
            rows = pstmt.executeUpdate();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtil.close(conn, pstmt);
        }
        return rows;
    }
}

4. 登录 Servlet(LoginServlet.java)

package com.servlet;

import com.dao.UserDao;
import com.entity.User;
import com.google.gson.Gson;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

// 注解:访问路径 /login
@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    // 创建DAO对象
    private UserDao userDao = new UserDao();
    // Gson:把对象转JSON字符串
    private Gson gson = new Gson();

    // 处理POST请求
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 设置编码,解决中文乱码
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");

        // 获取前端传来的账号密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        // 调用DAO登录方法
        User user = userDao.login(username, password);

        // 要返回给前端的数据
        Map<String, Object> map = new HashMap<>();

        if (user != null) {
            // 登录成功
            map.put("code", 200);
            map.put("msg", "登录成功");

            // 把用户存入Session,保持登录状态
            HttpSession session = request.getSession();
            session.setAttribute("loginUser", user);
        } else {
            // 登录失败
            map.put("code", 500);
            map.put("msg", "账号或密码错误");
        }

        // 转JSON并响应给前端
        String json = gson.toJson(map);
        response.getWriter().write(json);
    }
}

5. 用户列表 Servlet(UserListServlet.java)

package com.servlet;

import com.dao.UserDao;
import com.entity.User;
import com.google.gson.Gson;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/userList")
public class UserListServlet extends HttpServlet {

    private UserDao userDao = new UserDao();
    private Gson gson = new Gson();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=utf-8");

        // 查询所有用户
        List<User> list = userDao.findAll();

        // 转JSON
        String json = gson.toJson(list);

        // 响应
        response.getWriter().write(json);
    }
}

6. 添加用户 Servlet

package com.servlet;

import com.dao.UserDao;
import com.entity.User;
import com.google.gson.Gson;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/add")
public class AddServlet extends HttpServlet {
    private UserDao dao = new UserDao();
    private Gson gson = new Gson();

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");

        // 获取参数
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String name = request.getParameter("name");
        String phone = request.getParameter("phone");

        // 封装对象
        User u = new User();
        u.setUsername(username);
        u.setPassword(password);
        u.setName(name);
        u.setPhone(phone);

        // 调用添加
        int rows = dao.add(u);
        Map<String, Object> map = new HashMap<>();

        if (rows > 0) {
            map.put("msg", "添加成功");
        } else {
            map.put("msg", "添加失败");
        }

        response.getWriter().write(gson.toJson(map));
    }
}

7. 删除用户 Servlet

package com.servlet;

import com.dao.UserDao;
import com.google.gson.Gson;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@WebServlet("/delete")
public class DeleteServlet extends HttpServlet {
    private UserDao dao = new UserDao();
    private Gson gson = new Gson();

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("application/json;charset=utf-8");

        // 获取id
        int id = Integer.parseInt(request.getParameter("id"));

        int rows = dao.delete(id);
        Map<String, Object> map = new HashMap<>();

        if (rows > 0) {
            map.put("msg", "删除成功");
        } else {
            map.put("msg", "删除失败");
        }

        response.getWriter().write(gson.toJson(map));
    }
}

六、前端页面(逐行注释

1. 登录页面 login.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
    <style>
        /* 页面样式 */
        .box{width: 350px;margin: 100px auto;padding: 20px;border: 1px solid #ddd}
        input{width: 100%;margin: 10px 0;padding: 8px}
        button{width: 100%;padding: 10px;background: #007bff;color: white;border: none}
    </style>
</head>
<body>

<div class="box">
    <h2>系统登录</h2>
    <input id="username" placeholder="账号" value="admin">
    <input id="pwd" placeholder="密码" type="password" value="123456">
    <button onclick="login()">登录</button>
</div>

<script>
    // AJAX登录
    function login() {
        // 获取输入框的值
        let username = document.getElementById("username").value;
        let pwd = document.getElementById("pwd").value;

        // 创建AJAX对象
        let xhr = new XMLHttpRequest();

        // 配置请求
        xhr.open("POST", "login", true);

        // 设置请求头
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

        // 发送请求
        xhr.send("username=" + username + "&password=" + pwd);

        // 监听响应
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                // 解析JSON
                let res = JSON.parse(xhr.responseText);
                alert(res.msg);
                if (res.code == 200) {
                    // 跳主页
                    location.href = "index.html";
                }
            }
        }
    }
</script>
</body>
</html>

2. 主页 index.html(用户管理)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>用户管理</title>
    <style>
        body{margin: 0}
        .title{background: #007bff;color: white;padding: 15px}
        .content{padding: 20px}
        table{width: 100%;border-collapse: collapse;margin-top: 20px}
        td,th{border:1px solid #ddd;padding: 10px}
        input{padding: 6px}
        button{padding: 6px 12px;background: #007bff;color: white;border: none}
        .del{background: red}
    </style>
</head>
<body>

<div class="title">
    <h2>用户管理系统</h2>
</div>

<div class="content">
    <!-- 添加表单 -->
    <div>
        <input id="username" placeholder="账号">
        <input id="pwd" placeholder="密码">
        <input id="name" placeholder="姓名">
        <input id="phone" placeholder="电话">
        <button onclick="add()">添加</button>
    </div>

    <!-- 用户表格 -->
    <table>
        <tr>
            <th>ID</th>
            <th>账号</th>
            <th>姓名</th>
            <th>电话</th>
            <th>操作</th>
        </tr>
        <tbody id="userList"></tbody>
    </table>
</div>

<script>
    // 页面加载时查询所有用户
    window.onload = findAll;

    // 查询所有
    function findAll() {
        let xhr = new XMLHttpRequest();
        xhr.open("GET", "userList", true);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                let list = JSON.parse(xhr.responseText);
                let html = "";
                for (let i = 0; i < list.length; i++) {
                    let u = list[i];
                    html += "<tr>" +
                        "<td>" + u.id + "</td>" +
                        "<td>" + u.username + "</td>" +
                        "<td>" + u.name + "</td>" +
                        "<td>" + u.phone + "</td>" +
                        "<td><button class='del' onclick='del(" + u.id + ")'>删除</button></td>" +
                        "</tr>";
                }
                document.getElementById("userList").innerHTML = html;
            }
        }
    }

    // 添加
    function add() {
        let username = document.getElementById("username").value;
        let pwd = document.getElementById("pwd").value;
        let name = document.getElementById("name").value;
        let phone = document.getElementById("phone").value;

        let xhr = new XMLHttpRequest();
        xhr.open("POST", "add", true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
        xhr.send("username=" + username + "&password=" + pwd + "&name=" + name + "&phone=" + phone);
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(JSON.parse(xhr.responseText).msg);
                findAll();
            }
        }
    }

    // 删除
    function del(id) {
        if (!confirm("确定删除?")) return;
        let xhr = new XMLHttpRequest();
        xhr.open("GET", "delete?id=" + id, true);
        xhr.send();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(JSON.parse(xhr.responseText).msg);
                findAll();
            }
        }
    }
</script>
</body>
</html>

七、项目通用万能思路(所有 Web 项目都一样)

  1. 页面输入 → AJAX 发请求
  2. Servlet 接收参数
  3. Servlet 调用 DAO
  4. DAO 使用 JDBC 操作数据库
  5. 结果封装成 Entity 对象
  6. Servlet 返回 JSON
  7. AJAX 接收 → 渲染页面
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐