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

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的坑还是有点多,如果不清楚他的原理,很容易冒出一些奇怪的问题。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于ssm高校食堂订餐系统论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本高校食堂订餐系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

服务器数据恢复-EqualLogic PS存储硬盘坏道导致存储不可用的数据恢复案例

服务器数据恢复环境&#xff1a; 一台DELL EqualLogic PS系列存储&#xff0c;存储中有一组由16块SAS硬盘组成的RAID5。上层是VMFS文件系统&#xff0c;存放虚拟机文件。存储上层分了4个卷。 服务器故障&检测&#xff1a; 存储上有2个硬盘指示灯显示黄色&#xff0c;磁盘出…

51单片机的外部中断的以及相关寄存器的讲解

中断系统 本文主要涉及8051单片机的中断系统的讲解与使用 其中包括中断相关寄存器的介绍与使用以及外部中断初始化的代码分析。 文章目录 中断系统一、 中断的介绍二、 中断结构及相关寄存器2.1 中断源 2.2 中断请求控制器2.2.1 TCON寄存器2.2.2 SCON寄存器2.2.3 中断允许寄存器…

Spark与PySpark(1.概述、框架、模块)

目录 1.Spark 概念 2. Hadoop和Spark的对比 3. Spark特点 3.1 运行速度快 3.2 简单易用 3.3 通用性强 3.4 可以允许运行在很多地方 4. Spark框架模块 4.1 Spark Core 4.2 SparkSQL 4.3 SparkStreaming 4.4 MLlib 4.5 GraphX 5. Spark的运行模式 5.1 本地模式(单机) Local运行模…

智能优化算法应用:基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于模拟退火算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.模拟退火算法4.实验参数设定5.算法结果6.…

2036开关门,1109开关门

一&#xff1a;2036开关门 1.1题目 1.2思路 1.每次都是房间号是服务员的倍数的时候做处理&#xff0c;所以外层&#xff08;i&#xff09;枚举服务员1~n&#xff0c;内层&#xff08;j&#xff09;枚举房间号1~n&#xff0c;当j % i0时&#xff0c;做处理 2.这个处理指的是&…

module ‘tensorflow‘ has no attribute XXX 报错解决

问题描述&#xff1a; 粘了别人的tensorflow项目&#xff0c;运行总是报错module ‘tensorflow’ has no attribute什么什么 问题解决&#xff1a; 导入tensorflow的代码如下 import tensorflow as tf此时&#xff0c;某个某块报错&#xff0c;比如下面这个 那么就直接把tf.…

【【ZYNQ 7020显示 图片 实验 】】

ZYNQ 7020显示 图片 实验 关键配置 BRAM 因为本次 我想显示的 图片是 400*400 所以在 内部 的 ROM 存储单元选择 了160000 ZYNQ7020的内部资源 最多是 大概 200000左右的 大小 大家可以根据 资源选择合适的像素 此处存放 内部的 图片转文字的COE文件 PLL设置 我选用的是按…

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

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

第二证券:京沪楼市松绑,地产板块强势拉升,京能置业等涨停

地产板块15日盘中强势拉升&#xff0c;到发稿&#xff0c;上实开展、京能置业、大龙地产、新黄浦等涨停&#xff0c;京投开展涨逾6%&#xff0c;保利开展、招商蛇口等涨超3%。 消息面上&#xff0c;12月14日&#xff0c;北京发布调整优化一般住所标准和个人住所告贷政策的告诉…

MIT_线性代数笔记:第 17 讲 正交矩阵和施密特正交化

目录 正交向量 Orthonormal vectors标准正交矩阵 Orthonormal matrix标准正交列向量的优势 Orthonormal columns are good施密特正交化 Gram-Schmidt 本讲我们完成对“正交”的介绍。Gram-Schmidt 过程可以将原空间的一组基转变为标准正交基。 正交向量 Orthonormal vectors 满…

PyQt6 一个简单的例子

PyQt6简单例子 需求代码目录代码实现代码运行效果 需求 1、通过PyQt6实现一个小的应用程序&#xff0c;并设置应用程序的图标&#xff0c;应用程序的标题&#xff0c;然后再提示一个气泡框&#xff0c;不过显示一会就会消失不见。 代码目录 在PyQt文件夹下新建一个包&#x…

五、Shell 注释

一、单行注释 以井号&#xff08;#&#xff09;来注释单行&#xff0c;Shell 并不会处理 Shell 脚本中的注释行。然而 Shell 脚本第一行是个例外&#xff0c;# 号后面的感叹号&#xff08;!&#xff09;是用来告诉系统用哪个解释器来运行脚本。示例和运行结果如图所示&#xf…

基于Java SSM框架实现在线课程教育资源考试管理系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架实现在线课程教育资源考试管理系统演示 摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线教育资源管理系统&#xff0c;主要的模块包括管理员&#xff1b;个人中心、学生…

GoLang EASY 微服务游戏框架 01

1 Overview EASY 是一个go语言编写的框架&#xff0c;兼容性支持go版本1.19&#xff0c;go mod 方式构建管理。它是一个轻型&#xff0c;灵活&#xff0c;自定义适配强的微服务框架。 它支持多种网络协议TCP&#xff0c;websocket&#xff0c;UDP&#xff08;待完成&#xf…

java-sec-code的xss

java-sec-code 用于学习java漏洞代码 环境部署 直接在idea中使用git 运行即可 RequestMapping("/reflect") ResponseBody public static String reflect(String xss) {return xss;}当用户访问到/reflect URL地址时&#xff0c;程序会自动调用reflect方法&#xff0c…

机器视觉系统选型-工业相机的焦距

机器视觉项目需要尽快完成&#xff0c;需要有能力&#xff0c;有技术&#xff0c;经过项目的毒打过的老员工才可以扛起“战时状态”大旗&#xff0c;并且充分完成此类机器视觉项目&#xff0c;毫不夸张地说&#xff0c;就是公司机器视觉项目的顶梁柱。老员工就是机器视觉公司的…

【力扣】19. 删除链表的倒数第 N 个结点

19. 删除链表的倒数第 N 个结点 相比于昨天&#xff0c;感觉刷题越来越轻松了~ 我进步了&#xff01; 以后刷题力度要加快了&#xff0c;因为我报了蓝桥杯&#xff01;加油~ 法一&#xff1a;计算链表长度 思路&#xff1a; 首先用个函数来计算出该链表的长度&#xff0c;然…

【PWN】学习笔记(三)【返回导向编程】(下)

目录 课程回顾ret2libc![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ebe1a9a9e54f4319946621dbe89c5774.png)做题 课程 课程链接&#xff1a;https://www.bilibili.com/video/BV1854y1y7Ro/?vd_source7b06bd7a9dd90c45c5c9c44d12e7b4e6 课程附件&#xff1a; h…

Linux:时间显示(函数介绍)

文章目录 1、sleep&#xff1a;延迟函数2、time/localtime3、示例&#xff1a;sleep time localtime4、Linux时间调整 1、sleep&#xff1a;延迟函数 函数原型&#xff1a;unsigned int sleep(unsigned int seconds); 功 能&#xff1a;延时 参 数&#xff1a;seconds:秒&am…