从零开始搭建企业管理系统(七):RBAC 之用户管理

news2024/11/25 4:35:01

RBAC 之用户管理

    • 创建表(Entity)
      • 用户表
      • 角色表
      • 权限表
      • 用户角色表
        • 关系注解
        • @ManyToMany
      • 角色权限表
    • 接口开发
      • UserController
      • UserService
      • UserServiceImpl
      • UserRepository
    • 问题解决
      • update 更新问题
      • 懒加载问题
      • JSON 循环依赖问题

根据上一小结对表的设计,我们开始编写代码实现权限管理模块的代码。

我们直接通过编写实体映射类,让JPA自动帮我们生成一下数据库表。

创建表(Entity)

首先通过 JPA 将需要用到的5张表都建好。

先将基础实体类修改一下

@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
@Schema(description = "基础实体")
public class BaseEntity {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Schema(description = "用户ID")
    private Long id;

    @Column(columnDefinition = "tinyint(1) NOT NULL COMMENT '状态'")
    @Schema(description = "状态")
    private Integer status;

    @Column(columnDefinition = "bit NOT NULL COMMENT '0正常,1删除'")
    @Schema(description = "逻辑删除")
    private Boolean isDelete;

    @CreatedBy
    @Column(updatable = false, columnDefinition = "varchar(32) COMMENT '创建用户'")
    @Schema(description = "创建用户", hidden = true)
    private String createUser;

    @LastModifiedBy
    @Column(columnDefinition = "varchar(32) COMMENT '修改用户'")
    @Schema(description = "修改用户", hidden = true)
    private String updateUser;

    @CreatedDate
    @Column(updatable = false, columnDefinition = "datetime COMMENT '创建时间'")
    @Schema(description = "创建时间", hidden = true)
    private Date createTime;

    @LastModifiedDate
    @Column(columnDefinition = "datetime COMMENT '修改时间'")
    @Schema(description = "修改时间", hidden = true)
    private Date updateTime;
}

将一些每个表都存在的共有属性抽离出来当作一个父类,需要这些字段的实体通过继承获得这些字段属性。

@MappedSuperclass:标注了@MappedSuperclass的类将不是一个完整的实体类,他将不会映射到数据库表,但是他的属性都将映射到其子类的数据库字段中。

@Column:用来标识实体类中属性与数据表中字段的对应关系。

updatable:updatable属性表示 在使用“UPDATE”脚本插入数据时,是否需要更新该字段值。

columnDefinition:表示创建表时,该字段创建的SQL语句,一般用于通过Entity生成表定义时使用。

用户表

先看一下表结构:

字段类型含义
idbigint(20)主键ID
namevarchar(32)用户名
mobilechar(11)手机号
avatarvarchar(255)头像
emailvarchar(50)邮箱
passwordvarchar(12)密码
statustinyint(1)状态:0正常,1锁定
is_deletebit0删除,1未删除
last_login_timedatetime最后登录时间
create_timedatetime创建时间
create_uservarchar(32)创建用户
update_timedatetime更新时间
update_uservarchar(32)更新用户

UserEntity:

@Data
@Entity
@Table(name = "sys_user")
@Schema(description = "用户实体")
public class UserEntity extends BaseEntity implements Serializable {

    @Column(unique = true, columnDefinition = "varchar(32) NOT NULL COMMENT '名称'")
    @Schema(description = "用户名称")
    private String name;

    @Column(columnDefinition = "char(11) COMMENT '手机号'")
    @Schema(description = "手机号")
    private String mobile;

    @Column(columnDefinition = "varchar(255) COMMENT '头像'")
    @Schema(description = "头像")
    private String avatar;

    @Column(columnDefinition = "varchar(50) COMMENT '邮箱'")
    @Schema(description = "用户邮箱")
    private String email;

    @Column(columnDefinition = "varchar(12) NOT NULL COMMENT '密码'")
    @Schema(description = "用户密码")
    private String password;

    @Column(columnDefinition = "datetime COMMENT '最后登录时间'")
    @Schema(description = "最后登录时间")
    private Date lastLoginTime;
}

角色表

表结构:

字段类型含义
idbigint(20)主键ID
namevarchar(32)角色名称
remarkvarchar(255)备注
statustinyint(1)状态
is_deletebit0删除,1未删除
create_timedatetime创建时间
create_uservarchar(32)创建用户
update_timedatetime更新时间
update_uservarchar(32)更新用户

RoleEntity:

@Data
@Entity
@Table(name = "sys_role")
@Schema(description = "角色实体")
public class RoleEntity extends BaseEntity implements Serializable {

    @Column(unique = true, columnDefinition = "varchar(32) NOT NULL COMMENT '角色名称'")
    @Schema(description = "角色名称")
    private String name;

    @Column(columnDefinition = "varchar(500) COMMENT '备注'")
    @Schema(description = "备注")
    private String remark;

}

权限表

表结构:

字段类型含义
idbigint(20)主键ID
pidbigint(20)父菜单ID,一级菜单为0
namevarchar(32)菜单名称
urlvarchar(255)菜单URL
permsvarchar(500)授权(多个用逗号分隔,如:user:list,user:create)
typetinyint(1)类型: 0目录, 1菜单, 2按钮
iconvarchar(50)菜单图标
sorttinyint(2)排序
statustinyint(1)状态
is_deletebit0删除,1未删除
create_timedatetime创建时间
create_uservarchar(32)创建用户
update_timedatetime更新时间
update_uservarchar(32)更新用户

MenuEntity:

@Data
@Entity
@Table(name = "sys_menu")
@Schema(description = "菜单实体")
public class MenuEntity extends BaseEntity implements Serializable {

    @Column(columnDefinition = "bigint NOT NULL COMMENT '父菜单ID'")
    @Schema(description = "父菜单ID")
    private Long pid;

    @Column(unique = true, columnDefinition = "varchar(32) NOT NULL COMMENT '菜单名称'")
    @Schema(description = "菜单名称")
    private String name;

    @Column(columnDefinition = "varchar(255) COMMENT '菜单url'")
    @Schema(description = "url")
    private String url;

    @Column(columnDefinition = "varchar(500) COMMENT '授权(多个用逗号分隔,如:user:list,user:create)'")
    @Schema(description = "授权(多个用逗号分隔,如:user:list,user:create)")
    private String perms;

    @Column(columnDefinition = "tinyint(1) NOT NULL COMMENT '菜单类型:0目录,1菜单,2按钮'")
    @Schema(description = "菜单类型:0目录,1菜单,2按钮")
    private Byte type;

    @Column(columnDefinition = "varchar(50) COMMENT '菜单图标'")
    @Schema(description = "菜单图标")
    private String icon;

    @Column(columnDefinition = "tinyint(2) COMMENT '排序'")
    @Schema(description = "排序")
    private Integer sort;

}

编写好3个entity,启动程序查看建表是否成功。控制台打印如下建表语句,同时查看数据库,发现表创建没有问题。

Hibernate: 
    create table sys_menu (
        id bigint not null auto_increment,
        create_time datetime COMMENT '创建时间',
        create_user varchar(32) COMMENT '创建用户',
        is_delete bit NOT NULL COMMENT '0正常,1删除',
        status tinyint(1) NOT NULL COMMENT '状态',
        update_time datetime COMMENT '修改时间',
        update_user varchar(32) COMMENT '修改用户',
        icon varchar(50) COMMENT '菜单图标',
        name varchar(32) NOT NULL COMMENT '菜单名称',
        perms varchar(500) COMMENT '授权(多个用逗号分隔,如:user:list,user:create)',
        pid bigint NOT NULL COMMENT '父菜单ID',
        sort tinyint(2) COMMENT '排序',
        type tinyint(1) NOT NULL COMMENT '菜单类型:0目录,1菜单,2按钮',
        url varchar(255) COMMENT '菜单url',
        primary key (id)
    ) engine=InnoDB
Hibernate: 
    create table sys_role (
        id bigint not null auto_increment,
        create_time datetime COMMENT '创建时间',
        create_user varchar(32) COMMENT '创建用户',
        is_delete bit NOT NULL COMMENT '0正常,1删除',
        status tinyint(1) NOT NULL COMMENT '状态',
        update_time datetime COMMENT '修改时间',
        update_user varchar(32) COMMENT '修改用户',
        name varchar(32) NOT NULL COMMENT '角色名称',
        remark varchar(500) COMMENT '备注',
        primary key (id)
    ) engine=InnoDB
Hibernate: 
    create table sys_user (
        id bigint not null auto_increment,
        create_time datetime COMMENT '创建时间',
        create_user varchar(32) COMMENT '创建用户',
        is_delete bit NOT NULL COMMENT '0正常,1删除',
        status tinyint(1) NOT NULL COMMENT '状态',
        update_time datetime COMMENT '修改时间',
        update_user varchar(32) COMMENT '修改用户',
        avatar varchar(255) COMMENT '头像',
        email varchar(50) COMMENT '邮箱',
        last_login_time datetime COMMENT '最后登录时间',
        mobile char(11) COMMENT '手机号',
        name varchar(32) NOT NULL COMMENT '名称',
        password varchar(12) NOT NULL COMMENT '密码',
        primary key (id)
    ) engine=InnoDB

同时还为name字段添加了索引,因为我们给name字段添加了 unique=true 表示name字段为唯一,jpa 会为这个字段添加索引。

Hibernate: 
    alter table sys_menu 
       add constraint UK_4kk1vl4bvpaho8ked9v4xkr9d unique (name)
       
Hibernate: 
    alter table sys_role 
       add constraint UK_bqy406dtsr7j7d6fawi1ckyn1 unique (name)
       
Hibernate: 
    alter table sys_user 
       add constraint UK_iic0kskryiymn15fg9bqpmw22 unique (name)

用户角色表

使用实体映射来创建单表很好理解,但是怎么创建关联表呢,我们可以通过Spring Data JPA关系映射中对表关系定义的注解来创建表的关系。

关系注解
注解
@OneToOne定义表之间“一对一”的关系。
@OneToMany定义表之间“一对多”的关系。
@ManyToOne定义表之间“多对一”的关系。
@ManyToMany定义表之间“多对多”的关系。
@ManyToMany

我们之前分析了,我们的表之间的关系都是多对多的关系,所以我们使用 @ManyToMany 来定义表之间的关系,ManyToMany总是会使用中间关系连接表来存储关系,Jpa 会自动帮我们创建中间关联表。

@ManyToMany 注解用来定义具有多对多多重性的多值关联。

每个多对多关系都有两个方面,关系的拥有方和非拥有方。连接表(中间表)在关系的拥有方指定。

如果关联是双向的,任何一方都可以被指定为关系的拥有方。

如果关系是双向的,则关系的非拥有方必须使用 @ManyToMany 注解的 mappingBy 属性来指定拥有方的关系字段或属性。

user表作为主表,在 UserEntity 中添加如下字段

@ManyToMany
@JoinTable(name = "sys_user_role",
        joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
@Schema(description = "用户角色")
private List<RoleEntity> roles;

@JoinTable:@JoinTable 注解用于关联映射,它是在关联的拥有方进行配置。使用 @JoinTable 注解将创建一个连接表,也称为“中间表”。

name:中间连接表名称(sys_user_role),默认是主表_副表(user_role)

joinColumns:连接表主表外键(user_id)

inverseJoinColumns:连接表副表外键(role_id)

role表作为副表,需要使用@ManyToMany 注解的 mappingBy 属性来指定拥有方的关系字段或属性。

@ManyToMany(mappedBy = "roles")
@Schema(description = "角色包含的用户")
private List<UserEntity> users;

**mappedBy:**拥有关系的字段,单向关系不需要指定改属性;双向关系必须指定改属性的值。

添加好两个字段,启动看看是否能够成功创建表,控制台打印了如下sql,没有爆出表明表已经成功。

在这里插入图片描述

角色权限表

这个和用户角色表一模一样,直接上代码

@ManyToMany
@JoinTable(name = "sys_role_menu",
        joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "menu_id", referencedColumnName = "id")})
@Schema(description = "角色菜单")
private List<MenuEntity> menus;
@ManyToMany(mappedBy = "menus")
@Schema(description = "菜单包含的角色")
private List<RoleEntity> roles;

接口开发

先来梳理一下我们有哪些接口需要开发,现在只有 CRUD,后面根据需求慢慢加。

  • 分页查询用户
  • 根据名称查询用户
  • 根据ID查询用户
  • 新增|修改用户(批量)
  • 删除用户

直接上代码了,毕竟都是简单的crud,容易出错的部分拿出讲一下就好了

UserController

@Tag(name = "用户管理")
@RestController
@RequestMapping("/sys/user")
public class UserController {

    @Resource
    private UserService userService;

    @GetMapping("/page")
    @Operation(summary = "分页查询")
    public Page<UserEntity> page(int page, int size) {
        return userService.page(PageRequest.of(page - 1, size));
    }

    @GetMapping("/{id}")
    @Operation(summary = "根据用户ID查询用户")
    public UserEntity get(@PathVariable Long id) {
        return userService.get(id);
    }

    @GetMapping("/name/{name}")
    @Operation(summary = "根据用户名称查询用户")
    public UserEntity getByName(@PathVariable String name) {
        return userService.getByName(name);
    }

    @PostMapping
    @Operation(summary = "新增|修改用户")
    public void upsert(@RequestBody List<UserEntity> users) {
        userService.upsert(users);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "根据用户ID删除用户")
    public void delete(@PathVariable Long id) {
        userService.delete(id);
    }
}

UserService

public interface UserService {

    /**
     * 分页查询用户
     *
     * @param pageable 分页参数
     * @return Page<UserEntity> 分页用户
     */
    Page<UserEntity> page(Pageable pageable);

    /**
     * 根据ID查询用户
     *
     * @param id 用户ID
     * @return UserEntity 用户信息
     */
    UserEntity get(Long id);

    /**
     * 根据名称查询用户
     *
     * @param name 用户名称
     * @return UserEntity 用户信息
     */
    UserEntity getByName(String name);

    /**
     * 保存/更新用户
     *
     * @param users 用户信息
     */
    void upsert(List<UserEntity> users);

    /**
     * 删除用户
     *
     * @param id 用户id
     */
    void delete(Long id);

}

UserServiceImpl

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserRepository userRepository;

    @Override
    public Page<UserEntity> page(Pageable pageable) {
        return userRepository.findAll(pageable);
    }

    @Override
    public UserEntity get(Long id) {
        return userRepository.findById(id).orElse(null);
    }

    @Override
    public UserEntity getByName(String name) {
        return userRepository.findByName(name);
    }

    @Override
    public void upsert(List<UserEntity> users) {
        userRepository.saveAll(users);
    }

    @Override
    public void delete(Long id) {
        userRepository.deleteById(id);
    }

}

UserRepository

@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long>, Serializable {

    /**
     * 根据用户名称查询用户
     * 这个相当与一个公式, findBy字段名称,jpa 就会自动实现查询,不用我们再写查询逻辑
     *
     * @param name 用户名称
     * @return 用户信息
     */
    UserEntity findByName(String name);

}

简单的接口开发完了之后,其实还是存在了3个问题,接下来我们一一来解决。

问题解决

update 更新问题

jpa 中没有单独的 update 方案,他是通过 save 方法来进行更新的,如果 id 为空就是新增,不为空就是修改。

我们先通过新增方法新增一条数据,请求数据如下:

[
  {
    "status": 0,
    "isDelete": true,
    "name": "金克斯",
    "mobile": "11011101111",
    "avatar": "",
    "email": "xm@xm.com",
    "password": "123456",
    "lastLoginTime": "2023-12-12 12:12:12"
  }
]

然后假设我们现在想修改密码为:666666,请求体如下:

[
  {
    "id": 1,
    "password": "666666"
  }
]

按理来说没有如何问题对吧,但是一般这个时候就有问题了,请看VCR。

我们发现请求失败,返回值500,这肯定是后端报错了。

{
  "code": 500,
  "message": "系统异常,请稍后重试",
  "body": null
}

查看控制台日志,发现报错信息如下

java.sql.SQLIntegrityConstraintViolationException: Column 'is_delete' cannot be null

说的是字段 is_delete 不能为空,这是数据库的校验,但是我们没有修改这个字段呀,继续看打印的sql

    select
        ue1_0.id,
        ue1_0.avatar,
        ue1_0.create_time,
        ue1_0.create_user,
        ue1_0.email,
        ue1_0.is_delete,
        ue1_0.last_login_time,
        ue1_0.mobile,
        ue1_0.name,
        ue1_0.password,
        ue1_0.status,
        ue1_0.update_time,
        ue1_0.update_user 
    from
        sys_user ue1_0 
    where
        ue1_0.id=?


	update
        sys_user 
    set
        avatar=?,
        email=?,
        is_delete=?,
        last_login_time=?,
        mobile=?,
        name=?,
        password=?,
        status=?,
        update_time=?,
        update_user=? 
    where
        id=?

ok,答案出来了,jpa 默认更新全部字段,先从数据库查询出这条数据,然后更新全部数据,这可不行,这也太费劲了,我们需要更新我们像更新的字段就行呀,这个可以通过在实体类上添加@DynamicUpdate注解,表示动态更新查询。

@Data
@Entity
@DynamicUpdate
@Table(name = "sys_user")
@Schema(description = "用户实体")
public class UserEntity extends BaseEntity implements Serializable {

重启测试一下,但是发现还是不行,还是更新了全部数据,这是因为jpa会把属性值为null也当成是修改,意思就是当我们没有传入字段时,比如此时 isDelete=null ,但是jpa以为我们要把这个 null 更新到数据库, 这个怎么解决呢,我们自己写一个工具类将属性值为null的数据过滤掉在进行 save 即可,是不是感觉很麻烦。。。

编写一个 JpaUtils:

public class JpaUtils {

    /**
     * 从 src 中复制不为 null 的字段到 target
     *
     * @param src    源实体
     * @param target 目标实体
     */
    public static void copyNotNullProperties(Object src, Object target) {
        BeanUtils.copyProperties(src, target, getNullPropertyNames(src));
    }

    /**
     * 获取实体中为null的属性名称
     *
     * @param source 实体类
     * @return 需要过滤掉的属性名称
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        return Arrays.stream(src.getPropertyDescriptors())
                // 获取每一个属性名称
                .map(FeatureDescriptor::getName)
                // 过滤掉属性值不为null的字段
                .filter(name -> src.getPropertyValue(name) == null)
            	.toArray(String[]::new);
    }

}

修改实现类中的upsert方法

@Override
public void upsert(List<UserEntity> users) {
    users.forEach(user -> {
        Optional<UserEntity> userEntity = userRepository.findById(user.getId());
        if (userEntity.isPresent()) {
            // 修改
            JpaUtils.copyNotNullProperties(user, userEntity.get());
            userRepository.save(userEntity.get());
        } else {
            // 新增
            userRepository.save(user);
        }
    });
}

ok,到此这个问题解决。

懒加载问题

我们在查询用户时,会抛出异常

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: com.xm.module.sys.entity.UserEntity.roles: could not initialize proxy - no Session]

意思是获取 roles 的时候是懒加载的,但是懒加载失败,因为找不到session,那我们就修改为及时加载

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "sys_user_role",
        joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
@Schema(description = "用户角色")
private List<RoleEntity> roles;

**fetch:**关联是应该延迟加载还是必须马上加载。EAGER 策略表示必须马上获取关联的实体,LAZY 策略表示用到关联对象时才去加载。默认值为 javax.persistence.FetchType.LAZY

JSON 循环依赖问题

我们先为用户关联上一个角色,然后再去查询该用户信息,会显示这个,这是因为循环依赖导致返回数据非常大,因为我们的 UserEntity 中包含了 RoleEntity,而 RoleEntity 中有包含有 UserEntity,就会导致这个问题。

在这里插入图片描述

后台报错:

Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError)]

解决方案:

在副表的字段上添加@JsonIgnore注解,表示序列化的时候忽略这个子段。

@JsonIgnore
@ManyToMany(mappedBy = "roles")
@Schema(description = "角色包含的用户")
private List<UserEntity> users;

@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(name = "sys_role_menu",
        joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")},
        inverseJoinColumns = {@JoinColumn(name = "menu_id", referencedColumnName = "id")})
@Schema(description = "角色菜单")
private List<MenuEntity> menus;

最后解决掉这些问题,查询OK,这个JPA的坑还是有点多,如果不清楚他的原理,很容易冒出一些奇怪的问题。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1312104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2020年AMC8数学竞赛真题的典型考点和详细解析

从战争中学习战争。 对于2024年1月19日的AMC8竞赛&#xff0c;如何备考和冲刺取得更好的成绩&#xff1f;六分成长建议通过反复刷真题&#xff0c;来掌握AMC8的出题方式、考点和解题思路&#xff0c;并且对自己前期的学习查漏补缺&#xff0c;这是最快的方式。 如何提高刷真题…

5G边缘网关如何助力打造隧道巡检机器人

我国已建成全世界里程最长的公路网、铁路网&#xff0c;是国民经济发展与国家现代化的重要支撑。我国幅员辽阔&#xff0c;地理环境复杂&#xff0c;公路/铁路的延伸也伴随着许多隧道的建设&#xff0c;由于隧道所穿越山体的地质条件复杂&#xff0c;对于隧道的监测、管理与养护…

HarmonyOS保存应用数据

数据管理 1 概述 在移动互联网蓬勃发展的今天&#xff0c;移动应用给我们生活带来了极大的便利&#xff0c;这些便利的本质在于数据的互联互通。因此在应用的开发中数据存储占据了非常重要的位置&#xff0c;HarmonyOS应用开发也不例外。 本文将为您介绍HarmonyOS提供的数据管…

Excel公式逆天了--使用公式修改其他单元格格式

想必连VBA小白都知道&#xff0c;VBA编程中有两种过程&#xff1a;Sub和Function&#xff08;有时称为UDF&#xff0c;User Defined Function&#xff09;&#xff0c;二者最明显的区别在于Function可以提供返回值&#xff0c;并且在Excel公式可以调用Function。 多数VBA图书都…

言简意赅的 el-table 跨页多选

步骤一 在<el-table>中:row-key"getRowKeys"和selection-change"handleSelectionChange" 在<el-table-column>中type"selection"那列&#xff0c;添加:reserve-selection"true" <el-table:data"tableData"r…

Linux Shell——(函数)

shell函数 1. 函数定义2. 调用函数 总结 最近学习了shell脚本&#xff0c;记录一下shell函数相关语法 1. 函数定义 语法&#xff1a; [funciton] functionname [()] { 语句 [return] } 函数使用前必须先定义funciton关键字是可选的return关键字也是可选的&#xff0c;如果没有…

ChatGPT如何做科研??

2023年我们进入了AI2.0时代。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车&#xff0c;就有可能被淘汰在这个数字化时代&#xff0c;如何能高效地处理文本、文献查阅、PPT…

使用word中的VBA 批量设置Word中所有图片大小

在VBA编辑器中&#xff0c;你可以创建、编辑和运行VBA宏代码&#xff0c;以实现自动化任务和自定义Word 功能。如果你是VBA编程初学者&#xff0c;可以在VBA编辑器中查看Word VBA宏代码示例&#xff0c;以便更好地了解如何使用VBA编写代码。 要打开VBA编辑器&#xff0c;你可以…

压缩软件电脑版哪个好?

压缩软件是我们存储文件、清理电脑、向他人发送文件经常用到的工具&#xff0c;下面就从头到尾操作一遍各个软件压缩步骤&#xff0c;根据需求选择好啦。可以放心的是&#xff0c;这四款软件都经过了安全测试&#xff0c;能够保证文件的安全性&#xff0c;并且能够兼容多种操作…

jmeter,同一线程组内,调用cookie实现接口关联

取cookie方式参考上一篇&#xff1a;jemeter&#xff0c;取“临时重定向的登录接口”响应头中的cookie-CSDN博客 元件结构 登录后要执行的接口为“api/get_event_list/”&#xff0c;在该HTTP请求下创建HTTP信息头管理器&#xff0c;配置如下&#xff1a; 执行测试后&#xff0…

工作遇到问题与解决办法(二)

弹出确认框 this.$confirm(确定删除全部添加的数据吗?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning}).then(() > {// 确定操作this.addYpslTempList[];this.isSelectfalse;//删除状态this.addMultiple true;this.$message({type: success,mes…

Android Studio下载及安装和Gradle的配置(非常详细)从零基础入门到精通,看完这一篇就够了

文章目录 下载安装修改Sdk的位置创建项目修改Gradle的位置查看AS版本工具栏–View项工具栏–Build下的功能说明Build Variants视图说明下载模拟器&#xff08;avd&#xff09;/安卓虚拟设备 屏幕熄灭功能关闭虚拟设备功能删除自己开发的应用软件将开发的应用运行到虚拟设备上。…

java全栈体系结构-架构师之路(持续更新中)

Java 全栈体系结构 数据结构与算法实战&#xff08;已更&#xff09;微服务解决方案数据结构模型(openresty/tengine)实战高并发JVM虚拟机实战性能调优并发编程实战微服务框架源码解读集合框架源码解读分布式架构解决方案分布式消息中间件原理设计模式JavaWebJavaSE新零售电商项…

安卓开发显示加载中

private ProgressDialog loadobj; // 显示 ProgressDialog loadobj loadobj.show(MainActivity.this, "正在加载", "请稍后..."); // 取消 ProgressDialog loadobj.dismiss();或者 public ProgressDialog progressDialog;public void loading(){// …

深入探讨用于图像和视频生成的基于transformer的扩散模型

今天这篇文章探索了基于Transformer的扩散模型&#xff0c;用于图像和视频生成。尽管Transformer体系结构因其灵活性和可扩展性&#xff0c;在各个领域占主导地位&#xff0c;但在视觉生成领域&#xff0c;主要使用基于 CNN 的U-Net体系结构&#xff0c;特别是在基于扩散的模型…

MPLS专线和互联网专线有什么区别?如何选择?

MPLS和互联网专线是什么&#xff1f; MPLS专线和互联网专线是企业网络连接的常见方式。MPLS专线基于多协议标签交换&#xff08;MPLS&#xff09;该技术利用专线连接两个或多个分支机构&#xff0c;提供高质量的数据传输服务。互联网专线是基于公共知识产权基础设施的连接方式…

ElementPlus中的分页逻辑与实现

ElementPlus中的分页逻辑与实现 分页是web开发中必不可少的组件&#xff0c;element团队提供了简洁美观的分页组件&#xff0c;配合table数据可以实现即插即用的分页效果。分页的实现可以分成两种&#xff0c;一是前端分页&#xff0c;二是后端分页。这两种分页分别适用于不同…

c/c++ 文件操作(2)

文件操作读和写 顺序读写 1、fgetc、fputc 函数功能fgetc字符输入函数----->对应打开方式是 “r”fputc字符输出函数-----> 对应打开方式是 “w” 2、fgets、fputs 函数功能fgets文本行输入函数------> 对应打开方式是"r"fputs文本行输出函数------>…

社交网络分析2(上):社交网络情感分析的方法、挑战与前沿技术

社交网络分析2&#xff08;上&#xff09;&#xff1a;社交网络情感分析的方法、挑战与前沿技术 写在最前面1. 情感分析的基本概念社交网络情感分析的挑战与应用 情感分析研究现状2. 根据分析的对象&#xff0c;情感分析可以划分为哪几种类型&#xff0c;简要地进行说明。词汇表…

如何测试和挑选 2024 年最佳 Mac 数据恢复软件

数据是无价的。有些具有货币价值&#xff0c;例如您的银行帐户详细信息或官方文件。其他的则具有情感价值且不可替代&#xff0c;例如家庭照片。所有这些都存储在您的硬盘中&#xff0c;任何事情都可能出错。它可能会遇到技术错误&#xff0c;例如恶意软件攻击或驱动器故障&…