一文图解使用springboot v3快速创建项目实现crud(新手看就好老鸟划走)

329 阅读6分钟

最近在自学java开发(为了以后能做点自己的项目工具不求人的状态下学的),今天给大家分享一个java springboot 3.x 新手快速入门方案。。。搞快点推荐java架构师徐庶的b站课程废话较少!!! 直接来吧!!

准备工作

  • Java IDE (开发工具 or 你喜欢的)
  • Navicat (sql可视化工具 or 你喜欢的)
  • Mysql (数据库 or 你喜欢的)
  • Postman(测试接口 or 你喜欢的)
  • Maven (管理依赖)
  • JDK (建议17以上了 别玩老古董的事情虽然很多老项目,但是我学只为我快速入门,请君自便)

spring官网 目前3.x算最新的了;最少需要java17

image.png

image.png

image.png

创建好是这样的

image.png

直接运行会报错数据库未连接

image.png

配置文件配置 application.properties 配置数据库链接

    1. spring.jpa.show-sql=true:这个配置项用于控制是否在控制台打印出 JDBC 的 SQL 语句。设置为 true 会显示所有的 SQL 语句,这对于调试非常有帮助。
    1. spring.jpa.properties.hibernate.format_sql=true:这个配置项用于控制是否对打印出的 SQL 语句进行格式化。设置为 true 会使得 SQL 语句在控制台中以更易读的格式显示。
    1. spring.jpa.hibernate.ddl-auto=update:这个配置项用于设置 Hibernate 自动创建或更新数据库表的策略。update 模式下,Hibernate 会在应用程序启动时根据实体类自动更新数据库表结构,但不会删除表。其他常见的选项包括 create(每次启动都会创建新表,删除旧表)、create-drop(在启动时创建新表,在关闭时删除表)、validate(对数据库表进行验证,确保它们与实体类匹配)和 none(不自动更新数据库表)。

image.png

image.png

Navicat创建数据库

image.png pom文件相关依赖

image.png

image.png

crud 实现目标

image.png

准备就绪crud开始

在Java开发中,三层架构是一种常用的软件设计模式,它将应用程序划分为三个逻辑部分:表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。这种架构有助于提高代码的可维护性、可扩展性和可重用性。下面详细介绍这三层及其在Java中的实现。

1. 表现层(Presentation Layer)

职责:负责与用户交互,处理用户的输入并显示结果。通常包括用户界面(UI),如Web页面、控制台或移动应用的界面。

技术实现

  • Web应用:使用Servlet、JSP、Spring MVC等。
  • 桌面应用:使用Swing、JavaFX等。
  • 移动应用:使用Android的Activity、Fragment等。

2. 业务逻辑层(Business Logic Layer)

职责:处理业务规则,执行具体的业务操作。这一层不涉及数据的直接访问,它依赖于数据访问层提供的数据,并将这些数据转换成业务逻辑所需的形式。

技术实现

  • Java:使用POJOs(Plain Old Java Objects),并通过接口与数据访问层交互。
  • 框架:Spring框架中的Service层,用于封装业务逻辑。

3. 数据访问层(Data Access Layer)

职责:负责数据的存取操作,与数据库进行交互。这一层通常包括数据库连接、SQL查询的执行等。

技术实现

  • JDBC:直接使用JDBC进行数据库操作。
  • ORM框架:如Hibernate、MyBatis等,它们提供了对象关系映射,简化了数据访问代码。
  • JPA(Java Persistence API) :通过实体类直接操作数据库。

实施示例(使用Spring框架)

代码示例(使用Spring boot3.x框架)crud小案例

pojo下面相关文件

package com.lhl.springdemo.pojo;

import jakarta.persistence.*;

// 需要指定主键
@Table(name = "table_user")
@Entity
public class User {
    /**
     * 用户ID
     */
    @Id // 指定主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 主键约束
    @Column(name = "user_id") // 字段映射
    private Integer userId;
    /**
     * 用户名
     */
    @Column(name = "user_name")
    private String userName;

    /**
     * 密码
     */
    @Column(name = "pass_word")
    private String password;
    /**
     * 年龄
     */
    @Column(name = "age")
    private Integer age;
    /**
     * 邮箱
     */
    @Column(name = "email")
    private String email;
    /**
     * 电话
     */
    @Column(name = "phone")
    private String phone;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getPassword() {
        return password;
    }

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

    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 String getPhone() {
        return phone;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }


    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + ''' +
                ", password='" + password + ''' +
                ", age=" + age +
                ", email='" + email + ''' +
                ", phone='" + phone + ''' +
                '}';
    }
}

统一返回处理

package com.lhl.springdemo.pojo;

import org.springframework.http.HttpStatus;

public class ResponseMessage<T> {
    // 属性
    private int code;
    private String message;
    private T data;

    // 构造函数
    public ResponseMessage(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    // 静态方法:成功响应 重构
    public static <T> ResponseMessage<T> success(T data) {
        return new ResponseMessage<>(HttpStatus.OK.value(), "请求成功", data);
    }

    public static <T> ResponseMessage<T> success() {
        return new ResponseMessage<>(HttpStatus.OK.value(), "请求成功", null);
    }

    // 静态方法:错误响应
    public static <T> ResponseMessage<T> error(String message) {
        return new ResponseMessage<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), message, null);
    }

    // Getter 和 Setter 方法
    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
// dto
package com.lhl.springdemo.pojo.dto;

import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;

public class UserDto {
    @Override
    public String toString() {
        return "UserDto{" +
                "userId=" + userId +
                ", userName='" + userName + ''' +
                ", password='" + password + ''' +
                ", age='" + age + ''' +
                ", email='" + email + ''' +
                ", phone='" + phone + ''' +
                '}';
    }

    private Integer userId; // 编辑用 也可重新建一个 editDto
    @NotBlank(message = "用户名不能为空") // 去除空格
    // @NotEmpty ""
    private String userName;
    @NotBlank(message = "密码不能为空")
    @Length(min = 6,max = 12)
    private String password;
    private String age;
    @Email(message = "邮箱格式不正确")
    private String email;
    private String phone;

    public String getPassword() {
        return password;
    }

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

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

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

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getUserId() {
        return userId;··
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

controller层的代码

package com.lhl.springdemo.controller;

import com.lhl.springdemo.pojo.ResponseMessage;
import com.lhl.springdemo.pojo.User;
import com.lhl.springdemo.pojo.dto.UserDto;
import com.lhl.springdemo.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

@RestController // 接口方法返回对接 转换成json文本
@RequestMapping("/user") // 前端访问接口地址 localhost:8088/user/**
public class UserController {
    // RESTful API是一种基于HTTP协议的架构风格,用于设计网络服务的接口
    @Autowired
    IUserService userService;
    // 增 @PostMapping("/add") 单个对象新增的没必要 batch的时候需要区分
    @PostMapping
    public ResponseMessage<User> addUser(@Validated @RequestBody UserDto user) {
       User newUser =  userService.add(user);
       return ResponseMessage.success(newUser);
    }
    // 删
    @DeleteMapping("/{userId}") // localhost:8088/user/1
    @GetMapping("/{userId}") // localhost:8088/user/1
    public ResponseMessage<User> delete(@PathVariable Integer userId){
        userService.delete(userId);
        return ResponseMessage.success();
    }
    // 查
    @GetMapping("/{userId}") // localhost:8088/user/1
    public ResponseMessage<User> get(@PathVariable Integer userId){
        User newUser = userService.findById(userId);
        return ResponseMessage.success(newUser);
    }
    // 改
    @PutMapping
    public ResponseMessage<User> edit(@Validated @RequestBody UserDto user) {
        User newUser =  userService.edit(user);
        return ResponseMessage.success(newUser);
    }
}

serviece层

// 接口
package com.lhl.springdemo.service;

import com.lhl.springdemo.pojo.User;
import com.lhl.springdemo.pojo.dto.UserDto;


public interface IUserService {
    /**
     * 新增用户
     * @param user 参数
     */
    User add(UserDto user);

    /**
     * 查询用户
     * @param userId 用户id
     * @return 当前用户对象
     */
    User findById(Integer userId);

    /**
     * 修改用户
     * @param user 修改当前用户对象
     * @return 修改当前用户对象
     */
    User edit(UserDto user);

    /**
     * 删除用户
     *
     * @param userId 用户id
     */
    void delete(Integer userId);
}
// service
package com.lhl.springdemo.service;

import com.lhl.springdemo.pojo.User;
import com.lhl.springdemo.pojo.dto.UserDto;
import com.lhl.springdemo.repository.UserRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service // spring的bean 就是一个 @Component
public class UserService implements IUserService {
    // 调用数据访问类
    @Autowired
    UserRepository userRepository;

    @Override
    public User add(UserDto user) {
        // 有id修改 没有新增
        User userEntity = new User();
        // 从user copy到 userEntity
        BeanUtils.copyProperties(user, userEntity);
        // userRepository.save(userEntity);
         return userRepository.save(userEntity);
    }

    @Override
    public User findById(Integer userId){
        return userRepository.findById(userId).orElse(null);
    }

    @Override
    public User edit(UserDto user) {
        // 有id修改 没有新增
        User userEntity = new User();
        // 从user copy到 userEntity
        BeanUtils.copyProperties(user, userEntity);
        // userRepository.save(userEntity);
        return userRepository.save(userEntity);
    }

    @Override
    public void delete(Integer userId){
        userRepository.deleteById(userId);
    }
}

继承 CrudRepository 即可

package com.lhl.springdemo.repository;

import com.lhl.springdemo.pojo.User;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository // spring bean 就是一个 @Component 职责更清晰
public interface UserRepository extends CrudRepository<User, Integer> {

}

全局异常捕获

package com.lhl.springdemo.exception;

import com.lhl.springdemo.pojo.ResponseMessage;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice // 统一处理异常
public class GlobalExceptionErrorHanded {
    Logger logger = LoggerFactory.getLogger(GlobalExceptionErrorHanded.class);
    @ExceptionHandler({Exception.class}) // 什么异常的统一处理 (所有异常的父类)
    public ResponseMessage<?> handlerException(Exception e, HttpServletRequest request, HttpServletResponse response) {
        // 记录日志
        logger.error("Handling global exception: ", e);

        // 构造 ResponseMessage 对象
        return new ResponseMessage<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "error", null);
    }
}

到此一个小而美的crud就结束了,当然这个只是快速起步。。。快速搭建一个简单的crud实现。。现在AI很快生成完毕了,但是初学的人还有很长的路需要走,报错了如何解决???基础语法,注意事项,基础概念这些你先得有你才能更好的用好的你的AI调教师!!!