硅基计划5.0 MySQL 陆 视图&JDBC编程&用户权限控制


文章目录

    • 一、视图
      • [1. 定义](#1. 定义)
      • [2. 创建视图](#2. 创建视图)
      • [3. 修改视图](#3. 修改视图)
      • [4. 无法修改视图,并且也无法影响到真实表的情况------面试题](#4. 无法修改视图,并且也无法影响到真实表的情况——面试题)
      • [5. 删除视图](#5. 删除视图)
    • 二、JDBC编程(非查询)
      • [1. 创建数据源](#1. 创建数据源)
      • [2. 设置用户名以及密码](#2. 设置用户名以及密码)
      • [3. 与数据库建立网络连接](#3. 与数据库建立网络连接)
      • [4. 撰写对应SQL语句](#4. 撰写对应SQL语句)
      • [5. 发送语句到服务器](#5. 发送语句到服务器)
      • [6. 释放资源](#6. 释放资源)
      • [7. 最终结果](#7. 最终结果)
      • [8. 用户输入型](#8. 用户输入型)
      • [9. 小结](#9. 小结)
    • 三、JDBC编程(查询)
    • 四、用户权限管理------一般用不到
      • [1. 创建用户](#1. 创建用户)
      • [2. 修改密码](#2. 修改密码)
      • [3. 删除用户](#3. 删除用户)
      • [4. 权限控制](#4. 权限控制)

一、视图

1. 定义

我们create创建的是一个实际的表,是真实存在于数据库之内的

反之我们现在的视图是一个虚拟的表,具有临时性,本身不存在于硬盘中,从而也不会占用实际的存储空间

我们把查询的结果呈现出来,比如select语句的结果集,就是一种视图

2. 创建视图

sql 复制代码
create view 表名 as 相关的查询语句;

比如我用之前的学生表,我只想把一班的学生筛选出来放入视图

sql 复制代码
create view class_id_1 as select * from student where class_id = 1;

这个视图创建出来后,我们可以通过show tables看到,但是虽然看起来和其他表一样,但是本质上我们创建的还是一个视图

其实如果你仔细观察,你会发现,视图其实就是一种子查询,因为我们把查询的结果集放入了一个"表"中,我们利用这个视图,可以针对这个结果集再进行其他增删改查操作

这也就避免了子查询的多层嵌套造成的代码复杂的问题

我们还可以指定原表哪些列去构建视图,然后针对不同的列起别名,只能是英文的别名

sql 复制代码
create view class_id_2(列别名1,列别名2......) as select name,class_id from student where class_id = 1;

3. 修改视图

当我们修改真实表的时候,视图的数据也是会同步更新

反之,修改视图的时候,真实的表也会同步更新

因此他们之间是相辅相成的,说白了他们之间就是关联的,视图本质上就是真实表的一种投影

4. 无法修改视图,并且也无法影响到真实表的情况------面试题

  1. 创建视图的时候,使用了聚合函数
  2. 视图关联查询中,存在去重查询、带有group byhaving关键字、带有unionunion all关键字、使用了子查询去创建视图和使用了不可修改的视图再去创建

其实上述本质上就是一个问题,我们上面那些语句创建的是一个结果集,比如聚合函数,我们求和后是把多行数据整合到一起

如果我们修改,就无法定位到原始的真实表中哪一行数据要修改

再比如去重查询,假设有很多重复条件,那我们修改去重结果,就无法定位到原本真实表中哪一行数据要修改,也就无法定位到原始数据归属在哪里

5. 删除视图

我们不可以直接drop table,因为本质上不是一个真正的表,因此我们要drop view 视图名

二、JDBC编程(非查询)

这是Java与MySQL数据库之间的联动,通过驱动进行连接,需要我们额外下载自行导入

我们之前一直都是在写sql语句,都是要自己手动执行

一旦有了JDBC,我们就可以让其自动调用,自动执行

因此MySQL提供了很多API(提供函数、方法、类等等)可供开发者调用

因为MySQL是使用C/C++开发的,因此提供的API对于其他语言需要进行封装再进一步调用

因此我们Java就提供了一套API,其他数据库兼容这个API,对接到这个JavaAPI,就叫JDBC

关于驱动包的下载和导入在这里就不再赘述,可以自行上网搜索详细教程

1. 创建数据源

我们使用DataSource接口类然后去实例化MySqlDataSource类,然后再把DataSource类强转为MySqlDataSouece类,调用setUrl方法去获取我们数据库的位置

java 复制代码
public class TestJdbc {
    public static void main(String[] args) {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/home?CharacterEncoding=utf8&useSSL=false");
    }
}

当然还可以这样写

java 复制代码
MysqlDataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/home?CharacterEncoding=utf8&useSSL=false");

为什么我们实际开发中还是推崇第一种写法呢,这是因为我们那样写,在实际开发中无需关心类型,便于灵活地去切换不同的数据库

但是这种写法我们还是不推崇,在之后的代码中,我们还是会提供一个get方法去返回DateSouece类型

我们来解释下各个部分的具体信息

java 复制代码
// 这个 URL 的每个参数来源:
String url = "jdbc:mysql://127.0.0.1:3306/home?CharacterEncoding=utf8&useSSL=false";

URL:即唯一资源定位符,用来明确某个网络资源其位置在哪

我们对逐个模块进行分解

  1. jdbc:mysql,即明确URL是用来干什么的,我们这种解释就是在告诉编辑器我们这个URL就是给MySQL用的
  2. 127.0.0.1,这个是IP地址,用来明确一台主机在网络中的位置
  3. 3306,这个是端口号,每一个应用程序对应一个端口号

2. 设置用户名以及密码

java 复制代码
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("123456789");

3. 与数据库建立网络连接

java 复制代码
Connection connection = dataSource.getConnection();

我们正常抛出异常,此时我们就可以测试下有没有连接成功,如果出现异常就代表没有成功

4. 撰写对应SQL语句

首先我们可以先在SQL中创建对应的表,比如我们现在执行插入操作

java 复制代码
String sql = "insert into student values('赵六',2,21)";

但是字符串不符合JDBC的要求,因此我们需要创造对象去使用,我们提供两种方法

java 复制代码
Statement statement = connection.createStatement();
statement.addBatch(sql);//不推荐

PreparedStatement preparedStatement = connection.prepareStatement(sql);//推荐

为什么我们推荐下面那种写法,因为下面那种写法是预处理的,对于其服务器检查SQL是否合规变成了在客户端进行,大大降低了服务器的多人同时使用的负担

5. 发送语句到服务器

java 复制代码
int ret = preparedStatement.executeUpdate();

返回的是一个整数,代表这个语句影响了多少行的内容

6. 释放资源

请注意,释放资源的时候,我们是按照什么顺序创建的,就要反着按照什么顺序释放掉

java 复制代码
preparedStatement.close();
connection.close();

7. 最终结果

8. 用户输入型

但是你是否发现,我们现在都把SQL语句写死了,如果用户想通过输入来输入数据,那就非常不方便

如果采用最原始的字符串拼接做法,会非常麻烦,而且不安全,如果用户输入了非法字符呢,因此我们采用占位符和PreparedStatement中对应的set方法完成创建

java 复制代码
Scanner sc = new Scanner(System.in);
String name = sc.next();
int id = sc.nextInt();
int age = sc.nextInt();
String sql1 = "insert into student values(?,?,?)";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql1);
preparedStatement1.setString(1,name);
preparedStatement1.setInt(2,id);
preparedStatement1.setInt(3,age);
int ret1 = preparedStatement1.executeUpdate();

9. 小结

不管是插入,删除还是修改,大体上还是一样的,但是我们日常工作中还是很少用到,我们以后主要还是去使用一些框架

三、JDBC编程(查询)

这个大体上还是差不多,只不过在发送给服务器那里有变化

java 复制代码
String sql2 = "select * from student";
PreparedStatement preparedStatement1 = connection.prepareStatement(sql2);
ResultSet resultSet = preparedStatement1.executeQuery();
while(resultSet.next()){
    String name = resultSet.getString("name");
    int id = resultSet.getInt("class_id");
    int age = resultSet.getInt("age");
    System.out.print(name+" "+id+" "+age+"   ||  ");
}
preparedStatement1.close();
statement.close();

这里多表查询也是类似的,就不过多演示了

四、用户权限管理------一般用不到

我们在实际工作中,是很少让我们自己配置的,一般都是别人配置好的,因此我们这部分内容不会讲的很详细

我们创建数据库的时候,有一个默认的管理员用户,可以任意操控数据库,然而在实际的公司运作中,我们都是让有深度开发经验的人拥有高权限,而其他的程序员或者用户只能有部分数据库的读写权利

  1. host: 允许登录的主机,如果是localhost,表示只能从本机登陆
  2. authentication_string:加密后用户的密码

1. 创建用户

sql 复制代码
create user '用户名'@'主机名(host)' identified by '密码';

比如我们创建一个测试用户

sql 复制代码
create user 'test_user'@'localhost' identified by '123456789';

接下来我们查看user表中存在我们创建的这个用户,但是各个权限都是没有的

如果我们想创建一个在任意机器访问的

sql 复制代码
create user 'test_users'@'%' identified by '123456789';

2. 修改密码

我们通过alter关键字实现

sql 复制代码
alter user '用户名'@'主机名' identified by mysql_native_password by '密码';

比如我修改我们刚刚创建的那个用户的密码

sql 复制代码
alter user 'test_user'@'localhost' identified with mysql_native_password by '123456';

3. 删除用户

sql 复制代码
drop user '用户名'@'主机名';

比如我们把我们刚刚创建的用户删除掉

sql 复制代码
drop user 'test_user'@'localhost';

4. 权限控制

里面有非常多的权限,具体可以参考文档,这里仅列举几个常见的权限

  • `all'或者是'all privilege':全部权限
  • selectinsertupdatedeletealterdropcreate等等权限顾名思义,之前的文章已经介绍过了,就不赘述了
  1. 查询权限
sql 复制代码
show grants for '用户名'@'主机名';

比如查询我们默认的root用户

sql 复制代码
show grants for 'root'@'localhost';

因为默认是管理员权限,因此可以有针对这个数据库的所有权限

  1. 授予权限
sql 复制代码
grant 权限 on 数据库名/表名 to '用户名'@'主机名';

比如把我们创建的测试用户授予所有权限

sql 复制代码
grant all on home to 'test_user'@'localhost';

当然若想授予所有数据库,可以使用*通配符替代

  1. 撤销权限
sql 复制代码
revoke 权限 on 数据库名/表名 from '用户名'@'主机名';

我们可以把刚刚的测试用户权限全部撤回

sql 复制代码
revoke all on home from 'test_user'@'localhost';

如果想授予多个权限,中间要使用,分隔

但是一般在公司中,只有测试运维或者是数据库管理员才会执行这些sql语句,普通开发人员并没有这个权限控制


希望本篇文章对您有帮助,有错误您可以指出,我们友好交流


END

相关推荐
摇滚侠3 小时前
Spring Boot3零基础教程,自定义 starter,把项目封装成依赖给别人使用,笔记65
数据库·spring boot·笔记
不剪发的Tony老师3 小时前
SQLiteSpy:一款轻量级的SQLite管理工具
数据库·sqlite
VT.馒头3 小时前
【力扣】2725. 间隔取消
javascript·leetcode·1024程序员节
一 乐3 小时前
车辆管理|校园车辆信息|基于SprinBoot+vue的校园车辆管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·车辆管理
vistaup3 小时前
Android 基于清单文件mate-data数据共享
1024程序员节
得物技术3 小时前
告别数据无序:得物数据研发与管理平台的破局之路
大数据·数据库·数据分析
百锦再3 小时前
Python、Java与Go:AI大模型时代的语言抉择
java·前端·vue.js·人工智能·python·go·1024程序员节
笑对人生任我行4 小时前
ORM 使用说明
1024程序员节
杨筱毅4 小时前
【底层机制】【Android】【面试】Zygote 为什么使用 Socket 而不是 Binder?
android·1024程序员节·底层机制