05-权限分配 尚筹网

news2024/11/20 8:44:44

权限控制

权限控制机制的本质就是“用钥匙开锁”。
在这里插入图片描述
在实现权限控制之前,这里先完成给Admin分配Role和给Role分配Auth的功能。

一、给Admin分配Role

目标

​ 通过前端页面操作,将Admin与Role之间的关系保存到数据库

思路

​ 给下面的按钮,添加单击响应函数
在这里插入图片描述
打开如下页面:
在这里插入图片描述
通过左右按钮,可以改变角色分配的情况。

代码

1)、创建关联数据库表

inner_admin_role

USE project_rowd;

CREATE TABLE inner_admin_role
( 
	id INT NOT NULL AUTO_INCREMENT,
	admin_id INT,
	role_id INT,
	PRIMARY KEY (id) 
);

​ 该表因为并不是一个实体类的表,只用于表示关联关系,因此不需要进行逆向工程生成。

2)、前后端代码

修改admin-page.jsp中对应按钮的单击响应函数:

跳转到assign/to/page.html页面,附带当前的页码、关键词以及当前按钮对应的admin的id

<a href="assign/to/page.html?adminId=${admin.id}&pageNum=${requestScope.pageInfo.pageNum}&keyword=${param.keyword}" class="btn btn-success btn-xs">
    <i class=" glyphicon glyphicon-check">
    </i>
</a>

创建处理权限分配功能的控制类:AssignHandler

对应controller中的方法:

@RequestMapping("/assign/to/page.html")
public String toAssignPage(@RequestParam("adminId") Integer adminId, ModelMap modelMap){

    // 得到对应当前adminId未被分配的角色(Role)List
    List<Role> UnAssignedRoleList = roleService.queryUnAssignedRoleList(adminId);

    // 得到对应当前adminId已被分配的角色(Role)List
    List<Role> AssignedRoleList = roleService.queryAssignedRoleList(adminId);

    // 将已选择的、未选择的放入modelMap
    modelMap.addAttribute("UnAssignedRoleList",UnAssignedRoleList);
    modelMap.addAttribute("AssignedRoleList",AssignedRoleList);

    // 请求转发到assign-role.jsp
    return "assign-role";
}

service层方法:

@Override
public List<Role> queryUnAssignedRoleList(Integer adminId) {
    return roleMapper.queryUnAssignedRoleList(adminId);
}

@Override
public List<Role> queryAssignedRoleList(Integer adminId) {
    return roleMapper.queryAssignedRoleList(adminId);
}

roleMapper.xml文件中对应的两个SQL语句(通过in 与 not in查询已分配和未分配的):

<!--查询对应adminId的未被分配的Role-->
<select id="queryUnAssignedRoleList" resultMap="BaseResultMap">
  select id,name
  from t_role
  where
  id not in (select role_id from inner_admin_role where admin_id = #{adminId})
</select>

<!--查询对应adminId的已被分配的Role-->
<select id="queryAssignedRoleList" resultMap="BaseResultMap">
  select id,name
  from t_role
  where
  id in (select role_id from inner_admin_role where admin_id = #{adminId})
</select>

查询到数据,并存入modelMap中后,跳转到assign-role.jsp页面

在该页面显示查询到的信息:

需要在文件的头部引入jstl,使用forEach遍历的到的List,分别在两个select标签中显示出来;并且将前面页面传给后端的页码、关键词、Admin的id放在隐藏域,一起发送给后端。

<form action="assign/do/assign.html" method="post" role="form" class="form-inline">                        
    <!--隐藏域保存不会改变的adminId、pageNum、keyword,在提交时一起传给后端-->
    <input type="hidden" value="${param.adminId}" name="adminId"/>
    <input type="hidden" value="${param.pageNum}" name="pageNum"/>
    <input type="hidden" value="${param.keyword}" name="keyword"/>
    <div class="form-group">
        <label for="exampleInputPassword1">未分配角色列表</label><br>
        <select class="form-control" multiple="" size="10" style="width:100px;overflow-y:auto;">
            <c:forEach items="${requestScope.UnAssignedRoleList}" var="role">
                <option value="${role.id}">${role.name}</option>
            </c:forEach>
        </select>
    </div>
    <div class="form-group">
        <ul>
            <li id="toRightBtn" class="btn btn-default glyphicon glyphicon-chevron-right"></li>
            <br>
            <li id="toLeftBtn" class="btn btn-default glyphicon glyphicon-chevron-left" style="margin-top:20px;"></li>
        </ul>
    </div>
    <div class="form-group" style="margin-left:40px;">
        <label for="exampleInputPassword1">已分配角色列表</label><br>
        <!-- 被选中要分配的部分,name设置为roleIdList -->
        <select name="roleIdList" class="form-control" multiple="" size="10" style="width:100px;overflow-y:auto;">
            <c:forEach items="${requestScope.AssignedRoleList}" var="role">
                <option value="${role.id}">${role.name}</option>
            </c:forEach>
        </select>
    </div>
    <button id="submitBtn" type="submit" style="width:100px;margin-top: 20px;margin-left: 230px;" class="btn btn-sm btn-success btn-block">提交</button>
</form>

完成显示后,需要:

​ ①实现通过左右按钮,调整选中的Role的位置

​ ②给“提交”按钮设置单击响应函数(为了使点击提交的时候,保证已经选中了“已分配”框的全部内容,能将数据完整地传给后端),最后将将表单内容发送给 assign/do/assign.html

<script type="text/javascript">
    $(function () {

        // 给向右的按钮添加单击响应函数,将左边选中的添加到右边
        $("#toRightBtn").click(function (){
            $("select:eq(0)>option:selected").appendTo("select:eq(1)");
        });
        // 给向左的按钮添加单击响应函数,将右边选中的添加到左边
        $("#toLeftBtn").click(function (){
            $("select:eq(1)>option:selected").appendTo("select:eq(0)");
        });

        // 给提交按钮添加单击响应函数,使其在提交前,先全选“已分配角色列表”的选项,使提交时会提交全部
        // 避免不提交之前存在的option的bug
        $("#submitBtn").click(function () {
            $("select:eq(1)>option").prop("selected","selected");
        });

    });
</script>

​ 后端Controller代码:

@RequestMapping("/assign/do/assign.html")
public String saveAdminRoleRelationship(
        @RequestParam("adminId") Integer adminId,
        @RequestParam("pageNum") Integer pageNum,
        @RequestParam("keyword") String keyword,
        // 允许roleIdList为空(因为可能已分配的被清空)
        @RequestParam(value = "roleIdList", required = false) List<Integer> roleIdList
){
	// 调用service层方法
    adminService.saveAdminRoleRelationship(adminId, roleIdList);

    //重定向(减少数据库操作)返回信息页
    return "redirect:/admin/page/page.html?pageNum="+pageNum+"&keyword="+keyword;
}

​ Service层方法:

@Override
public void saveAdminRoleRelationship(Integer adminId, List<Integer> roleIdList) {

    // 先清除旧的对应inner_admin_role表中对应admin_id的数据
    adminMapper.clearOldRelationship(adminId);

    // 如果roleIdList非空,则将该list保存到数据库表中,且admin_id=adminId
    if (roleIdList != null && roleIdList.size() > 0){
        adminMapper.saveAdminRoleRelationship(adminId,roleIdList);
    }
    // roleIdList为空,则清空后不做操作

}

​ AdminMapper.xml中的两个SQL语句:

<!-- 清除inner_admin_role表中对应adminId的旧数据 -->
<delete id="clearOldRelationship">
  delete from inner_admin_role
  where admin_id = #{adminId}
</delete>

<!-- 向inner_admin_role表中插入关系(借助foreach标签) -->
<insert id="saveAdminRoleRelationship">
  insert into inner_admin_role(admin_id, role_id) values
  <foreach collection="roleIdList" item="roleId" separator=",">
    (#{adminId},#{roleId})
  </foreach>
</insert>

​ 这里注意因为插入的语句传入了两个变量,因此需要在mapper接口中用@Param标注出来;下面就是对应的mapper接口的方法:

void saveAdminRoleRelationship(@Param("adminId") Integer adminId, @Param("roleIdList") List<Integer> roleIdList);

void clearOldRelationship(Integer adminId);

至此,已经实现了给Admin分配Role的功能。

二、给Role分配Auth

目标

​ 将Role与Auth的关联关系保存到数据r库。

思路

通过role-page页面的下面的按钮,打开分配Auth的模态框
在这里插入图片描述
模态框:
在这里插入图片描述

代码

1)、准备数据库表

t_auth表:

use project_rowd;

# 建t_auth表
CREATE TABLE t_auth (
	id int(11) NOT NULL AUTO_INCREMENT,
	name varchar(200) DEFAULT NULL,
	title varchar(200) DEFAULT NULL,
	category_id int(11) DEFAULT NULL,

	PRIMARY KEY (id)
);

# 给t_auth表插入数据
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(1,'','用户模块',NULL);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(2,'user:delete','删除',1);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(3,'user:get','查询',1);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(4,'','角色模块',NULL);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(5,'role:delete','删除',4);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(6,'role:get','查询',4);
INSERT INTO t_auth(id,`name`,title,category_id) VALUES(7,'role:add','新增',4);

逆向生成Auth实体类、Mapper,并创建AuthService接口、等。

​ 关联表inner_role_auth:

use project_rowd;

CREATE TABLE inner_role_auth( 
    id INT NOT NULL AUTO_INCREMENT,
    role_id INT,
    auth_id INT,
    PRIMARY KEY (id) 
);

​ 该表和inner_admin_role相似,不需要进行逆向工程

2)、前后端代码

​ 因为role页面的按钮是在my-role.js中动态生成的,修改其中的代码,给checkBtn添加id等于当前的role的id,添加class “checkBtn”:

var checkBtn = "<button type='button' id='"+roleId+"' class='btn btn-success btn-xs checkBtn'><i class=' glyphicon glyphicon-check'></i></button>"

显示树形结构

在role-page.jsp中给对应按钮添加单击响应函数:

// 给分配权限的按钮添加单击响应函数,打开分配模态框
$("#rolePageTBody").on("click",".checkBtn",function () {

    // 将当前按钮的id放入全局变量
    window.roleId = this.id;
    // 打开模态框
    $("#assignModal").modal("show");
    // 生成权限信息
    generateAuthTree();
});

通过zTree生成权限信息generateAuthTree(),且将从后端查到的已经分配的权限回显到模态框中:

这里直接交给zTree自己组装树形结构

​ 要使自动组装需要开启简单JSON功能

// 生成权限信息的树形结构
function generateAuthTree(){

    var ajaxReturn = $.ajax({
        url: "assign/get/tree.json",
        type: "post",
        async: false,
        dataType: "json"
    });

    if (ajaxReturn.status != 200){
        layer.msg("请求出错!错误码:"+ ajaxReturn.status + "错误信息:" + ajaxReturn.statusText);
        return ;
    }

    var resultEntity = ajaxReturn.responseJSON;

    if (resultEntity.result == "FAILED"){
        layer.msg("操作失败!"+resultEntity.message);
    }

    if (resultEntity.result == "SUCCESS"){
        var authList = resultEntity.data;
        // 将服务端查询到的list交给zTree自己组装
        var setting = {
            data: {
                // 开启简单JSON功能
                simpleData: {
                    enable: true,
                    // 通过pIdKey属性设置父节点的属性名,而不使用默认的pId
                    pIdKey: "categoryId"
                },
                key: {
                    // 设置在前端显示的节点名是查询到的title,而不是使用默认的name
                    name:"title"
                },
            },

            check: {
                enable:true
            }
        };

        // 生成树形结构信息
        $.fn.zTree.init($("#authTreeDemo"), setting, authList);

        // 设置节点默认是展开的
        // 1 得到zTreeObj
        var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo");
        // 2 设置默认展开
        zTreeObj.expandAll(true);

        // ----------回显部分----------
        
        // 回显(勾选)后端查出的匹配的权限
        ajaxReturn = $.ajax({
            url: "assign/get/checked/auth/id.json",
            type: "post",
            dataType: "json",
            async: false,
            data:{
                "roleId":window.roleId
            }
        });

        if (ajaxReturn.status != 200){
            layer.msg("请求出错!错误码:"+ ajaxReturn.status + "错误信息:" + ajaxReturn.statusText);
            return ;
        }

        resultEntity = ajaxReturn.responseJSON;

        if (resultEntity.result == "FAILED"){
            layer.msg("操作失败!"+resultEntity.message);
        }

        if (resultEntity.result == "SUCCESS"){
            var authIdArray = resultEntity.data;

            // 遍历得到的autoId的数组
            // 根据authIdArray勾选对应的节点
            for (var i = 0; i < authIdArray.length; i++){
                var authId = authIdArray[i];

                // 通过id得到treeNode
                var treeNode = zTreeObj.getNodeByParam("id",authId);

                // checked设置为true,表示勾选节点
                var checked = true;

                // checkTypeFlag设置为false,表示不联动勾选,
                // 即父节点的子节点未完全勾选时不改变父节点的勾选状态
                // 否则会出现bug:前端只要选了一个子节点,传到后端后,下次再调用时,发现前端那个子节点的所有兄弟节点也被勾选了,
                // 因为在子节点勾选时,父节点也被勾选了,之后前端显示时,联动勾选,导致全部子节点被勾选
                var checkTypeFlag = false;

                // zTreeObj的checkNode方法 执行勾选操作
                zTreeObj.checkNode(treeNode,checked,checkTypeFlag);
            }
        }

    }
}

Controller层**(显示树形结构部分)**:

@ResponseBody
@RequestMapping("/assign/get/tree.json")
public ResultEntity<List<Auth>> getAuthTree(){
    List<Auth> authList = authService.queryAuthList();

    return ResultEntity.successWithData(authList);
}

Service层:

@Override
public List<Auth> queryAuthList() {
    // 直接传入一个new的AuthExample,查询全部的Auth
    return authMapper.selectByExample(new AuthExample());
}

Controller层**(回显已分配权限部分)**:

// 获得被勾选的auth信息
@ResponseBody
@RequestMapping("/assign/get/checked/auth/id.json")
public ResultEntity<List<Integer>> getAuthByRoleId(Integer roleId){
    List<Integer> authIdList = authService.getAuthByRoleId(roleId);
    return ResultEntity.successWithData(authIdList);
}

Service层:

@Override
public List<Integer> getAuthByRoleId(Integer roleId) {
    return authMapper.getAuthByRoleId(roleId);
}

Mapper接口与authMapper.xml文件的sql:

List<Integer> getAuthByRoleId(Integer roleId);
<!--从inner_role_auth查找匹配roleId的auth_id-->
<select id="getAuthByRoleId" resultType="int">
  select auth_id from inner_role_auth
  where role_id = #{roleId}
</select>
分配权限功能

给模态框的提交按钮绑定单击响应函数

// 给分配权限的模态框中的提交按钮设置单击响应函数
$("#assignBtn").click(function () {
    // 声明一个数组,用来存放被勾选的auth的id
    var authIdArray = [];

    // 拿到zTreeObj
    var zTreeObj = $.fn.zTree.getZTreeObj("authTreeDemo");

    // 通过getCheckedNodes方法拿到被选中的option信息
    var authArray = zTreeObj.getCheckedNodes();

    for (var i = 0; i < authArray.length; i++) {
        // 从被选中的auth中遍历得到每一个auth的id
        var authId = authArray[i].id;
        // 通过push方法将得到的id存入authIdArray
        authIdArray.push(authId);
    }
    var requestBody = {
        // 为了后端取值方便,两个数据都用数组格式存放,后端统一用List<Integer>获取
        "roleId":[window.roleId],
        "authIdList":authIdArray
    }
    requestBody = JSON.stringify(requestBody);

    $.ajax({
        url: "assign/do/save/role/auth/relationship.json",
        type: "post",
        data: requestBody,
        contentType: "application/json;charset=UTF-8",
        dataType: "json",
        success: function (response) {
            if (response.result == "SUCCESS"){
                layer.msg("操作成功!");
            }
            if (response.result == "FAILED"){
                layer.msg("操作失败!提示信息:"+ response.message);
            }
        },
        error: function (response) {
            layer.msg(response.status + "  " + response.statusText);
        }
    });

    // 关闭模态框
    $("#assignModal").modal("hide");
});

​ Controller层代码:

@ResponseBody
@RequestMapping("/assign/do/save/role/auth/relationship.json")
public ResultEntity<String> saveRoleAuthRelationship(
    	// 用一个map接收前端发来的数据
        @RequestBody Map<String,List<Integer>> map ) {
	// 保存更改后的Role与Auth关系
    authService.saveRoleAuthRelationship(map);
    
    return ResultEntity.successWithoutData();
}

​ Service层方法:

@Override
public void saveRoleAuthRelationship(Map<String, List<Integer>> map) {
    // 从map获取到roleId、authIdList
    List<Integer> roleIdList = map.get("roleId");
    Integer roleId = roleIdList.get(0);

    List<Integer> authIdList = map.get("authIdList");

    // 1 清除原有的关系信息
    authMapper.deleteOldRelationshipByRoleId(roleId);


    // 2 当authIdList有效时,添加前端获取的新的关系信息
    if (authIdList != null && authIdList.size() > 0){
        authMapper.insertNewRelationship(roleId,authIdList);
    }
}

​ Mapper接口与authMapper.xml文件的sql代码:

void deleteOldRelationshipByRoleId(Integer roleId);

void insertNewRelationship(@Param("roleId") Integer roleId, @Param("authIdList") List<Integer> authIdList);
<!--通过roleId删除inner_role_auth表中旧的关系-->
<delete id="deleteOldRelationshipByRoleId">
  delete from inner_role_auth where
  role_id = #{roleId}
</delete>

<!--向inner_role_auth表中插入新的关系-->
<insert id="insertNewRelationship">
  insert into inner_role_auth(role_id, auth_id) values
  <foreach collection="authIdList" item="authId" separator=",">
    (#{roleId},#{authId})
  </foreach>
</insert>

​ 此时分配权限的功能也实现了。

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

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

相关文章

【ED合集】事件检测的文章

1 CorED: Incorporating Type-level and Instance-level Correlationsfor Fine-grained Event Detection 论文来源&#xff1a;SIGIR 2022(CCF A类会议) 论文链接&#xff1a;https://dl.acm.org/doi/pdf/10.1145/3477495.3531956 代码链接&#xff1a;GitHub - JiaweiSheng…

抖音小程序|基于天气API实现天气预报功能

文章目录 一、前言包含了功能UI展示 二、开发前的准备三、开发步骤1.app.js 配置2.pages/index.js 演示二维码源码在百度网盘下载 一、前言 参考老版iPhone自带的天气预报APP。目前只有一个界面UI, 后续会更新出更多功能; 包含了功能 - 实况预报 - 未来48小时 - 未来一周的天…

动态gif图片如何在线做?轻松实现图片在线生成gif

常见的jpg、png格式的静态图片想要变成gif格式的动态图片时&#xff0c;要怎么办呢&#xff1f;有没有什么简单实用的gif制作工具呢&#xff1f; 一、什么工具能够在线制作gif&#xff1f; GIF中文网作为一款专业的gif制作&#xff08;https://www.gif.cn/&#xff09;工具&a…

Golang - slice 内部实现原理解析

Golang - slice 内部实现原理解析 一.Go中的数组和slice的关系 1.数组 在几乎所有的计算机语言中&#xff0c;数组的实现都是一段连续的内存空间&#xff0c;Go语言数组的实现也是如此&#xff0c;但是Go语言中的数组和C语言中数组还是有所不同的 C语言数组变量是指向数组第…

鸿蒙Hi3861学习七-Huawei LiteOS(信号量)

一、简介 信号量&#xff08;Semaphore&#xff09;是一种实现任务间通信的机制&#xff0c;实现任务之间同步或临界资源的互斥访问。常用于协助一组相互竞争的任务来访问临界资源。 在多任务系统中&#xff0c;各任务之间需要同步或互斥实现临界资源的保护&#xff0c;信号量功…

阿里工作7年,肝到P8就靠这份学习笔记了,已助14个朋友拿到offer

​ 在阿里工作了7年&#xff0c;工作压力大&#xff0c;节奏快&#xff0c;但是从技术上确实得到了成长&#xff0c;尤其是当你维护与大促相关的系统的时候&#xff0c;熬到P8也费了不少心思。 技术的更新迭代越来越快&#xff0c;程序员或许是这个过程中最为挣扎的一波人。每…

第0章 学习之前的准备

突然想写点关于linux的东西&#xff0c;一是将自己几十年来零碎的知识作以串联&#xff0c;二是能为正在学习路上的新手作些指引。而恰好作者的孩子是一位初一的学生&#xff0c;我写的这些东西也正是我手把手教授他的&#xff0c;现在分享出来并且命名为《linux中学教程》&…

记一次SpringBoot应用性能调优过程

背景 使用SpringBoot、MyBatis-Plus开发一个接口转发的能&#xff0c;将第三方接口注册到平台中&#xff0c;由平台对外提供统一的地址&#xff0c;平台转发时记录接口的转发日志信息。开发完成后使用Jmeter进行性能测试&#xff0c;使用100个线程、持续压测180秒&#xff0c;…

Java中池化技术探讨

背景&#xff1a;在日常开发中&#xff0c;除了考虑IO操作、线程上下文切换、GC的影响性能外。还通过池化技术提高性能通过循环复用资源&#xff0c;降低资源创建和销毁带来的开销和损失&#xff0c;从而提高性能&#xff0c;例如对象池、内存池、线程池、连接池 一、对象池&a…

软件测试 - 测试用例设计方法之等价类划分和边界值分析

1. 等价类划分法 1.1 基本理论 等价类划分法是通过科学的方法找到具有共同特性的测试输入的集合&#xff0c;避免进行穷举测试&#xff0c;大大减少了测试用例的数量&#xff0c;从而提高测试效率。等价类划分法的典型应用场景就是输入框&#xff0c;适用于较少数量输入框的场…

晶振概述及工作原理

晶振在电路板中随处可见&#xff0c;只要用到处理器的地方就必定有晶振的存在&#xff0c;即使没有外部晶振&#xff0c;芯片内部也有晶振。 晶振概述 晶振一般指晶体振荡器。晶体振荡器是指从一块石英晶体上按一定方位角切下薄片&#xff08;简称为晶片&#xff09;&#xf…

虚拟服务器基础架构解决方案:用最小的工作量实现最大的价值

虚拟服务器基础架构解决方案&#xff1a;用最小的工作量实现最大的价值 一切皆可虚拟化&#xff01;包括服务器在内。NetApp 虚拟服务器基础架构解决方案有助于加快数据访问速度、构建创新服务并简化部署&#xff0c;从而实现最大价值。 为什么选择 NetApp 的虚拟服务器基础架…

pytorch矩阵乘法总结

1. element-wise&#xff08;*&#xff09; 按元素相乘&#xff0c;支持广播&#xff0c;等价于torch.mul() a torch.tensor([[1, 2], [3, 4]]) b torch.tensor([[2, 3], [4, 5]]) c a*b # 等价于torch.mul(a,b) # tensor([[ 2, 6], # [12, 20]]) a * torch.tenso…

详解C++类对象(上篇)——超详细

目录 一&#xff0c;面向对象&面向过程的认识(简单了解即可&#xff0c;逐步认识&#xff09; 二&#xff0c; 类 2.1 类的引入 2.2 类的定义 1. struct 2. class 类的两种定义方式&#xff1a; 2.3 封装&类的访问限定符 1. 封装概念 2. 类的访问限定符 …

低代码如何不写代码创建表单和维护表单

工作表新建与修改 新建工作表的流程包含 新建工作表/编辑公祖表为工作表添加字段&#xff0c;例如“员工档案”表中有姓名、性别、年龄等字段为字段设置属性工作表布局工作表预览、保存、关闭 1、新建工作表/修改工作表 新建工作表 修改工作表 2、为工作表添加字段 添加字段 左…

关于C语言的一些杂记2

文章目录 sizeof运算符内容关于基本概念的问题关于一些语句的理解和分号的注意字符的理解关于输出格式的扩展 本文内容摘自C技能树一些优秀的博主 sizeof运算符内容 关于基本概念的问题 sizeof是C语言的关键字&#xff0c;它用来计算变量&#xff08;或数据类型&#xff09;在…

2.Hive创建数据库

1.数据库操作 1.1 创建数据库 create database test comment Just for test location /abcd with dbproperties(aaabbb); comment后面指的是注释&#xff1b;location后面是数据库存放路径&#xff1b;dbproperties代表了数据库的属性 ps.避免要创建的数据库已经存在错误&…

Vue最新状态管理工具Pinia——Pinia的安装与使用

Pinia从了解到实际运用——pinia的安装与使用 知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现一、环境搭建1.创建项目2.安装pinia 二、基本使用1.创建pinia示例并挂载2.基本使用访问state使用getters使用actions 3.详细示例&#xff08;详细注解&#xff0…

【23】核心易中期刊推荐——视觉/图像感知与识别人工智能算法及应用​​​​​​​

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

2023年盐城工学院五年一贯制专转本旅游学概论考试大纲

2023年盐城工学院五年一贯制专转本旅游学概论考试大纲 一、考核对象 本课程的考核对象是五年一贯制高职专升本酒店管理专业考生。 二、考核方式 本课程考核采用闭卷考试的方式。 三、考核要求 掌握旅游学的基本原理&#xff0c;掌握旅游学的核心概念&#xff0c;具备旅游…