Java Spring Boot Controller、Service、DAO实践

发布时间 2024-01-10 14:01:22作者: 进击的davis

如果你用过 Spring MVC,那就对 Controller、Service、DAO 三者的概念一定不陌生,我们通过 Controller 来接收请求和返回响应,具体的业务处理则放在 Service层 处理,而 DAO 则实现具体与数据库等持久层的操作。

今天从分层的角度来学习下在 Spring Boot 中的简单应用,业务场景也很简单,就是实现 用户信息 的增删改查,本文重在 这三者 的应用,涉及到更好设计的功能这里不讨论。

本人水平有限,主要针对新手学习用,如有不足,请大佬忽略或轻喷。

依赖

新建个 Spring Boot 项目,添加下面的依赖:

<!--  mysql driver      -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.1.0</version>
</dependency>
<!-- mp依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>
<!--   @Data     -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.30</version>
</dependency>
<!--  params validate -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

主要目录

目录结构如下图所示:

image.png

配置文件

application.yml内容:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    url: jdbc:mysql://{ip}:3306/mybatis_demo?&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF8&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true&rewriteBatchedStatements=true

后面的实现从 DAO -> Service -> Controller 依次实现。

DAO(Mapper)

新建个 UserInfoMapper.java

package com.example.springbootmybatisplusdemo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springbootmybatisplusdemo.entity.UserInfo;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

Service

实现简单的功能:

package com.example.springbootmybatisplusdemo.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.springbootmybatisplusdemo.entity.UserInfo;
import com.example.springbootmybatisplusdemo.mapper.UserInfoMapper;
import com.example.springbootmybatisplusdemo.utils.CryptoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserInfoServiceImpl implements UserInfoService<UserInfo> {

    @Autowired
    private UserInfoMapper userInfoMapper;

    private static final String salt = "crypto";

    public UserInfoServiceImpl() {
        super();
    }

    @Override
    public boolean createUserInfo(UserInfo userInfo) {
        // check if exist repeated user
        QueryWrapper qw = new QueryWrapper<>();
        qw.eq("phone", userInfo.getPhone());
        Long count = userInfoMapper.selectCount(qw);
        if (count > 0) return false;

        // crypto password
        String pwd = userInfo.getPassword() + salt;
        userInfo.setPassword(CryptoUtils.md5Sum(pwd));

        // insert into database
        int affected = userInfoMapper.insert(userInfo);
        if (affected != 1) return false;

        return true;
    }

    @Override
    public boolean deleteUserInfo(Long id) {
        // logic delete
        int affected = userInfoMapper.deleteById(id);
        if (affected != 1) return false;

        return true;
    }

    @Override
    public UserInfo getUserInfo(Long id) {
        // query user info by userId
        UserInfo user = userInfoMapper.selectById(id);
        return user;
    }

    @Override
    public boolean updateUserInfo(UserInfo userInfo) {
        // update table set ...
        int affected = userInfoMapper.updateById(userInfo);
        if (affected != 1) return false;

        return true;
    }
}

Controller

实现几个接口:

package com.example.springbootmybatisplusdemo.controller;

import com.example.springbootmybatisplusdemo.entity.UserInfo;
import com.example.springbootmybatisplusdemo.service.UserInfoServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserManagerController {

    @Autowired
    UserInfoServiceImpl userInfoService;

    @PostMapping("/register")
    public Object register(@RequestBody UserInfo userInfo) {
        boolean result = userInfoService.createUserInfo(userInfo);
        Map<String, Object> data = new HashMap<>();
        data.put("result", result);
        return data;
    }

    @DeleteMapping("/deregister/{id}")
    public Object deregister(@PathVariable("id") Long id) {
        boolean result = userInfoService.deleteUserInfo(id);
        Map<String, Object> data = new HashMap<>();
        data.put("result", result);
        return data;
    }

    @GetMapping("/info/{id}")
    public UserInfo getInfo(@PathVariable("id") Long id) {
        UserInfo user = userInfoService.getUserInfo(id);
        return user;
    }

    @PostMapping("/update/")
    public Object updateInfo(@RequestBody UserInfo userInfo) {
        userInfoService.updateUserInfo(userInfo);
        return null;
    }
}

最后在 启动入口处 加上注解:

package com.example.springbootmybatisplusdemo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.example.springbootmybatisplusdemo.mapper")
public class SpringbootMybatisPlusDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootMybatisPlusDemoApplication.class, args);
    }

}

p.s. UserInfo用户bean

package com.example.springbootmybatisplusdemo.entity;

import com.baomidou.mybatisplus.annotation.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;

import java.time.LocalDateTime;

@Data
@TableName(value = "user_info")
public class UserInfo {
    @TableId(type = IdType.AUTO)
    private Long id;

    @NotBlank
    @NotNull
    @Size(min = 4, max = 30, message = "name's length is too long or to short.")
    private String name;

    @Size(min = 8, max = 20)
    private String password;

    private String address;

    @Size(min = 11, max = 11, message = "phone's length should be 11.")
    private String phone;

    @TableField(fill = FieldFill.INSERT, value = "created_time")
    private LocalDateTime createdTime;

    @TableField(fill = FieldFill.UPDATE, value = "updated_time")
    private LocalDateTime updatedTime;

    @TableLogic(value = "false", delval = "true")
    @TableField(value = "is_deleted")
    private boolean isDeleted;
}

工具类:

package com.example.springbootmybatisplusdemo.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class CryptoUtils {
    public static final String ALGO = "MD5";

    public static String md5Sum(String val) {
        if (val == null) val = "";

        String str = "";
        try {
            MessageDigest msgD = MessageDigest.getInstance(ALGO);
            msgD.update(val.getBytes());
            byte[] bytes = msgD.digest();

            int i;
            StringBuilder builder = new StringBuilder();
            for (int j = 0; j < bytes.length; j++) {
                i = bytes[j];
                if (i < 0) i += 256;
                if (i < 16) builder.append("0");

                builder.append(Integer.toHexString(i));
            }

            str = builder.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        return str;
    }

    public static void main(String[] args) {
        System.out.println(CryptoUtils.md5Sum("Hello world!" + "crypto"));
    }
}

创建表的 SQL 语句:

CREATE TABLE `user_info` (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(30) NOT NULL,
    password CHAR(32) NOT NULL,
    address varchar(50) DEFAULT '',
    phone CHAR(11) NOT NULL UNIQUE KEY,
    created_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
    updated_time DATETIME NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
    is_deleted BOOLEAN
) ENGINE =innodb, CHARSET =utf8;