目录

概念

JPA的具体实现

1、引入依赖

2、domain模块配置yml文件

3、实体类(以权限表为例)

4、user模块配置yml文件

5、Dao层接口

6、Service层接口及实现类(以UserService为例)

7、Controller控制层

8、单元测试

9、启动类添加@EntityScan引入实体类的包

概念

基于角色的访问控制(Role-Based Access Control),它包括用户 / 角色 / 权限。

1、用户是发起操作的主体, 按类型分可分为 2B 和 2C 用户, 可以是后台管理系统的用户, 可以是 OA 系统的内部员工, 也可以是面向 C 端的用户, 比如阿里云的用户。

2、角色起到了桥梁的作用, 连接了用户和权限的关系, 每个角色可以关联多个权限, 同时一个用户关联多个角色, 那么这个用户就有了多个角色的多个权限。

java jpa 查时间 一整天的数据_List

一个角色可以与多个用户关联, 管理员只需要把该角色赋予用户, 那么用户就有了该角色下的所有权限, 这样设计既提升了效率, 也有很大的拓展性。

3、权限:
是用户可以访问的资源, 包括页面权限, 操作权限, 数据权限:

  • 页面权限:
    即用户登录系统可以看到的页面, 由菜单来控制, 菜单包括一级菜单和二级菜单, 只要用户有一级和二级菜单的权限, 那么用户就可以访问页面
  • 操作权限:
    即页面的功能按钮,包括查看, 新增, 修改, 删除, 审核等,用户点击删除按钮时,后台会校验用户角色下的所有权限是否包含该删除权限。如果是, 就可以进行下一步操作, 反之提示无权限。

有的系统要求 "可见即可操作", 意思是如果页面上能够看到操作按钮, 那么用户就可以操作, 要实现此需求, 这里就需要前端来配合, 前端开发把用户的权限信息缓存, 在页面判断用户是否包含此权限, 如果有, 就显示该按钮, 如果没有, 就隐藏该按钮。在实际场景可自行选择是否需要这样做,有利于提升用户体验。

  • 数据权限:
    数据权限就是用户在同一页面看到的数据是不同的,比如财务部只能看到其部门下的用户数据,人事部只看人事部的数据。

JPA的具体实现

1、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

2、domain模块配置yml文件

java jpa 查时间 一整天的数据_java_02

3、实体类(以权限表为例)

@Table(name = "privs_tab")
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Privs {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="privs_id")
    private Long id;
    @Column(name="privs_name")
    private String name;
    @Column(name="privs_desc")
    private String desc;

    @Column(name="privs_create_by")
    private String createBy;
    @Column(name="privs_create_time")
    private Date createTime;
    @Column(name="privs_update_time")
    private Date updateTime;
}

4、user模块配置yml文件

server:
  port: 9099

spring:
  application:
    name: bms-user
#屏蔽mybatisplus的多数据源自动启动
  autoconfigure:
    exclude: com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration
logging:
  level:
    com.wnhz.bms.user: debug

5、Dao层接口

@Repository
public interface PrivsDao extends JpaRepository<Privs,Long> {
}
@Repository
public interface UserDao extends JpaRepository<User,Long> {

    //根据user的username和password查询该用户的权限privs
    User findByUsernameAndPassword(String username,String password);
}
@Repository
public interface RoleDao extends JpaRepository<Role,Long> {
}
@Repository
public interface RolePrivsDao extends JpaRepository<RolePrivs,Long> {

    @Query(value = "SELECT * FROM rp_tab WHERE rp_role_id=?",nativeQuery = true)
    List<RolePrivs> findRpsByRoleId(Long roleId);
}

6、Service层接口及实现类(以UserService为例)

public interface UserService {

    //根据user的username和password查询该用户的权限privs
    List<Privs> findUserPrivs(String username, String password);

    //全查询
    List<User> findAllUsers();

    //删除
    void deleteUser(Long id);

    //使用jpa查询某个用户的角色名称及权限
    UserVo findUserRoleNameAndPrivs(String username, String password);

}
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RolePrivsDao rolePrivsDao;
    @Autowired
    private PrivsDao privsDao;

    //根据user的username和password查询该用户的权限privs
    @Override
    public List<Privs> findUserPrivs(String username, String password) {

        List<Privs> privsList = new ArrayList<>();

        User user = userDao.findByUsernameAndPassword(username, password);
        Long roleId = user.getRoleId();

        List<RolePrivs> rpsByRoleId = rolePrivsDao.findRpsByRoleId(roleId);

        rpsByRoleId.forEach(rolePrivs -> {
            Long privsId = rolePrivs.getPrivsId();
            privsList.add(privsDao.findById(privsId).get());
        });

        return privsList;
    }

    //全查询
    //@Cacheable(cacheNames = "findAllUsers") //第一次查询完就放入缓存
    @CachePut(cacheNames = "findAllUsers")  //每次查询每次进缓存
    @Override
    public List<User> findAllUsers() {
        return userDao.findAll();
    }

    //删除
    @CacheEvict(cacheNames = "findAllUsers",key = "#id")
    @Override
    public void deleteUser(Long id) {
        userDao.deleteById(id);
    }

    //使用jpa查询某个用户的角色名称role及权限privs
    @Override
    public UserVo findUserRoleNameAndPrivs(String username, String password) {

        List<Privs> privsList = new ArrayList<>();  //创建一个空的权限列表 privsList,用于存储查询到的权限信息

        User user = userDao.findByUsernameAndPassword(username, password);  //根据用户名和密码查询用户信息,
        Long roleId = user.getRoleId(); //并获取用户的角色ID。

        List<RolePrivs> rpsByRoleId = rolePrivsDao.findRpsByRoleId(roleId); //根据角色ID查询角色权限关系列表

        rpsByRoleId.forEach(rolePrivs -> {  //遍历角色权限关系列表
            Long privsId = rolePrivs.getPrivsId();  //获取权限ID
            privsList.add(privsDao.findById(privsId).get());  //根据权限ID查询对应的权限对象,并添加到权限列表privsList中
        });

        Role role = roleDao.findById(roleId).get(); //根据角色ID查询角色对象
        UserVo userVo = new UserVo();   //创建一个 UserVo 对象
        //将查询到的用户信息、角色信息和权限列表信息分别设置到 UserVo 对象中的相应属性
        userVo.setUser(user);
        userVo.setRole(role);
        userVo.setPrivs(privsList);
        //返回封装好的 UserVo 对象
        return userVo;
    }
}

7、Controller控制层

@RestController
@RequestMapping("/api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/findAllUsers")
    public HttpResp<List<User>> findAllUsers(){
        return HttpResp.success(userService.findAllUsers());
    }

    @DeleteMapping("rmUser")
    public HttpResp rmUser(Long id){
        userService.deleteUser(id);
        return HttpResp.success("删除用户"+id+"成功");
    }
}

8、单元测试

@SpringBootTest
@RunWith(SpringRunner.class)
public class UserServiceImplTest {

    @Autowired
    private UserService userService;

    @Test
    public void findUserPrivs() {
        List<Privs> list = userService.findUserPrivs("jpa", "123");
        list.forEach(e-> System.out.println(e.getName()));
    }

    //使用jpa查询某个用户的角色名称及权限
    @Test
    public void findUserRoleNameAndPrivs() {
        UserVo jpa = userService.findUserRoleNameAndPrivs("jpa", "123");
        System.out.println(jpa.getRole().getName()+"-"+jpa.getPrivs().toString());
    }
}

9、启动类添加@EntityScan引入实体类的包

@SpringBootApplication
@EntityScan(basePackages = "com.****.bms.domain.entity.jpa")
@EnableCaching  //开启spring缓存
public class UserApp {
    public static void main(String[] args) {
        SpringApplication.run(UserApp.class);
    }
}