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

JSP + Servlet + MySQL 完整 CRUD 實戰:從 DAO 封裝到前端交互

     編輯:Java 綜合教學

技術棧與依賴

  • Servlet API 3.0+、JSP 2.2
  • MySQL Connector/J 5.1.40
  • Apache Commons Lang3 3.5(工具類)
  • Tomcat 7/8/9

項目分層架構

src/
├── com.javaweb.bean.User           # 實體類
├── com.javaweb.dao
│   ├── DBDao.java                  # 通用數據訪問基類(反射+元數據映射)
│   └── UserDao.java                # 業務 DAO
├── com.javaweb.action
│   ├── Servlet.java                # 頁面跳轉 Servlet
│   └── ServletSql.java             # CRUD 業務 Servlet
└── com.javaweb.utils
    ├── DBUtlis.java                # 連接獲取/關閉
    ├── PropertiesUtil.java         # 配置文件讀取
    ├── DateUtlis.java              # 日期格式化
    └── StringUtlis.java            # UUID/駝峰轉換
WebContent/
├── index.jsp       # 首頁/添加表單
├── delete.jsp      # 刪除表單
├── update.jsp      # 修改表單
└── queryAll.jsp    # 列表展示
WEB-INF/
├── web.xml
└── config/db.properties

核心代碼精華

1. 通用 DBDao:反射實現 ResultSet → Object 自動映射

public class DBDao<T> {
    // 查詢:返回 List<T>
    public <T> List<T> findAll(String sql, Class<T> clazz, List<Object> params) {
        // 1. 獲取連接、PreparedStatement、ResultSet
        // 2. ResultSetMetaData 獲取列名/列數
        // 3. 遍歷 ResultSet,clazz.newInstance() 創建實例
        // 4. 列名轉駝峰 (camelName) 匹配字段,反射 setAccessible(true) 注入值
        // 5. 日期類型轉換 (DateUtlis)
        // 6. 關閉資源,返回列表
    }

    // 增刪改:返回影響行數
    public int execute(String sql, List<Object> params) {
        // PreparedStatement 設置參數 -> executeUpdate()
    }
}

2. 業務 UserDao:SQL 組裝與參數綁定

public class UserDao {
    private DBDao dao = new DBDao();

    public List<User> findAll() {
        String sql = "SELECT id, username, password FROM user";
        return dao.findAll(sql, User.class, null);
    }

    public int add(User u) {
        String sql = "INSERT INTO user(id, username, password) VALUES(?,?,?)";
        return dao.execute(sql, Arrays.asList(u.getId(), u.getUsername(), u.getPassword()));
    }

    public int delete(User u) {
        return dao.execute("DELETE FROM user WHERE id=?", Collections.singletonList(u.getId()));
    }

    public int update(User u) {
        StringBuilder sql = new StringBuilder("UPDATE user SET ");
        List<Object> params = new ArrayList<>();
        if (StringUtils.isNoneBlank(u.getUsername())) { sql.append("username=?, "); params.add(u.getUsername()); }
        if (StringUtils.isNoneBlank(u.getPassword())) { sql.append("password=?, "); params.add(u.getPassword()); }
        sql.deleteCharAt(sql.length()-1).append(" WHERE id=?"); // 去掉尾隨逗號
        params.add(u.getId());
        return dao.execute(sql.toString(), params);
    }
}

3. ServletSql:請求分發與流程控制

public class ServletSql extends HttpServlet {
    private UserDao dao = new UserDao();

    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String op = req.getParameter("op");
        if ("queryAll".equalsIgnoreCase(op)) queryAll(req, resp);
        else if ("add".equalsIgnoreCase(op)) add(req, resp);
        else if ("delete".equalsIgnoreCase(op)) delete(req, resp);
        else if ("update".equalsIgnoreCase(op)) update(req, resp);
    }

    private void queryAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setAttribute("list", dao.findAll());
        req.getRequestDispatcher("/queryAll.jsp").forward(req, resp); // 轉發保持請求屬性
    }

    private void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        if (dao.add(init(req, resp)) > 0) queryAll(req, resp); else resp.sendRedirect("index.jsp");
    }
    // delete/update 同理:操作成功後重新 queryAll 刷新列表
    private User init(HttpServletRequest req, HttpServletResponse resp) { ... 從參數構建 User 對象 ... }
}

4. 工具類亮點

  • DBUtlis:靜態塊讀取 db.properties,提供 getConnection()、多重 close() 重載、事務控制 rollback()/setAutoCommit()
  • PropertiesUtil:Class.getResourceAsStream("/config/db.properties") 載入類路徑配置
  • StringUtlis.camelName():USER_NAME → userName,解決數據庫下劃線與 Java 駝峰映射
  • DateUtlis:java.sql.Date ↔ String 互轉

前端 JSP 片段

<!-- index.jsp 添加表單 -->
<form action="<%=basePath%>/servletSql?op=add" method="post">
    <input name="id"> <input name="name"> <input name="password">
    <input type="submit" value="保存">
</form>

<!-- queryAll.jsp 列表 -->
<table>
    <c:forEach items="${list}" var="u">
        <tr><td>${u.id}</td><td>${u.username}</td><td>${u.password}</td>
        <td><a href="update.jsp?id=${u.id}">修改</a> <a href="delete.jsp?id=${u.id}">刪除</a></td></tr>
    </c:forEach>
</table>

配置文件

# db.properties
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/javaweb?useSSL=false
db.userName=root
db.password=123456789

運行驗證

  1. 啟動 Tomcat,訪問 https://localhost:8080/項目名/
  2. 首頁添加用戶 → 自動跳轉列表頁顯示新增記錄
  3. 點擊「修改」跳轉編輯頁 → 提交後列表刷新
  4. 點擊「刪除」確認後列表刷新

首頁

列表頁

遷移建議:Spring JDBC / MyBatis

  • JdbcTemplate 簡化連接/語句/結果集管理,RowMapper 替代反射映射
  • MyBatis XML/注解映射 SQL,動態 SQL 強大,分頁插件豐富
  • 事務管理:@Transactional 聲明式替代手動 try-catch
  • 連接池:HikariCP 替代手工 DriverManager

本例展示「手工構建 ORM 雛形」全過程,理解其原理後,框架學習將事半功倍。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved