若依框架的简单使用

Sabthever

  由于工作需求,后端开发框架都是使用的若依框架,于是自己去学习一下相关的使用。这里我主要使用的是它的前后端分离架构,也就是springboot+vue的架构。

  有springboot基础的小伙伴们上手起来应该是很快的,主要就是使用中间的一些注解。大部分内容都是直接参考RuoYi官网的。

简介

  RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。

A. 相关链接

具体就得参考上面的文档中的地址,这边只是记录一些我常用的。

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
2
3
4
5
JDK >= 1.8 (推荐1.8版本)
Mysql >= 5.7.0 (推荐5.7版本)
Redis >= 3.0
Maven >= 3.0
Node >= 12

(一) 后端部署

  1. 导入到Eclipse,菜单 File -> Import,然后选择 Maven -> Existing Maven Projects,点击 Next> 按钮,选择工作目录,然后点击 Finish 按钮,即可成功导入。
    Eclipse会自动加载Maven依赖包,初次加载会比较慢(根据自身网络情况而定)

  2. 创建数据库ry-vue并导入数据脚本ry_2021xxxx.sqlquartz.sql

  3. 在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

  4. 打开项目运行com.ruoyi.RuoYiApplication.java,出现如下图表示启动成功。

1
2
3
4
5
6
7
8
9
10
(♥◠‿◠)ノ゙  若依启动成功   ლ(´ڡ`ლ)゙  
.-------. ____ __
| _ _ \ \ \ / /
| ( ' ) | \ _. / '
|(_ o _) / _( )_ .'
| (_,_).' __ ___(_ o _)'
| |\ \ | || |(_,_)'
| | \ `' /| `-' /
| | \ / \ /
''-' `'-' `-..-'
  1. 想要看到效果,可以通过两种途径,一个是前端的部署,另一个是Swagger+Knife4j自动生成接口文档

本段参考:RuoYi-Vue环境部署

(二) 前端查看

  进入项目下的或者独立出来的ui文件夹,在文件夹下打开终端。

1
2
3
4
5
6
7
8
# 进入项目目录
cd ruoyi-ui
# 安装依赖
npm install
# 强烈建议不要用直接使用 cnpm 安装,会有各种诡异的 bug,可以通过重新指定 registry 来解决 npm 安装速度慢的问题。
npm install --registry=https://registry.npmmirror.com
# 本地开发 启动项目
npm run dev

  打开浏览器,输入:(http://localhost:80) 默认账户/密码 admin/admin123

(三) 接口文档查看

  ruoyi在拉下来的时候就已经配置了Swagger组件。

  • 多导入一个knife4j包来增强功能
1
2
3
4
5
6
<!-- knife4j -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
  • 用@Api(tags = “”)来对Controller进行修饰

    用@ApiOperation(value = “”)来对类进行修饰

    其他修饰参见SpringBoot里面和Swagger相关的@Apixxx

  • 使用 http://ip:port/doc.html 来看api文档,效果如下

C. 相关注解和使用

(一) 注解

@Value

  用于给下面的变量赋值

1
2
@Value("${fanruan.publicKey}")
private String publicKey;

  和直接赋值不同的是,这个值用"${parameter}"的格式来输入值,可以通过修改application.yml中的参数,方便修改,如下所示

1
2
fanruan:
publicKey: MIIBIjANBgkqhki

  这样子,上面的publicKey中的内容中的${fanruan.publicKey}会被替换为MIIBIjANBgkqhki


@Autowired

  自动装配,依赖注入

1
2
@Autowired
private FeishuService feishuService;
  • **@Qualifier**注解配合使用

      当有多个相同类型的Bean时,可以使用@Qualifier注解与@Autowired注解一起使用,以指定注入哪一个具体的Bean。

      例如,如果你有一个FeishuService接口和多个实现类,你可能想要指定注入哪一个实现:

    1
    2
    3
    @Autowired
    @Qualifier("specificFeishuService")
    private FeishuService feishuService;
  • 疑问:和@Resource有哪些区别呢

  @Autowired@Resource两个注解都用于实现依赖注入,但它们之间存在几个主要区别:

  1. 来源不同
    1. @Autowired是Spring框架提供的注解,而@Resource来自于Java规范,特别是JSR-250。
  2. 依赖查找顺序不同
    1. @Autowired默认先按类型(byType)查找,如果存在多个Bean再按名称(byName)查找。
    2. @Resource默认先按名称(byName)查找,如果找不到与名称匹配的Bean,则退回到按类型(byType)查找。
  3. 支持的参数不同
    1. @Autowired只支持设置一个参数required,用于指定依赖是否必须。
    2. @Resource支持设置多个参数,如nametype等,提供了更灵活的配置。
  4. 依赖注入的用法支持不同
    1. @Autowired支持构造方法注入、属性注入和Setter方法注入。
    2. @Resource主要支持属性注入和Setter方法注入,通常不用于构造方法注入。
  5. 编译器IDEA的提示不同
    1. 使用@Autowired时,IDEA可能会出现警告,提示字段注入不被推荐。
    2. 使用@Resource时,IDEA通常不会出现类似的警告

model中的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Data
@ApiModel(description = "首页数据查询请求参数")
public class HomeQueryParam {
// 年月
@ApiModelProperty(value = "202404")
@NotBlank(message = "年月不能为空")
private String month;

// 类型(单月/累计)
@ApiModelProperty(value = "单月",example="这边是api使用展示值")
@NotBlank(message = "类型不能为空") // 会在为空的时候给前端返回
private String type;

}
  1. @Data
    1. 这是Lombok库提供的一个注解,用于自动为类的字段生成getter和setter方法、equals()hashCode()toString()方法。这可以减少模板代码的编写,使代码更加简洁。
  2. @ApiModel
    1. 这是Swagger库提供的一个注解,用于描述一个模型(即一个POJO类)的信息。在这个例子中,@ApiModel注解的description属性被设置为”首页数据查询请求参数”,这意味着这个类是用来封装发送到首页数据查询接口的请求参数的。
  3. @ApiModelProperty
    1. 这也是Swagger库提供的一个注解,用于描述HomeQueryParam类中字段的信息。它可以提供字段的额外信息,比如示例值、描述等,这些信息会在生成的Swagger文档中显示。
  4. @NotBlank
    1. 这是一个验证注解,通常与Spring Validation API一起使用,用于确保字段不为空,即字段的值不是null且不是空白字符。如果字段验证失败,会返回message属性指定的错误信息。

类中的两个字段:

  • 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
2
3
4
@Api(tags = "采购-供应商管理-品类分布")
@RestController
@RequestMapping("/purchasing/supplier-manage/category-distribute")
public class SmCateDistriController {。。。}
  • @ApiOperation

value为文档中接口名称(一般命名方式都是模块名,用-连接),notes是接口的描述

1
2
3
4
5
6
7
@ApiOperation(value = "四大品类分布-品类-数量-占比", notes = "传入的参数是date+department,department为空时就返回全部事业部的总值。这个部门或者这个时间没有数据的话就返回空。")
@PostMapping("/cateDistri")
@Log(title = "四大品类分布-品类-数量-占比", businessType = BusinessType.SELECT)
public Result<CateDistriVo> selectReplaceRate(@RequestBody @Validated SmCatDistriParam param){
CateDistriVo cateDistriVo = smCateDistriService.selectCateDistri(param);
return Result.ok(cateDistriVo);
}

@Log在日志中标志

  • 枚举类传递
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
@ApiParam(name = "smCatDistriEnum", value = "切换模块", required = true)
@RequestParam("smCatDistriEnum") @NotNull(message = "smCatDistriEnum")
SmCatDistriEnum smCatDistriEnum

枚举类
public enum SmCatDistriEnum {
/**
* 品类分布
*/
品类分布("品类分布"),
四大品类分布下钻表("四大品类分布下钻表"),
品类厂商分布下钻表("品类厂商分布下钻表"),
各专业部四大品类分布下钻表("各专业部四大品类分布下钻表"),
;


private String description;

SmCatDistriEnum(String description) {
this.description = description;
}

public String getDescription() {
return description;
} // 也可以在类上面用@Getter替代
}

(二) 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
    104
    package com.cockpit.common.core.domain;

    import io.swagger.annotations.ApiModel;
    import io.swagger.annotations.ApiModelProperty;
    import lombok.Data;

    /**
    * 响应结果
    *
    * @author liyuqi
    */
    @Data
    @ApiModel( description = "响应结果" )
    public class Result<T> {

    /**
    * 响应状态码
    */
    @ApiModelProperty( value = "响应状态码", example = "200" )
    private int code;

    /**
    * 响应消息
    */
    @ApiModelProperty( value = "响应消息", example = "参数不合法" )
    private String msg;

    /**
    * 响应结果
    */
    @ApiModelProperty( value = "响应结果" )
    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格式内容


(三) 装载数据源

  1. 在admin相应的sping.datasource.druid.xxx下加,如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    spring:
    datasource:
    type: com.zaxxer.hikari.HikariDataSource
    druid:
    home:
    enabled: true # 这个不能少
    url:
    username:
    password:
    driverClassName:
  2. 在common中找到enums,DataSourceType加相应的枚举类的名字

  3. 在framework中找到config.DruidConfig,其中要加两处要加

    1
    2
    3
    4
    5
    6
    7
    8
    @Bean
    @ConfigurationProperties("spring.datasource.druid.xxx")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.xxx", name = "enabled", havingValue = "true")
    public DataSource homeDataSource(DruidProperties druidProperties)
    {
    DruidDataSource dataSource = DruidDataSourceBuilder.create().build();
    return druidProperties.dataSource(dataSource);
    }

    以及在dataSource方法中加一句

    1
    setDataSource(targetDataSources, DataSourceType.XXX.name(), "xxxDataSource");
  4. 装配完成,使用的时候只要在Mapper接口上加上@DataSource(DataSourceType.XXX)即可


(四) 接口调用

  接口调用前都要获取token,获取token的方式可以找Login接口。在admin模块下找controller中的system有一个类为SysLoginController。可以用接口文档的注解方式给它注解,运行后我们能看到如下的接口。


  进入调试中,请求头部Authorization是不需要的,请求参数中有如下

1
2
3
4
5
6
{
"code": "",
"password": "",
"username": "",
"uuid": ""
}

  在此之前可以进入Login函数的server层把验证码验证给去了,code那边放的就是验证码。

  然后默认账号admin,默认密码admin123。提交后获得token,放进其他接口的Authorization即可访问其他接口。

(五) 参数传递

  后端接口主要有两种参数接收的方式,

  1. 用类封装

    这种方式,前端用Json格式传递到后端,后端可以用类来接收数据,如:

    1
    2
    3
    4
    5
    6
    @ApiOperation("Test1")
    @PostMapping("/Test1")
    @Log(title = "Test1", businessType = BusinessType.SELECT)
    public Result<Map<String, Object>> getAttributeSupplierInfo(@ApiParam(value = "请求参数") @RequestBody AttributeSupplierParam param) {
    return Result.ok(supplierAreaService.getAttributeSupplierInfo(param));
    }

    AttributeSupplierParam内部如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Data
    @ApiModel(description = "Test1传参")
    public class AttributeSupplierParam {
    @ApiModelProperty(value = "部门")
    private String department;

    @ApiModelProperty(value = "年月")
    private String month;

    @ApiModelProperty(value = "省份")
    private List<String> province;
    }

    那么前端传递过来的参数为json,形如

    1
    2
    3
    4
    5
    {
    "department":"具体部门名称",
    "month":"具体年月",
    "province":["省份1","省份2","省份3"]
    }
  2. 直接传递

    这种方式,前端用application/x-www-form-urlencoded传递到后端,后端可以用类来接收数据,如:

    1
    2
    3
    4
    5
    6
    7
    8
    @ApiOperation("Test2")
    @GetMapping("/Test2")
    @Log(title = "Test2", businessType = BusinessType.SELECT)
    public Result<AreaTabListVo> selectAreaTabList(@ApiParam(name = "name", value = "张三", required = false, example = "张三")
    @RequestParam(value = "name", required = false) 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
    3
    JsonUtils.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
    6
    SecurityUtils.getAuthentication(); // 得到用户信心
    SecurityUtils.getLoginUser(); // 得到当前用户完整的用户信息
    // SecurityUtils.getLoginUser()相当于SecurityUtils.getAuthentication().getPrincipal();
    SecurityUtils.getDeptId();
    SecurityUtils.etUsername();
    SecurityUtils.getUserId();

    roleIds获取

    1
    2
    3
    LoginUser 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
2
3
4
5
6
7
8
9
10
11
// 查询字段
QueryWrapper<EmpInfoEntity> wrapper = new QueryWrapper<>();
wrapper.isNotNull("post_sequence").groupBy("post_sequence")
.select("post_sequence").orderByAsc("post_sequence");
List<Object> postSequences = empInfoMapper.selectObjs(wrapper);

postBasicInfoMapper
.selectList(Wrappers
.lambdaQuery(AdsRaPostBasicInfoDfEntity.class)
.eq(AdsRaPostBasicInfoDfEntity::getPostSequence, entity.getPostSequence())
);

还可以selectOneselectById

  • 在此之前需要在mapper层继承BaseMapper<T>,其中的T是你数据库映射的类

  • 数据库映射类,需要做表和字段的映射,举例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @TableName(value ="t_emp_info")
    @Data
    public class EmpInfoEntity {
    /**
    * 主键自增
    */
    @TableId(type = IdType.AUTO)
    @TableField("id")
    private Long id;

    /**
    * 工号(唯一)
    */
    @TableField("emp_no")
    private String empNo;
    }

4.分页工具

  分页有两种方式,一种是数据库分页,一种是读到内存来分页。

4.1.数据存放类Page

  首先我先说一种存放分页数据的类,是mybatis-plus自带的一个专门存放分页数据的类Page,是IPage的实现类。

  包括了如下的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Page<T> implements IPage<T> {
private static final long serialVersionUID = 8545996863226528798L;
protected List<T> records;
protected long total;
protected long size;
protected long current;
protected List<OrderItem> orders;
protected boolean optimizeCountSql;
protected boolean searchCount;
protected boolean optimizeJoinOfCountSql;
protected String countId;
protected Long maxLimit;
....
}
IPage中还有个pages

  其中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
    20
    public class PageDomain
    {
    /** 当前记录起始索引 */
    @ApiModelProperty("页数")
    private Integer pageNum;

    /** 每页显示记录数 */
    @ApiModelProperty("分页大小")
    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
2
3
4
5
6
7
8
9
10
11
12
13
PageHelper.startPage(param.getPageNum(), param.getPageSize());
List<SysRole> sysRoles = permissionConfigMapper.selectRoleAll();

// 获取分页信息
PageInfo<SysRole> pageInfo = new PageInfo<>(sysRoles);

// 获取总记录数
long total = pageInfo.getTotal();
int totalPages = pageInfo.getPages();
Page<RoleListResult> page = new Page<>(param.getPageNum(), param.getPageSize());
page.setTotal(total);
page.setRecords(roleListResults);
page.setPages(totalPages);

B. PageUtils

  加上自己在内存中分页的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 集合分页
*/
public static <T> List<T> getPaginatedList(List<T> list, int pageNumber, int pageSize) {
int totalItems = list.size();
int startIndex = (pageNumber - 1) * pageSize;
// 处理越界情况
if (startIndex >= totalItems || pageNumber < 1) {
return new ArrayList<>();
}

int endIndex = Math.min(startIndex + pageSize, totalItems);
return list.subList(startIndex, endIndex);
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
List<RoleListResult> data = PageUtils.getPaginatedList(roleListResults, param.getPageNum(), param.getPageSize());

Page<RoleListResult> page = new Page<>(param.getPageNum(), param.getPageSize());
// 序号
int indexTemp = 1;
for(RoleListResult single: data){
single.setIndex((param.getPageNum()-1)*param.getPageSize()+indexTemp++);
}

page.setTotal(roleListResults.size());
page.setRecords(data);
page.setPages(roleListResults.size()/param.getPageSize());

5.BaseException

若依框架用Result.ok()输出结果时,有个msg,有的时候有错误,判断参数等等的时候没有data,只要返回500的msg可以用该方法抛出

1
2
throw new BaseException("ssssss");
// 抛出的ssssss会在Json的msg中显示

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 进行许可。