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>
主要目录
目录结构如下图所示:
配置文件
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;
分类:
java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!