若依框架的简单使用

由于工作需求,后端开发框架都是使用的若依框架,于是自己去学习一下相关的使用。这里我主要使用的是它的前后端分离架构,也就是springboot+vue的架构。
有springboot基础的小伙伴们上手起来应该是很快的,主要就是使用中间的一些注解。大部分内容都是直接参考RuoYi官网的。
简介
RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。
A. 相关链接
- 若依官网:http://ruoyi.vip(opens new window)
- 演示地址:http://vue.ruoyi.vip(opens new window)
- 代码下载:https://gitee.com/y_project/RuoYi-Vue
- 文档地址:https://doc.ruoyi.vip/ruoyi-vue/
具体就得参考上面的文档中的地址,这边只是记录一些我常用的。
B. 系统需求
- JDK >= 1.8
- MySQL >= 5.7
- Maven >= 3.0
- Node >= 12
- Redis >= 3
C. 特性
- 完全响应式布局(支持电脑、平板、手机等所有主流设备)
- 强大的一键生成功能(包括控制器、模型、视图、菜单等)
- 支持多数据源,简单配置即可实现切换。
- 支持按钮及数据权限,可自定义部门数据权限。
- 对常用js插件进行二次封装,使js代码变得简洁,更加易维护
- 完善的XSS防范及脚本过滤,彻底杜绝XSS攻击
- Maven多项目依赖,模块及插件分项目,尽量松耦合,方便模块升级、增减模块。
- 国际化支持,服务端及客户端支持
- 完善的日志记录体系简单注解即可实现
- 支持服务监控,数据监控,缓存监控功能
使用
A. 代码获取
直接使用git clone
把相关的代码拉下来
1 | git clone https://gitee.com/y_project/RuoYi-Vue.git |
也可以使用ssh等方式,仓库在这里。
B. 本地部署运行
环境自己准备好,记得把Node等等换源,当然,如果只要后端的话Node就不用了。
1 | JDK >= 1.8 (推荐1.8版本) |
(一) 后端部署
导入到
Eclipse
,菜单File
->Import
,然后选择Maven
->Existing Maven Projects
,点击Next
> 按钮,选择工作目录,然后点击Finish
按钮,即可成功导入。Eclipse
会自动加载Maven
依赖包,初次加载会比较慢(根据自身网络情况而定)创建数据库
ry-vue
并导入数据脚本ry_2021xxxx.sql
,quartz.sql
在admin-…-resources-application-druid.yml修改master的数据源的相关配置
1
2
3
4
5
6
7
8
9
10
11# 数据源配置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://ip:port/database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username:
password:也可以在配置文档中修改相关的端口,默认端口是
8080
打开项目运行
com.ruoyi.RuoYiApplication.java
,出现如下图表示启动成功。
1 | (♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ |
- 想要看到效果,可以通过两种途径,一个是前端的部署,另一个是
Swagger+Knife4j
自动生成接口文档
本段参考:RuoYi-Vue环境部署
(二) 前端查看
进入项目下的或者独立出来的ui文件夹,在文件夹下打开终端。
1 | # 进入项目目录 |
打开浏览器,输入:(http://localhost:80) 默认账户/密码 admin/admin123
)
(三) 接口文档查看
ruoyi在拉下来的时候就已经配置了Swagger组件。
- 多导入一个knife4j包来增强功能
1 | <!-- knife4j --> |
用@Api(tags = “”)来对Controller进行修饰
用@ApiOperation(value = “”)来对类进行修饰
其他修饰参见SpringBoot里面和Swagger相关的@Apixxx
使用 http://ip:port/doc.html 来看api文档,效果如下
C. 相关注解和使用
(一) 注解
@Value
用于给下面的变量赋值
1 |
|
和直接赋值不同的是,这个值用"${parameter}"
的格式来输入值,可以通过修改application.yml中的参数,方便修改,如下所示
1 | fanruan: |
这样子,上面的publicKey
中的内容中的${fanruan.publicKey}
会被替换为MIIBIjANBgkqhki
@Autowired
自动装配,依赖注入
1 |
|
与**
@Qualifier
**注解配合使用:当有多个相同类型的Bean时,可以使用
@Qualifier
注解与@Autowired
注解一起使用,以指定注入哪一个具体的Bean。例如,如果你有一个
FeishuService
接口和多个实现类,你可能想要指定注入哪一个实现:1
2
3
private FeishuService feishuService;疑问:和
@Resource
有哪些区别呢
@Autowired
和@Resource
两个注解都用于实现依赖注入,但它们之间存在几个主要区别:
- 来源不同:
@Autowired
是Spring框架提供的注解,而@Resource
来自于Java规范,特别是JSR-250。
- 依赖查找顺序不同:
@Autowired
默认先按类型(byType)查找,如果存在多个Bean再按名称(byName)查找。@Resource
默认先按名称(byName)查找,如果找不到与名称匹配的Bean,则退回到按类型(byType)查找。
- 支持的参数不同:
@Autowired
只支持设置一个参数required
,用于指定依赖是否必须。@Resource
支持设置多个参数,如name
和type
等,提供了更灵活的配置。
- 依赖注入的用法支持不同:
@Autowired
支持构造方法注入、属性注入和Setter方法注入。@Resource
主要支持属性注入和Setter方法注入,通常不用于构造方法注入。
- 编译器IDEA的提示不同:
- 使用
@Autowired
时,IDEA可能会出现警告,提示字段注入不被推荐。 - 使用
@Resource
时,IDEA通常不会出现类似的警告
- 使用
model中的
1 |
|
- @Data:
- 这是Lombok库提供的一个注解,用于自动为类的字段生成getter和setter方法、
equals()
、hashCode()
和toString()
方法。这可以减少模板代码的编写,使代码更加简洁。
- 这是Lombok库提供的一个注解,用于自动为类的字段生成getter和setter方法、
- @ApiModel:
- 这是Swagger库提供的一个注解,用于描述一个模型(即一个POJO类)的信息。在这个例子中,
@ApiModel
注解的description
属性被设置为”首页数据查询请求参数”,这意味着这个类是用来封装发送到首页数据查询接口的请求参数的。
- 这是Swagger库提供的一个注解,用于描述一个模型(即一个POJO类)的信息。在这个例子中,
- @ApiModelProperty:
- 这也是Swagger库提供的一个注解,用于描述
HomeQueryParam
类中字段的信息。它可以提供字段的额外信息,比如示例值、描述等,这些信息会在生成的Swagger文档中显示。
- 这也是Swagger库提供的一个注解,用于描述
- @NotBlank:
- 这是一个验证注解,通常与Spring Validation API一起使用,用于确保字段不为空,即字段的值不是
null
且不是空白字符。如果字段验证失败,会返回message
属性指定的错误信息。
- 这是一个验证注解,通常与Spring Validation API一起使用,用于确保字段不为空,即字段的值不是
类中的两个字段:
- month:表示年月,使用了
@NotBlank
注解确保这个字段在请求中必须被提供,且不能是空白字符。@ApiModelProperty
注解提供了一个示例值”202404”。 - type:表示类型(单月/累计),同样使用了
@NotBlank
注解确保这个字段在请求中必须被提供,且不能是空白字符。@ApiModelProperty
注解提供了一个示例值”单月”。
mapper中
- @Mapper
标识为mybatis的mapper接口
- @DataSource(DataSourceType.PURCHASING)
这是若依框架自定义的注解,默认MASTER
其他数据源可以在common-enum-DataSourceType中新增
然后实际配置在admin中的application-druid.yml中
controller中
- @Api(tags = “采购-供应商管理-品类分布”)
Swagger中相当于整体的包,一般在Controller的上注解
1 | @Api(tags = "采购-供应商管理-品类分布") |
- @ApiOperation
value为文档中接口名称(一般命名方式都是模块名,用-连接),notes是接口的描述
1 | @ApiOperation(value = "四大品类分布-品类-数量-占比", notes = "传入的参数是date+department,department为空时就返回全部事业部的总值。这个部门或者这个时间没有数据的话就返回空。") |
@Log在日志中标志
- 枚举类传递
1 |
|
(二) Result的使用
在全限定名:com.cockpit.common.core.domain.Result下
代码
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104package com.cockpit.common.core.domain;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 响应结果
*
* @author liyuqi
*/
public class Result<T> {
/**
* 响应状态码
*/
private int code;
/**
* 响应消息
*/
private String msg;
/**
* 响应结果
*/
private T data;
/**
* 构造方法
*
* @param code 响应状态
* @param msg 响应消息
* @param data 响应结果
*/
private Result(int code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
/**
* 构造方法
*
* @param code 响应状态
* @param msg 响应消息
*/
private Result(int code, String msg) {
this(code, msg, null );
}
/**
* 构造方法
*/
public Result() {
}
/**
* 返回成功响应对象
*
* @return 响应对象
*/
public static <T> Result<T> ok( String message, T result ) {
return new Result<>( 200, message, result );
}
/**
* 返回成功响应结果
*
* @param result 响应结果
* @param <T> 响应结果类型
* @return 响应对象
*/
public static <T> Result<T> ok( T result ) {
return ok( null, result );
}
/**
* 返回成功响应对象
*
* @return 响应对象
*/
public static Result<Void> ok() {
return ok( null );
}
/**
* 返回失败响应对象
*
* @param status 响应状态
* @param message 响应消息
* @return 响应对象
*/
public static <T> Result<T> fail( int status, String message ) {
return new Result<>( status, message );
}
}需要包
1
2
3
4
5
6
7
8
9
10
11<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.2</version>
<scope>compile</scope>
</dependency>这时可用
Result.ok(xxx)
返回json格式内容
(三) 装载数据源
在admin相应的sping.datasource.druid.xxx下加,如下
1
2
3
4
5
6
7
8
9
10spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
druid:
home:
enabled: true # 这个不能少
url:
username:
password:
driverClassName:在common中找到enums,DataSourceType加相应的枚举类的名字
在framework中找到config.DruidConfig,其中要加两处要加
1
2
3
4
5
6
7
8
public DataSource homeDataSource(DruidProperties druidProperties)
{
DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
return druidProperties.dataSource(dataSource);
}以及在dataSource方法中加一句
1
setDataSource(targetDataSources, DataSourceType.XXX.name(), "xxxDataSource");
装配完成,使用的时候只要在Mapper接口上加上
@DataSource(DataSourceType.XXX)
即可
(四) 接口调用
接口调用前都要获取token
,获取token
的方式可以找Login
接口。在admin模块下找controller中的system有一个类为SysLoginController
。可以用接口文档的注解方式给它注解,运行后我们能看到如下的接口。

进入调试中,请求头部Authorization
是不需要的,请求参数中有如下
1 | { |
在此之前可以进入Login函数的server层把验证码验证给去了,code那边放的就是验证码。
然后默认账号admin
,默认密码admin123
。提交后获得token,放进其他接口的Authorization
即可访问其他接口。
(五) 参数传递
后端接口主要有两种参数接收的方式,
用类封装
这种方式,前端用Json格式传递到后端,后端可以用类来接收数据,如:
1
2
3
4
5
6
public Result<Map<String, Object>> getAttributeSupplierInfo( { AttributeSupplierParam param)
return Result.ok(supplierAreaService.getAttributeSupplierInfo(param));
}AttributeSupplierParam内部如下
1
2
3
4
5
6
7
8
9
10
11
12
public class AttributeSupplierParam {
private String department;
private String month;
private List<String> province;
}那么前端传递过来的参数为json,形如
1
2
3
4
5{
"department":"具体部门名称",
"month":"具体年月",
"province":["省份1","省份2","省份3"]
}直接传递
这种方式,前端用
application/x-www-form-urlencoded
传递到后端,后端可以用类来接收数据,如:1
2
3
4
5
6
7
8
public Result<AreaTabListVo> selectAreaTabList(
{ String name)
AreaTabListVo areaTabListVo = supplierAreaService.selectAreaTabList(name);
return Result.ok(areaTabListVo);
}在使用
get
时,能够直接从url获取相应值,在post
时,能够从请求体中获取相应的数据。
代码工具
1.JsonUtils
若依框架自己封装了相关的Json工具,可以自由转换
包来源
com.cockpit.common.utils.json.JsonUtils
可使用工具
1
2
3JsonUtils.toList(groupLevelString, String.class); // string转List<String>
JsonUtils.toJsonString(parm.getDataSourceList()); // List<String>转string
// 还有toMap toJsonNode等等方法
2.SecurityUtils
系统用户信息
- 若依框架中的
SecurityUtils
是一个用于简化用户身份验证和权限管理的工具类,尤其在前后端分离版本中扮演了核心角色。- 获取当前用户信息:
SecurityUtils
提供静态方法直接获取当前登录用户的基本信息(如用户名、用户ID等),无需手动解析安全上下文。例如,SecurityUtils.getUsername()
可直接返回当前会话的用户- 权限验证:结合Shiro或Spring Security框架,
SecurityUtils
可快速验证用户是否具备特定角色或权限,例如通过hasRole()
方法判断用户角色
该类主要是通过用户登录后的token去访问Redis,获取预先存放在Redis中的数据。
包来源
1
com.cockpit.common.utils.SecurityUtils;
可使用工具
1
2
3
4
5
6SecurityUtils.getAuthentication(); // 得到用户信心
SecurityUtils.getLoginUser(); // 得到当前用户完整的用户信息
// SecurityUtils.getLoginUser()相当于SecurityUtils.getAuthentication().getPrincipal();
SecurityUtils.getDeptId();
SecurityUtils.etUsername();
SecurityUtils.getUserId();roleIds获取
1
2
3LoginUser loginUser = SecurityUtils.getLoginUser();
SysUser user = loginUser.getUser();
Set<Long> roleIds = user.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toSet());
3.Mybatis-plus
mybatis-plus
主要针对于单表的CRUD操作。
1 | // 查询字段 |
还可以selectOne
、selectById
等
在此之前需要在mapper层继承
BaseMapper<T>
,其中的T是你数据库映射的类数据库映射类,需要做表和字段的映射,举例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class EmpInfoEntity {
/**
* 主键自增
*/
private Long id;
/**
* 工号(唯一)
*/
private String empNo;
}
4.分页工具
分页有两种方式,一种是数据库分页,一种是读到内存来分页。
4.1.数据存放类Page
首先我先说一种存放分页数据的类,是mybatis-plus自带的一个专门存放分页数据的类Page
,是IPage
的实现类。
包括了如下的变量
1 | public class Page<T> implements IPage<T> { |
其中records
就是存放数据的地方,total
是数据总数,size是页面大小,pages
是总页数,current
是当前页。
4.2.参数类PageDomain
该类是若依管理的一个类,用于传入分页相关参数
包来源
1
com.cockpit.common.core.page.PageDomain
变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class PageDomain
{
/** 当前记录起始索引 */
private Integer pageNum;
/** 每页显示记录数 */
private Integer pageSize;
/** 排序列 */
private String orderByColumn;
/** 排序的方向desc或者asc */
private String isAsc = "asc";
/** 分页参数合理化 */
private Boolean reasonable = true;
。。。
}我们可以在自己的参数类上继承这个类:
public class MyParam extends PageDomain
4.3.分页
前面提到有两种分页方式。数据库自带的分页,是用的自带的分页工具
PageHelper
;内存中分页是用的若依的类PageUtils
,但是这个类功能不够强大,在这边加了一个类用于分页。
A.PageHelper
sysRoles读出来就是已经分好页的
1 | PageHelper.startPage(param.getPageNum(), param.getPageSize()); |
B. PageUtils
加上自己在内存中分页的方法
1 | /** |
使用
1 | List<RoleListResult> data = PageUtils.getPaginatedList(roleListResults, param.getPageNum(), param.getPageSize()); |
5.BaseException
若依框架用Result.ok()输出结果时,有个msg,有的时候有错误,判断参数等等的时候没有data,只要返回500的msg可以用该方法抛出
1 | throw new BaseException("ssssss"); |
6.手动切换数据源
不推荐使用,一般还是用若依自带的
@DataSource(DataSourceType.Master)
这样的方式
1 | DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.SLAVE.name()); |
利用上下文对于当前线程的数据源进行手动切换。
结束点
若依框架中还有更多功能,比如自动代码生成,权限分配等等,这些可以自己参考文档。
- 标题: 若依框架的简单使用
- 作者: Sabthever
- 创建于 : 2025-01-03 14:26:02
- 更新于 : 2025-04-02 16:07:05
- 链接: https://sabthever.online/2025/01/03/technology/java/ruoyi-1/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。