Java Spring Boot Controller、Service、DAO实践

如果你用过 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;

posted on   进击的davis  阅读(669)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示