1.项目结构

后端

com.ruoyi

├── ruoyi-admin // 后台服务模块

│ └── web // 内置通用功能的controller (后台登录相关的、权限控制相关的、数据字典相关的,用于接收前端的请求并做出响应

│ └── RuoYiApplication // 若依项目启动类 基于springboot

├── ruoyi-common // 通用工具模块

│ └── annotation // 自定义注解

│ └── config // 全局配置,这里面的类是用来读取项目中的配置文件信息的

│ └── constant // 通用常量,可以放自定义的常量信息

│ └── core // 核心控制,比如说我们以后写的所有Controller都要集成它里面的BaseConttroller,以及实体类定义的统一返回结果AjaxResult、BaseEntity等等,也是在它里面的类的基础上实现的。还有分页返回的统一结果对象、redis相关配置、文本相关内容等等。

│ └── enums // 通用枚举,可以放自定义的枚举信息

│ └── exception // 通用异常

│ └── filter // 过滤器处理

│ └── utils // 通用类处理

│ └── xss // 自定义xss校验 ( 防止跨域脚本

├── ruoyi-framework // 框架核心模块

│ └── aspectj // AOP配置,想做一些方法增强,就放在这里面,里面都是切面类

│ └── config // 系统配置,是springboot集成第三方项目以后制定的配置文件,比如说有redis相关的、mybatis相关的、验证码等等

│ └── datasource // 多数据源配置

│ └── interceptor // 拦截器

│ └── manager // 异步处理

│ └── security // 权限控制

│ └── web // 前端控制

├── ruoyi-generator // 代码生成模块(可移除)

├── ruoyi-quartz // 定时任务模块(可移除)

├── ruoyi-system // 系统代码模块

│ └── domain // 系统代码的实体类

│ └── mapper // 系统代码的持久层

│ └── service // 系统代码的业务层

2.项目中配置文件

项目中的配置文件都在ruoyi-admin模块下

i18n:国际化处理

META-INF:存储了项目的元信息(描述数据的数据),无需修改

mybatis:mybatis相关的配置信息

application.yml:项目中的核心配置

application-druid.yml:数据库连接配置

banner.txt:默认的banner图标信息,项目启动,控制台打印显示

logback.xml:日志配置

3.模块依赖关系

4.后端代码分析

Controller,接收前端的请求,调用service处理业务逻辑,并返回我们的结果

/**

* 查询课程管理列表

*/

@PreAuthorize("@ss.hasPermi('course:course:list')")

@GetMapping("/list")

public TableDataInfo list(Course course)

{

startPage(); //1. 开启分页

List<Course> list = courseService.selectCourseList(course); //2. 查询课程列表

return getDataTable(list);//3. 返回表格分页数据对象

}

开启分页和返回表格分页数据对象这两个方法在CourseController在并不存在,而且service只是接收了条件,进行查询,并返回一个list集合,那如何做到最终返回的是一个分页数据对象呢?

首先,找到startPage的所属类在BaseController中,他手机web层通用的数据处理类,我们所有的业务Controller类默认都继承了这个BaseController,那么BaseController中所有公开的属性的方法都可以去使用了。

底层通过拦截器去拦截第二部的SQL语句,实现分页的功能。

那么第三步,他是怎么返回分页数据对象的呢?我们点进去看一下

当前方法也是放在了BaseController中,返回的是一个TableDateInfo对象,


第二个方法是exce的文件下载导出,放到原理篇后面讲

第三个方法是获取课程管理详细信息,返回的是一个非分页的操作结果AjaxResult,那他是怎么实现的呢?

/**

* 获取课程管理详细信息

*/

@PreAuthorize("@ss.hasPermi('course:course:query')")

@GetMapping(value = "/{id}")

public AjaxResult getInfo(@PathVariable("id") Long id)

{

return success(courseService.selectCourseById(id));

}

该方法调用了AjaxResult的静态success方法,将对象传过去,而这个对象穿的格式是什么呢?

我们继续点进去,对于非分页的查询,这里面涉及到我们刚才提到的sucess,里面包含三个参数,比如说我们在做课程修改时,是需要会写这部分数据的,我们就可以把data查询出来,在页面进行显示。

那对于一些不需要返回数据对象的业务操作,比如说我们的增删改,又是怎么实现的呢?

这边同样返回的是AjaxResult,但返回的方法不再是success,而是toAjax(),这个方法干了什么事呢?我们点进去看一下。

里面接受的是sevice返回的影响行数,那刚才我们提到了对于数据库的操作,如果影响行数大于0,表示成功了,否则就是操作失败了。

现在我们知道了,将来想做分页查询,返回对象就叫TableDataInfo。将来我们做非分页的操作,咱们返回的结果就是AjaxResult。

最后我们来看一下BaseEntity