SSM 框架實現增刪改查(CRUD)功能代碼詳解

以 “用户管理” 模塊為案例,基於 SSM(Spring+SpringMVC+MyBatis)框架實現用户的新增、查詢(單條 / 列表)、修改、刪除功能,全程遵循 “POJO→Mapper→Service→Controller” 的分層開發邏輯,附完整代碼與配置説明。

一、前期準備:項目結構與依賴

1.1 項目目錄結構

採用 Maven Web 項目結構,各層職責明確:

ssm-crud-demo/├── src/main/java/│   └── com/│       ├── pojo/          # 實體類(對應數據庫表)│       │   └── User.java│       ├── mapper/        # 持久層(MyBatis接口+XML)│       │   ├── UserMapper.java│       │   └── UserMapper.xml│       ├── service/       # 業務邏輯層(接口+實現)│       │   ├── UserService.java│       │   └── UserServiceImpl.java│       └── controller/    # 控制層(SpringMVC)│           └── UserController.java├── src/main/resources/    # 配置文件│   ├── jdbc.properties    # 數據庫配置│   ├── mybatis-config.xml # MyBatis全局配置│   ├── spring-mybatis.xml # Spring+MyBatis整合配置│   └── spring-mvc.xml     # SpringMVC配置└── src/main/webapp/       # Web資源    └── WEB-INF/        └── web.xml        # Web核心配置

1.2 Maven 依賴(pom.xml 核心配置)

需引入 Spring、SpringMVC、MyBatis、MySQL 驅動、連接池等依賴:

<properties>    <spring.version>4.3.20.RELEASE</spring.version>    <mybatis.version>3.4.6</mybatis.version></properties><dependencies>    <!-- Spring核心 -->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-context</artifactId>        <version>${spring.version}</version>    </dependency>    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-jdbc</artifactId>        <version>${spring.version}</version>    </dependency>    <!-- SpringMVC -->    <dependency>        <groupId>org.springframework</groupId>        <artifactId>spring-webmvc</artifactId>        <version>${spring.version}</version>    </dependency>    <!-- MyBatis及整合包 -->    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis</artifactId>        <version>${mybatis.version}</version>    </dependency>    <dependency>        <groupId>org.mybatis</groupId>        <artifactId>mybatis-spring</artifactId>        <version>1.3.2</version>    </dependency>    <!-- 數據庫相關 -->    <dependency>        <groupId>mysql</groupId>        <artifactId>mysql-connector-java</artifactId>        <version>5.1.47</version>    </dependency>    <dependency>        <groupId>com.alibaba</groupId>        <artifactId>druid</artifactId>        <version>1.1.10</version>    </dependency>    <!-- Web基礎 -->    <dependency>        <groupId>javax.servlet</groupId>        <artifactId>javax.servlet-api</artifactId>        <version>3.1.0</version>        <scope>provided</scope>    </dependency>    <!-- JSON支持(用於接口返回) -->    <dependency>        <groupId>com.fasterxml.jackson.core</groupId>        <artifactId>jackson-databind</artifactId>        <version>2.9.8</version>    </dependency></dependencies>

二、第一步:數據庫表與 POJO 實體類

2.1 數據庫表設計(MySQL)

創建tb_user表,存儲用户信息:

CREATE TABLE tb_user (    id INT PRIMARY KEY AUTO_INCREMENT COMMENT '用户ID',    username VARCHAR(50) NOT NULL COMMENT '用户名',    age INT COMMENT '年齡',    email VARCHAR(100) COMMENT '郵箱',    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間') ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

2.2 POJO 實體類(User.java)

對應tb_user表,屬性與字段一一映射,生成 getter/setter 方法:

package com.pojo;import java.util.Date;public class User {    private Integer id;         // 對應表中id字段    private String username;    // 對應表中username字段    private Integer age;        // 對應表中age字段    private String email;       // 對應表中email字段    private Date createTime;    // 對應表中create_time字段    // 無參構造(MyBatis映射必需)    public User() {}    // 帶參構造(用於新增/修改時快速創建對象)    public User(String username, Integer age, String email) {        this.username = username;        this.age = age;        this.email = email;    }    // 省略getter和setter方法(需手動生成或用Lombok)    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 Integer getAge() { return age; }    public void setAge(Integer age) { this.age = age; }    public String getEmail() { return email; }    public void setEmail(String email) { this.email = email; }    public Date getCreateTime() { return createTime; }    public void setCreateTime(Date createTime) { this.createTime = createTime; }}

三、第二步:持久層(MyBatis)實現

持久層負責與數據庫交互,通過 “Mapper 接口 + XML 映射文件” 實現 CRUD 的 SQL 操作。

3.1 Mapper 接口(UserMapper.java)

定義 CRUD 方法,方法名需與 XML 中 SQL 的id一致:

package com.mapper;import com.pojo.User;import org.apache.ibatis.annotations.Param;import java.util.List;public interface UserMapper {    // 1. 新增用户    int insertUser(User user);    // 2. 根據ID查詢單個用户    User selectUserById(@Param("id") Integer id); // @Param指定參數名,匹配XML中#{id}    // 3. 查詢所有用户(無參數)    List<User> selectAllUsers();    // 4. 根據ID修改用户(僅修改非空字段)    int updateUserById(User user);    // 5. 根據ID刪除用户    int deleteUserById(@Param("id") Integer id);}

3.2 Mapper XML 映射文件(UserMapper.xml)

編寫 SQL 語句,綁定 Mapper 接口,實現 “SQL 與代碼分離”:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- namespace必須與Mapper接口全路徑一致 --><mapper namespace="com.mapper.UserMapper">    <!-- 結果集映射:數據庫字段→POJO屬性(解決字段名與屬性名不一致問題,如create_time→createTime) -->    <resultMap id="UserResultMap" type="com.pojo.User">        <id column="id" property="id"/> <!-- 主鍵映射 -->        <result column="username" property="username"/>        <result column="age" property="age"/>        <result column="email" property="email"/>        <result column="create_time" property="createTime"/> <!-- 字段名與屬性名不一致,需顯式映射 -->    </resultMap>    <!-- 1. 新增用户:useGeneratedKeys獲取自增主鍵,keyProperty映射到POJO的id屬性 -->    <insert id="insertUser" parameterType="com.pojo.User" useGeneratedKeys="true" keyProperty="id">        INSERT INTO tb_user (username, age, email)        VALUES (#{username}, #{age}, #{email})    </insert>    <!-- 2. 根據ID查詢用户:resultMap引用上面定義的結果集映射 -->    <select id="selectUserById" parameterType="int" resultMap="UserResultMap">        SELECT id, username, age, email, create_time        FROM tb_user        WHERE id = #{id}    </select>    <!-- 3. 查詢所有用户:返回List<User>,resultMap指定映射規則 -->    <select id="selectAllUsers" resultMap="UserResultMap">        SELECT id, username, age, email, create_time        FROM tb_user        ORDER BY create_time DESC    </select>    <!-- 4. 根據ID修改用户:<if>標籤實現“非空字段才修改”(避免覆蓋原有值) -->    <update id="updateUserById" parameterType="com.pojo.User">        UPDATE tb_user        <set> <!-- <set>標籤自動處理逗號,避免SQL語法錯誤 -->            <if test="username != null and username != ''">username = #{username},</if>            <if test="age != null">age = #{age},</if>            <if test="email != null and email != ''">email = #{email},</if>        </set>        WHERE id = #{id}    </update>    <!-- 5. 根據ID刪除用户 -->    <delete id="deleteUserById" parameterType="int">        DELETE FROM tb_user        WHERE id = #{id}    </delete></mapper>

四、第三步:業務邏輯層(Service)實現

Service 層封裝業務邏輯,調用 Mapper 接口操作數據庫,同時通過 Spring 的@Transactional管理事務。

4.1 Service 接口(UserService.java)

定義業務方法,與 Mapper 接口方法對應,但可增加業務邏輯(如參數校驗):

package com.service;import com.pojo.User;import java.util.List;public interface UserService {    // 1. 新增用户(業務:校驗用户名非空)    boolean addUser(User user);    // 2. 根據ID查詢用户    User getUserById(Integer id);    // 3. 查詢所有用户    List<User> getAllUsers();    // 4. 修改用户(業務:校驗ID非空)    boolean updateUser(User user);    // 5. 刪除用户(業務:校驗ID存在)    boolean deleteUser(Integer id);}

4.2 Service 實現類(UserServiceImpl.java)

注入 Mapper 接口,實現業務方法,添加事務註解:

package com.service;import com.mapper.UserMapper;import com.pojo.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.List;// @Service標記為Spring管理的Service組件@Servicepublic class UserServiceImpl implements UserService {    // 注入MyBatis的Mapper接口(Spring通過MyBatis-Spring自動生成代理對象)    @Autowired    private UserMapper userMapper;    /**     * 新增用户:添加事務,若出現異常則回滾;業務校驗用户名非空     */    @Override    @Transactional // 聲明式事務:方法執行失敗時自動回滾數據庫操作    public boolean addUser(User user) {        // 業務校驗:用户名不能為空        if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {            throw new IllegalArgumentException("用户名不能為空!");        }        // 調用Mapper接口插入數據,返回影響行數(1為成功,0為失敗)        int rows = userMapper.insertUser(user);        return rows > 0;    }    /**     * 根據ID查詢用户:查詢操作無需事務     */    @Override    public User getUserById(Integer id) {        if (id == null || id <= 0) {            throw new IllegalArgumentException("用户ID無效!");        }        return userMapper.selectUserById(id);    }    /**     * 查詢所有用户     */    @Override    public List<User> getAllUsers() {        return userMapper.selectAllUsers();    }    /**     * 修改用户:事務管理,校驗ID非空     */    @Override    @Transactional    public boolean updateUser(User user) {        // 業務校驗:ID不能為空        if (user.getId() == null || user.getId() <= 0) {            throw new IllegalArgumentException("用户ID不能為空!");        }        // 校驗用户是否存在(避免修改不存在的用户)        User existUser = userMapper.selectUserById(user.getId());        if (existUser == null) {            throw new RuntimeException("用户不存在,無法修改!");        }        // 調用Mapper修改數據        int rows = userMapper.updateUserById(user);        return rows > 0;    }    /**     * 刪除用户:事務管理,校驗ID存在     */    @Override    @Transactional    public boolean deleteUser(Integer id) {        if (id == null || id <= 0) {            throw new IllegalArgumentException("用户ID無效!");        }        // 校驗用户是否存在        User existUser = userMapper.selectUserById(id);        if (existUser == null) {            throw new RuntimeException("用户不存在,無法刪除!");        }        // 調用Mapper刪除數據        int rows = userMapper.deleteUserById(id);        return rows > 0;    }}

五、第四步:控制層(SpringMVC)實現

Controller 層接收前端請求,調用 Service 層處理業務,返回結果(頁面跳轉或 JSON 數據)。此處以 “返回 JSON 接口” 為例(適配前後端分離或 AJAX 請求)。

5.1 Controller 類(UserController.java)

package com.controller;import com.pojo.User;import com.service.UserService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.*;import java.util.HashMap;import java.util.List;import java.util.Map;// @Controller標記為SpringMVC的控制器;@ResponseBody表示所有方法返回JSON(無需視圖渲染)@Controller@RequestMapping("/user") // 類級別的URL前綴:所有接口路徑以/user開頭@ResponseBodypublic class UserController {    // 注入Service組件    @Autowired    private UserService userService;    /**     * 1. 新增用户:POST請求,接收JSON格式參數     * URL:/user/add     * 請求體:{"username":"張三","age":20,"email":"zhangsan@xxx.com"}     */    @PostMapping("/add") // 對應HTTP POST請求,路徑為/user/add    public Map<String, Object> addUser(@RequestBody User user) { // @RequestBody接收JSON參數        Map<String, Object> result = new HashMap<>();        try {            boolean success = userService.addUser(user);            if (success) {                result.put("code", 200); // 成功狀態碼                result.put("msg", "新增用户成功!");                result.put("data", user.getId()); // 返回新增用户的ID            } else {                result.put("code", 500);                result.put("msg", "新增用户失敗!");            }        } catch (IllegalArgumentException e) {            // 捕獲業務校驗異常(如用户名空)            result.put("code", 400);            result.put("msg", e.getMessage());        } catch (Exception e) {            // 捕獲其他異常            result.put("code", 500);            result.put("msg", "服務器異常:" + e.getMessage());        }        return result;    }    /**     * 2. 根據ID查詢用户:GET請求,URL參數傳遞ID     * URL:/user/get?id=1     */    @GetMapping("/get") // 對應HTTP GET請求,路徑為/user/get    public Map<String, Object> getUserById(@RequestParam("id") Integer id) { // @RequestParam接收URL參數        Map<String, Object> result = new HashMap<>();        try {            User user = userService.getUserById(id);            if (user != null) {                result.put("code", 200);                result.put("msg", "查詢成功!");                result.put("data", user); // 返回用户詳情            } else {                result.put("code", 404);                result.put("msg", "用户不存在!");            }        } catch (IllegalArgumentException e</doubaocanvas>