【瑞吉外卖模块-CRUD】

下面是一个完整的 Spring Boot + MyBatis Plus CRUD 示例,以用户管理为例:

1. 项目结构和依赖

pom.xml 关键依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

application.yml 配置

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    map-underscore-to-camel-case: true
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: deleted
      logic-delete-value: 1
      logic-not-delete-value: 0

logging:
  level:
    com.example.mapper: debug

2. 实体类 (Entity)

package com.rongx.reggie.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.time.LocalDateTime;

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("user")
public class User {
    
    @TableId(type = IdType.AUTO)
    private Long id;
    
    private String username;
    
    private String password;
    
    private String email;
    
    private String phone;
    
    private Integer status;
    
    private Integer age;
    
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    
    @TableLogic
    private Integer deleted;
    
    // 版本号,用于乐观锁
    @Version
    private Integer version;
}

3. Mapper 接口

package com.rongx.reggie.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.rongx.reggie.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    
    // 可以在这里添加自定义的 SQL 方法
    // 例如:根据用户名查询用户
    // User selectByUsername(@Param("username") String username);
}

4. Service 接口和实现

Service 接口

package com.rongx.reggie.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.rongx.reggie.entity.User;

public interface UserService extends IService<User> {
    
    /**
     * 自定义业务方法:根据用户名查询用户
     */
    User getByUsername(String username);
    
    /**
     * 自定义业务方法:用户注册
     */
    boolean register(User user);
    
    /**
     * 自定义业务方法:更新用户状态
     */
    boolean updateStatus(Long id, Integer status);
}

Service 实现类

package com.rongx.reggie.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rongx.reggie.entity.User;
import com.rongx.reggie.mapper.UserMapper;
import com.rongx.reggie.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Override
    public User getByUsername(String username) {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getUsername, username);
        return this.getOne(wrapper);
    }

    @Override
    public boolean register(User user) {
        // 检查用户名是否已存在
        User existingUser = this.getByUsername(user.getUsername());
        if (existingUser != null) {
            throw new RuntimeException("用户名已存在");
        }
        
        // 密码加密(简单示例)
        String encryptedPassword = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(encryptedPassword);
        
        // 设置默认状态
        user.setStatus(1);
        
        return this.save(user);
    }

    @Override
    public boolean updateStatus(Long id, Integer status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        return this.updateById(user);
    }
}

5. Controller 层

package com.rongx.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rongx.reggie.common.R;
import com.rongx.reggie.entity.User;
import com.rongx.reggie.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    // ==================== 新增操作 ====================
    
    /**
     * 新增用户
     */
    @PostMapping
    public R<String> save(@RequestBody User user) {
        log.info("新增用户: {}", user);
        try {
            boolean success = userService.register(user);
            return success ? R.success("新增用户成功") : R.error("新增用户失败");
        } catch (Exception e) {
            log.error("新增用户异常", e);
            return R.error(e.getMessage());
        }
    }

    /**
     * 批量新增用户
     */
    @PostMapping("/batch")
    public R<String> saveBatch(@RequestBody List<User> users) {
        log.info("批量新增用户,数量: {}", users.size());
        boolean success = userService.saveBatch(users);
        return success ? R.success("批量新增成功") : R.error("批量新增失败");
    }

    // ==================== 查询操作 ====================

    /**
     * 根据ID查询用户
     */
    @GetMapping("/{id}")
    public R<User> getById(@PathVariable Long id) {
        log.info("根据ID查询用户: id={}", id);
        User user = userService.getById(id);
        return user != null ? R.success(user) : R.error("用户不存在");
    }

    /**
     * 查询所有用户
     */
    @GetMapping("/list")
    public R<List<User>> list() {
        List<User> users = userService.list();
        return R.success(users);
    }

    /**
     * 分页查询用户
     */
    @GetMapping("/page")
    public R<IPage<User>> page(
            @RequestParam(defaultValue = "1") int pageNum,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(required = false) String username,
            @RequestParam(required = false) String email) {
        
        log.info("分页查询用户: page={}, size={}, username={}, email={}", 
                pageNum, pageSize, username, email);
        
        // 创建分页对象
        Page<User> page = new Page<>(pageNum, pageSize);
        
        // 创建查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(username != null, User::getUsername, username)
               .like(email != null, User::getEmail, email)
               .orderByDesc(User::getCreateTime);
        
        // 执行分页查询
        IPage<User> userPage = userService.page(page, wrapper);
        
        return R.success(userPage);
    }

    /**
     * 条件查询用户列表
     */
    @GetMapping("/listByCondition")
    public R<List<User>> listByCondition(User user) {
        log.info("条件查询用户: {}", user);
        
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        
        // 动态添加查询条件
        if (user.getUsername() != null) {
            wrapper.like("username", user.getUsername());
        }
        if (user.getEmail() != null) {
            wrapper.like("email", user.getEmail());
        }
        if (user.getStatus() != null) {
            wrapper.eq("status", user.getStatus());
        }
        
        wrapper.orderByDesc("create_time");
        
        List<User> users = userService.list(wrapper);
        return R.success(users);
    }

    /**
     * 根据用户名查询用户
     */
    @GetMapping("/username/{username}")
    public R<User> getByUsername(@PathVariable String username) {
        log.info("根据用户名查询用户: username={}", username);
        User user = userService.getByUsername(username);
        return user != null ? R.success(user) : R.error("用户不存在");
    }

    // ==================== 更新操作 ====================

    /**
     * 更新用户信息
     */
    @PutMapping
    public R<String> update(@RequestBody User user) {
        log.info("更新用户: {}", user);
        boolean success = userService.updateById(user);
        return success ? R.success("更新成功") : R.error("更新失败");
    }

    /**
     * 批量更新用户
     */
    @PutMapping("/batch")
    public R<String> updateBatch(@RequestBody List<User> users) {
        log.info("批量更新用户,数量: {}", users.size());
        boolean success = userService.updateBatchById(users);
        return success ? R.success("批量更新成功") : R.error("批量更新失败");
    }

    /**
     * 更新用户状态
     */
    @PutMapping("/status/{id}")
    public R<String> updateStatus(@PathVariable Long id, @RequestParam Integer status) {
        log.info("更新用户状态: id={}, status={}", id, status);
        boolean success = userService.updateStatus(id, status);
        return success ? R.success("状态更新成功") : R.error("状态更新失败");
    }

    // ==================== 删除操作 ====================

    /**
     * 根据ID删除用户(逻辑删除)
     */
    @DeleteMapping("/{id}")
    public R<String> delete(@PathVariable Long id) {
        log.info("删除用户: id={}", id);
        boolean success = userService.removeById(id);
        return success ? R.success("删除成功") : R.error("删除失败");
    }

    /**
     * 批量删除用户
     */
    @DeleteMapping("/batch")
    public R<String> deleteBatch(@RequestBody List<Long> ids) {
        log.info("批量删除用户: ids={}", ids);
        boolean success = userService.removeByIds(ids);
        return success ? R.success("批量删除成功") : R.error("批量删除失败");
    }

    /**
     * 根据条件删除用户
     */
    @DeleteMapping("/byCondition")
    public R<String> deleteByCondition(@RequestBody User user) {
        log.info("根据条件删除用户: {}", user);
        
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (user.getUsername() != null) {
            wrapper.eq("username", user.getUsername());
        }
        if (user.getStatus() != null) {
            wrapper.eq("status", user.getStatus());
        }
        
        boolean success = userService.remove(wrapper);
        return success ? R.success("删除成功") : R.error("删除失败");
    }

    // ==================== 统计操作 ====================

    /**
     * 统计用户数量
     */
    @GetMapping("/count")
    public R<Long> count() {
        long count = userService.count();
        return R.success(count);
    }

    /**
     * 根据条件统计用户数量
     */
    @GetMapping("/countByCondition")
    public R<Long> countByCondition(User user) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if (user.getStatus() != null) {
            wrapper.eq("status", user.getStatus());
        }
        if (user.getUsername() != null) {
            wrapper.like("username", user.getUsername());
        }
        
        long count = userService.count(wrapper);
        return R.success(count);
    }
}

6. 配置类

MyBatis Plus 配置

package com.rongx.reggie.config;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.LocalDateTime;

@Slf4j
@Configuration
public class MybatisPlusConfig {

    /**
     * MyBatis Plus 插件配置
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        
        // 分页插件
        PaginationInnerInterceptor paginationInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        paginationInterceptor.setMaxLimit(1000L); // 单页分页条数限制
        paginationInterceptor.setOverflow(true);   // 页码超出后是否处理
        
        interceptor.addInnerInterceptor(paginationInterceptor);
        
        return interceptor;
    }

    /**
     * 自动填充处理器
     */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new MetaObjectHandler() {
            @Override
            public void insertFill(MetaObject metaObject) {
                log.info("开始插入填充...");
                this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
                this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
            }

            @Override
            public void updateFill(MetaObject metaObject) {
                log.info("开始更新填充...");
                this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
            }
        };
    }
}

7. 统一返回结果封装

package com.rongx.reggie.common;

import lombok.Data;
import java.util.HashMap;
import java.util.Map;

@Data
public class R<T> {
    private Integer code;
    private String msg;
    private T data;
    private Map<String, Object> map = new HashMap<>();

    public static <T> R<T> success(T object) {
        R<T> r = new R<>();
        r.data = object;
        r.code = 1;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R<T> r = new R<>();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }
}

8. 数据库表结构

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(100) NOT NULL COMMENT '密码',
  `email` varchar(100) DEFAULT NULL COMMENT '邮箱',
  `phone` varchar(20) DEFAULT NULL COMMENT '手机号',
  `status` int(1) DEFAULT '1' COMMENT '状态 0:禁用 1:正常',
  `age` int(3) DEFAULT NULL COMMENT '年龄',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `deleted` int(1) DEFAULT '0' COMMENT '逻辑删除 0:未删除 1:已删除',
  `version` int(11) DEFAULT '0' COMMENT '版本号',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_username` (`username`),
  KEY `idx_status` (`status`),
  KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

9. 测试用例

package com.rongx.reggie;

import com.rongx.reggie.entity.User;
import com.rongx.reggie.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.List;

@Slf4j
@SpringBootTest
class UserCRUDTests {

    @Autowired
    private UserService userService;

    @Test
    void testCRUD() {
        // 1. 新增
        User user = new User();
        user.setUsername("testuser");
        user.setPassword("123456");
        user.setEmail("test@example.com");
        user.setPhone("13800138000");
        userService.save(user);
        log.info("新增用户: {}", user);

        // 2. 查询
        User foundUser = userService.getById(user.getId());
        log.info("查询用户: {}", foundUser);

        // 3. 更新
        foundUser.setEmail("updated@example.com");
        userService.updateById(foundUser);
        log.info("更新用户: {}", foundUser);

        // 4. 删除(逻辑删除)
        userService.removeById(user.getId());
        log.info("删除用户完成");

        // 5. 批量操作
        List<User> users = Arrays.asList(
            createUser("user1", "user1@example.com"),
            createUser("user2", "user2@example.com"),
            createUser("user3", "user3@example.com")
        );
        userService.saveBatch(users);
        log.info("批量新增完成");
    }

    private User createUser(String username, String email) {
        User user = new User();
        user.setUsername(username);
        user.setPassword("123456");
        user.setEmail(email);
        return user;
    }
}

10. API 使用示例

10.1 新增用户

POST /user
Content-Type: application/json

{
  "username": "zhangsan",
  "password": "123456",
  "email": "zhangsan@example.com",
  "phone": "13800138000",
  "age": 25
}

10.2 分页查询

GET /user/page?pageNum=1&pageSize=10&username=zhang

10.3 条件查询

GET /user/listByCondition?username=zhang&status=1

10.4 更新用户

PUT /user
Content-Type: application/json

{
  "id": 1,
  "username": "zhangsan",
  "email": "newemail@example.com",
  "age": 26
}

10.5 删除用户

DELETE /user/1

11. 高级查询示例

复杂条件查询

// 在 Service 中实现复杂查询
public List<User> complexQuery(String keyword, Integer minAge, Integer maxAge, Integer status) {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    
    // 多个条件组合
    wrapper.and(qw -> qw
            .like(User::getUsername, keyword)
            .or()
            .like(User::getEmail, keyword)
            .or()
            .like(User::getPhone, keyword)
        )
        .ge(minAge != null, User::getAge, minAge)
        .le(maxAge != null, User::getAge, maxAge)
        .eq(status != null, User::getStatus, status)
        .orderByDesc(User::getCreateTime);
    
    return this.list(wrapper);
}

这个完整的 CRUD 示例涵盖了 Spring Boot + MyBatis Plus 的常见操作,包括:

  • ✅ 基础 CRUD 操作
  • ✅ 分页查询
  • ✅ 条件查询
  • ✅ 批量操作
  • ✅ 逻辑删除
  • ✅ 自动填充
  • ✅ 统一返回格式
  • ✅ 异常处理

您可以根据实际业务需求进行调整和扩展。

<think>根据用户引用和查询,用户想要获取瑞吉外卖项目的Java代码。从引用[2]中可以看到,该项目是黑马程序员的实战项目,视频教程在B站上有。引用[3]和[4]展示了一个通用返回结果类R的代码片段。但用户希望获取整个项目的代码。 需要注意的是,通常一个完整的项目代码不会直接在回答中提供,因为: 1. 项目代码量庞大,不适合在对话中展示 2. 涉及版权问题,该项目属于黑马程序员的教程内容 建议用户通过以下途径获取代码: 1. 官方教程配套资源(如黑马程序员官网或B站视频简介中的代码仓库链接) 2. GitHub等开源平台搜索(但需注意版权) 不过,我可以根据引用[3]和[4]提供通用返回类R的完整代码,并解释其作用。此外,还可以提供一个简单的示例(如控制器中使用R类的代码片段)。 下面先展示R类的代码(与引用[3][4]一致): ```java package com.itheima.reggie.common; import lombok.Data; import java.util.HashMap; import java.util.Map; @Data public class R<T> { private Integer code; //编码:1成功,0和其它数字为失败 private String msg; //错误信息 private T data; //数据 private Map<String, Object> map = new HashMap<>(); //动态数据 public static <T> R<T> success(T object) { R<T> r = new R<>(); r.data = object; r.code = 1; return r; } public static <T> R<T> error(String msg) { R<T> r = new R<>(); r.msg = msg; r.code = 0; return r; } public R<T> add(String key, Object value) { this.map.put(key, value); return this; } } ``` 然后展示一个使用R类的控制器示例: ```java @RestController @RequestMapping("/dish") public class DishController { @Autowired private DishService dishService; @GetMapping("/{id}") public R<Dish> getById(@PathVariable Long id) { Dish dish = dishService.getById(id); if (dish != null) { return R.success(dish); } return R.error("菜品不存在"); } } ``` 最后,建议用户通过正规渠道获取完整项目代码,并说明原因。 相关问题部分,根据项目学习可能产生的疑问生成。 </think> 根据您的需求,瑞吉外卖项目的完整Java代码可通过以下正规渠道获取: ### 1. 官方教程资源(推荐) 项目完整代码可在黑马程序员官方提供的B站教程配套资源中获取: - 📺 [B站视频教程](https://www.bilibili.com/video/BV13a411q753) - 💻 代码获取方式: ```markdown 1. 视频简介区查看GitHub仓库链接 2. 或访问黑马程序员官网获取课程配套资料 ``` 此教程包含完整的项目分层代码:Controller、Service、DAO、实体类等[^2]。 ### 2. 核心代码示例 以下为项目中的**通用返回结果封装类**(关键组件): ```java package com.itheima.reggie.common; import lombok.Data; import java.util.HashMap; import java.util.Map; @Data public class R<T> { private Integer code; // 1=成功, 0=失败 private String msg; // 错误信息 private T data; // 响应数据 private Map<String, Object> map = new HashMap<>(); // 动态数据 public static <T> R<T> success(T object) { R<T> r = new R<>(); r.data = object; r.code = 1; return r; } public static <T> R<T> error(String msg) { R<T> r = new R<>(); r.msg = msg; r.code = 0; return r; } public R<T> add(String key, Object value) { this.map.put(key, value); return this; } } ``` ▲ 此类用于标准化API响应格式(如`{code:1, data:{...}}`)[^3][^4] ### 3. 技术栈组成 | 层级 | 技术组件 | |-------------|--------------------------| | 前端 | HTML/CSS/JS, Vue.js | | 后端框架 | Spring Boot 2.x | | ORM | MyBatis-Plus | | 数据库 | MySQL | | 工具 | Lombok, Swagger API文档 | ### 4. 注意事项 - 🔒 完整代码涉及版权问题,需通过正规课程获取 - 核心业务模块包括: - 菜品管理模块CRUD操作) - 购物车与订单系统(Redis缓存) - JWT用户认证 - 数据统计报表
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值