如何高效地架构一个Java项目

引言

Java是企业级应用开发的主流语言之一,而我们作为使用Java语言的程序员,职称有初级、中级、高级、资深、经理、架构,但我们往往只是慢慢通过经验的积累迭代了自己的等级,如果没有保持学习的习惯,大多数程序员会停留在接近高级的位置,简单来讲就是CRUD工程师,小编不甘心于此,所以长期保持学习新知识的习惯,尝试很多大于自身能力的事情,我相信未来的某一天我会感谢曾经努力的自己,下面的内容是我在尝试架构项目时总结的经验,希望能帮助到大家

前期准备

  • 需求分析:明确项目的功能需求
  • 技术选型:
    • Java版本
      • 8,17
    • 框架选择
      • 应用:Spring,SpringBoot,SpringCloud
      • ORM(对象关系映射):JPA,MyBatis(Plus)
    • 数据库选择
      • 关系型:MySQL,PostgreSQL,Oracle
      • 非关系型:Redis,MongoDB
      • 时序数据库(物联网):TDengine,IoTDB
    • 构建工具
      • Maven,Gradle

项目结构设计

  • 分层架构
    • 认证授权
    • 控制层
    • 业务层
    • 数据层
  • 模块划分
    • 按功能划分
    • 按业务划分

简单示例

跳过项目的功能需求分析(具体项目具体分析),技术选型,Java版本选择17,应用框架选择SpringBoot,ORM(对象关系映射)框架选择MyBatis-Plus,数据库选择MySQL 8.x,构建工具选择Maven,项目结构,拦截器中完成认证授权,控制层接收用户请求调用业务层的方法,业务层处理逻辑调用数据层的方法,数据层与数据库交互,跳过模块划分(具体项目具体分析)

准备开发环境

1.下载安装配置Java17

访问官方的下载地址:Java Archive Downloads - Java SE 17

1.下载并解压

2.配置环境变量

我的电脑 -> 属性 -> 高级系统设置 -> 环境变量 ->系统变量(S) -> 新建(W)

双击系统变量(S)中的Path -> 新建(N)

确定后打开命令提示符界面(快捷键 win+R 输入 cmd 回车),输入java -version命令查看是否安装成功

2.下载安装MySQL 8.x

访问官方的下载地址:MySQL :: Download MySQL Installer (Archived Versions)

参考文章:【MySQL8.0.39下载安装】_mysql8.0.39.0安装教程-CSDN博客

架构项目

1.创建SpringBoot项目

2.创建包/文件结构

3.认证与授权

首先确定使用什么标准和框架进行认证与授权,常见的标准有:OAuth 2.0,JWT,常见的框架有:Spring Security,Apache Shiro,我采用的是近几年很火的轻量级框架:SaToken,如何集成可以参考我的另一篇文章:Java集成Sa-Token进行认证与授权_基于satoken的 sop-CSDN博客

4.创建数据库、用户表(含索引)

sql 复制代码
DROP DATABASE IF EXISTS `muze`;
CREATE DATABASE `muze` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
USE `muze`;
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
    id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键',
    username VARCHAR(30) COLLATE utf8mb4_0900_bin NOT NULL COMMENT '用户名',
    password VARCHAR(255) COLLATE utf8mb4_0900_bin NOT NULL COMMENT '密码',
    PRIMARY KEY (id)
) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';
CREATE INDEX idx_username ON t_user(username);

5.创建用户实体

为了方便实体类的编写,我们引入依赖 - 小辣椒

XML 复制代码
<!-- 小辣椒 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>
java 复制代码
/**
 * 用户实体
 * @author muze
 */
@Data
@TableName("t_user")
public class User implements Serializable {
    @Serial
    private static final long serialVersionUID = 684552117916625567L;

    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 账号
     */
    private String username;

    /**
     * 密码
     */
    private String password;
}

6.创建用户数据层

技术选型时数据库是MySQL,ORM(对象关系映射)框架是MyBatis-Plus,因此引入对应依赖

XML 复制代码
<!-- MySQL -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.7</version>
</dependency>

在启动类上打MyBatis-Plus提供的@MapperScan("MyBatis Mapper 接口包路径"),自动扫描指定包下的 MyBatis Mapper 接口,并将它们注册为 Spring 容器中的 Bean

java 复制代码
/**
 * 启动类
 * @author muze
 */
@MapperScan("com.muze.project.mapper")
@SpringBootApplication
public class ProjectApplication {

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

}

在配置文件application.yml中添加数据库连接信息

javascript 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/muze?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    username: 你的用户名
    password: 你的密码
    driver-class-name: com.mysql.cj.jdbc.Driver

用户数据层

java 复制代码
/**
 * 用户数据层
 * @author muze
 */
public interface UserMapper extends BaseMapper<User> {
}

7.创建用户业务层

我习惯将业务层分离为接口层和实现层,所以我会在sevice包下创建一个impl包,如果你不习惯可以只编写实现层,编写用户登录方法前需要定义方法入参和返回值

入参:请求实体(用户名 + 密码)

返回值:登录结果

创建DTO(请求实体)

java 复制代码
/**
 * 用户登录请求实体
 * @author muze
 */
@Data
public class UserLoginDTO implements Serializable {
    @Serial
    private static final long serialVersionUID = -1706553212610156227L;
    
    /**
     * 用户名
     */
    private String username;

    /**
     * 密码
     */
    private String password;
}

用户登录业务接口层和实现层

java 复制代码
/**
 * 用户业务接口层
 */
public interface IUserService {
    /**
     * 登录
     * @param userLoginDTO 用户登录请求实体
     * @return 登录结果
     */
    String login(UserLoginDTO userLoginDTO);
}
java 复制代码
/**
 * 用户业务实现层
 * @author muze
 */
@Service
public class UserServiceImpl implements IUserService {
    /**
     * 注入用户数据层
     */
    @Autowired
    private UserMapper userMapper;
    @Override
    public String login(UserLoginDTO userLoginDTO) {
        // 取出用户名和密码
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();
        // 构建查询条件
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<User>().eq(User::getUsername, username);
        // 查询用户
        User user = userMapper.selectOne(userLambdaQueryWrapper);
        // 如果用户为空或者输入密码与用户密码不匹配则返回:用户名或密码错误
        if (user == null || !password.equals(user.getPassword())) return "用户名或密码错误";
        // 使用SaToken的工具类StpUtil调用登录方法login,入参:用户id
        StpUtil.login(user.getId());
        // 返回:登录成功
        return "登录成功";
    }
}

8.创建用户控制层

编写控制层前我们要先确定请求路径,请求方式,请求参数,响应数据

请求路径:/user/login

请求方式:POST

请求参数:用户名 + 密码

响应数据:响应码 + 响应消息 + 响应数据

DTO(请求实体)已经在编写用户业务层时创建好了

VO(响应实体)使用SaToken提供的SaResult

java 复制代码
/**
 * 用户控制层
 */
@RestController
@RequestMapping("/user")
public class UserLogin {
    /**
     * 注入用户业务接口层
     */
    @Autowired
    private IUserService userService;

    /**
     * 登录
     * @param userLoginDTO 用户登录请求实体
     * @return 响应码 + 响应消息 + 响应数据
     */
    @PostMapping("/login")
    public SaResult login(@RequestBody UserLoginDTO userLoginDTO) {
        return SaResult.ok(userService.login(userLoginDTO));
    }
}

测试

编写sql语句新增一条用户信息用于测试登录

sql 复制代码
INSERT INTO t_user (username, password) VALUES ("muze", "123456");

启动项目,使用接口调试工具测试登录功能

端口默认为8080

可以发现,Cookie中放入了一个令牌

到此,一个拥有基础功能:登录,认证与授权的Java项目就架构完成了,后续就是按照功能需求划分模块进行开发了,希望能对你有所帮助!

彩蛋:你肯定也发现了,密码并没有进行加密解密,虽然在HTTPS协议中Post请求会对传输数据加密,但在HTTP协议中Post请求不会对传输数据加密,因此我们还应该对数据传输进行加密,小编会在后续更新一篇与数据加密相关的文章,敬请期待

相关推荐
徐小黑ACG9 分钟前
GO语言 使用protobuf
开发语言·后端·golang·protobuf
0白露1 小时前
Apifox Helper 与 Swagger3 区别
开发语言
Tanecious.2 小时前
机器视觉--python基础语法
开发语言·python
叠叠乐2 小时前
rust Send Sync 以及对象安全和对象不安全
开发语言·安全·rust
战族狼魂3 小时前
CSGO 皮肤交易平台后端 (Spring Boot) 代码结构与示例
java·spring boot·后端
Tttian6224 小时前
Python办公自动化(3)对Excel的操作
开发语言·python·excel
xyliiiiiL4 小时前
ZGC初步了解
java·jvm·算法
杉之4 小时前
常见前端GET请求以及对应的Spring后端接收接口写法
java·前端·后端·spring·vue
hycccccch5 小时前
Canal+RabbitMQ实现MySQL数据增量同步
java·数据库·后端·rabbitmq
独好紫罗兰5 小时前
洛谷题单2-P5713 【深基3.例5】洛谷团队系统-python-流程图重构
开发语言·python·算法