IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> 数据库(三)——事物、视图、DCL(用户权限操作)、JDBC(操作数据库、API、方法介绍、ResultSet结果集、PreparedStatement以及相关案例)、工具类的封装(练习) -> 正文阅读

[大数据]数据库(三)——事物、视图、DCL(用户权限操作)、JDBC(操作数据库、API、方法介绍、ResultSet结果集、PreparedStatement以及相关案例)、工具类的封装(练习)

数据库(三)

一、事务

1、例子引入

例子:

现在有这么个情况:
在这里插入图片描述

有两个人需要转账,一方转给另一方,按照之前的操作是,甲的账户扣500,乙的账户再加500。问题是如果甲发起了转账操作,钱扣了,这个时候数据库宕机了,再启动数据库,就会发现甲的钱扣了,但是这钱并没有到乙这边来。

所以一个解决方案就是,这两个sql语句为一组,同时执行,要么大家都成功,要么大家都失败。这种执行方式j就是通过事务来管理。

2、事务的概念:

在这里插入图片描述

3、事务执行的指令

在这里插入图片描述

4、事务实现

素材:
在这里插入图片描述

通过事务实现转账功能:

#查询状态
SELECT @@autocommit
#设置为手动提交
SET autocommit=0;
#开启事务
START TRANSACTION;
#实现转账
UPDATE account SET amoney=500 WHERE aname ="华子";
#出错了;fffff
UPDATE account SET amoney=2500 WHERE aname ="刘健";
#回滚
ROLLBACK;
#提交事务
COMMIT;

注意:数据库默认自动提交,我们需要自己设置手动提交;想要使用事务,需要先开启事务;接着就是写 sql 语句;然后有个回滚功能,在提交事务之前,无论执行了多少操作,都可以通过回滚功能返回到未执行操作之前的状态;当操作确定无误后,使用提交事务功能,确认最终状态。切记,提交事务之后就不能再回滚。

5、事务执行的原理

在这里插入图片描述

6、事务的特点(ACID)

()

二、视图

1、视图的概念

在这里插入图片描述

2、视图的作用

在这里插入图片描述
说人话就是:
1、查询出来的表,是一个虚拟表,即便这个虚拟表被更改了,也不会动到数据库里面的那份原表,是对数据库里面的表的一种保护。

2、有些数据经常会被查看,比如首页的数据,或者搜索出来的第一页的数据,如果经常加载这些数据,会加大数据库的负担,可以通过视图加载这些数据形成一个虚拟表,这样每次查看只会看到这张虚拟表,而不用每次都搜索数据库的数据,减少了数据库的负担。

3、创建视图的语法

1.语法:
	create view 视图的名称 as 查询语句
	
2.例子:
	CREATE VIEW v_s AS SELECT ename,eage FROM emp

4、查询视图

1.语法:
	select * from 视图名称
	 
2.例子:
	SELECT * FROM v_s

5、修改视图

1.语法:
	alter view 视图名称 as 查询语句
	 
2.例子:
	ALTER VIEW v_s AS SELECT ename FROM emp

6、删除视图

1.语法: 
	drop view 视图的名称
	
2.例子
	DROP VIEW v_s

三、DCL(对用户以及权限的操作)

1、查询用户

查询数据库的用户,需要先切入到某数据库中,然后再输入查询语句:
在这里插入图片描述

在这里插入图片描述

2、创建用户

1.语法:
	create user '用户名'@'主机名' IDENTIFIED by '密码'
	
2.例子:创建一个huazi用户
	CREATE USER 'huazi'@'localhost' IDENTIFIED BY '123'

3、删除用户

1.语法:
	 drop user '用户名'@'主机名'
	 
2.例子:
	 DROP USER 'huazi'@'localhost'

4、修改用户密码

1.语法: 
	UPDATE USER SET PASSWORD =PASSWORD('新密码') WHERE USER="用户名"
	
2.例子:
	UPDATE USER SET PASSWORD =PASSWORD('abc') WHERE USER="liujian"
	
3.说明:
	msyql中的密码使用的是 md5 加密。

5、查询权限

1.语法:
	show grants for '用户名'@'主机名'
	
2.例子:
	SHOW GRANTS FOR 'root'@'%'

6、设置权限

1.语法:
	GRANT 权限的类型 on 库名.表名 to ‘用户名’@ '主机名'
	
2.例子:
	GRANT SELECT DELETE UPDATE INSERT ON *.* TO 'hua'@'localhost'
		# 权限的类型可以通过 ALL 代表全部权限

7、撤销权限

1.语法:
	revoke 权限的类型 on 库名.表名 from ‘用户名’@ '主机名'
2.说明:
	需要重启服务之后才能生效

四、JDBC

1、JDBC的引入

之前都是通过客户端连接数据库:
在这里插入图片描述

在实际的开发中,更多的是通过代码来操作数据库

2、jdbc概念以及导入和基础搭建

a、jdbc是什么?

在这里插入图片描述

b、jdbc连接的原理

在这里插入图片描述

c、驱动包

如果要使用 jdbc ,首先要准备跟数据库版本相匹配的驱动包。

d、基础搭建

在这里插入图片描述

创建 lib 文件夹:
在这里插入图片描述

粘贴驱动包进来:
在这里插入图片描述

然后右键,添加项目依赖:
在这里插入图片描述

就完成了基础的搭建

3、jdbc操作数据库

a、操作步骤

在这里插入图片描述

b、开始代码输入

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

接着就是通过字符串保存 sql 语句,然后执行这个 sql 语句(这里的是增 / 删 / 改):

在这里插入图片描述

会返回一个 int 值,如果修改成功则是返回 1,否则返回 0。

最后自然是关闭资源:
在这里插入图片描述

那么完整代码:

public static void main(String[] args) {
        try {
            // 通过反射加载驱动类
            Class.forName("com.mysql.jdbc.Driver");

            // 获取链接对象:url地址,数据库用户名和密码
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8", "root", "root");

            // 得到 sql 执行的对象
            Statement sta = con.createStatement();

            // 存放 sql 语句
            String sql = "insert into account values(6,'测试',2222) ";

            // 执行 sql 语句,并获得结果集
            int num = sta.executeUpdate(sql);

            System.out.println(num);    //  输出这个结果集内容
            
            // 关闭资源
            sta.close();
            con.close();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

4、jdbc 的 API 介绍

在这里插入图片描述

5、方法的介绍

在这里插入图片描述

6、ResultSet 结果集

在这里插入图片描述

注意:上面方法中 ,getString 并不是唯一,还有其他很多方法,比如,getDouble 方法等等,这个方法主要是取数据库中的列名(字段名)。

next()方法的使用类似于迭代器的next()

使用方式:
在这里插入图片描述

上图中,一般都不这么取,一般是根据列名来取:
在这里插入图片描述

7、小案例——登录功能的实现

public static void main(String[] args) throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.next();
        System.out.println("请输入密码");
        int pwd = sc.nextInt();
        System.out.println(checkLogin(username, pwd));
    }

    public static boolean checkLogin(String username,int pwd) throws SQLException {
        Connection con = null;
        Statement sta = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
//        获取链接对象:url地址,数据库用户名和密码
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8", "root", "root");
            sta = con.createStatement();

            // 这里的字符串拼接要注意,数据库中的对应字段都有单引号 ' ,所以这块拼接会复杂一点。
            String sql = "select * from admin where username='"+username+"'"+"and pwd='"+pwd+"'";
            System.out.println(sql);
            rs = sta.executeQuery(sql);     //  向数据库发送查询指令,并接收返回的结果

            if (rs.next()){     //  迭代。如果查找到了数据,则能执行 next 语句,意味着用户名跟密码都输入正确
                return true;
            }
            return false;       //  没找到数据,返回失败

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {       //  关闭资源
            if (rs!=null){
                rs.close();
            }
            if (sta!=null){
                sta.close();
            }
            if (con!=null){
                con.close();
            }
        }
        return false;       
    }

8、PreparedStatement

a、登录功能中的 sql 代码缺陷——sql语句注入问题

在上面得登录功能代码中,sql 语句有问题,可以看到这个执行语句最终会判断是否返回 true。如果外部某人通过某手段,向这个sql语句中再加入一些语句,比如 or 1=1,因为 or 语句有一个为真则为真,且 1=1,这个语句恒为真,这时候就会出现重大问题:
在这里插入图片描述

b、防止 sql 注入

在这里插入图片描述

c、PreparedStatement 特点和方法

在这里插入图片描述

PreparedStatement 不会直接扔进数据库,而是先检查语句是否正确,没问题才放到数据库,这种方式效率更高。

在这里插入图片描述

d、PreparedStatement 的使用

原先代码中接收用户输入的方式是这样:
在这里插入图片描述
通过 PreparedStatement 对象的使用,则不用这种方法;而是需要填数据的地方先通过占位符代替这个位置,然后判断是否合理合法,如果合理合法,则继续执行,再通过 setXXX方法去填充这个值,然后自后再提交语句。

e、通过 PreparedStatement 优化登录功能

所以通过这种方式修改的登录代码为:

public static void main(String[] args) throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = sc.next();
        System.out.println("请输入密码");
        int pwd = sc.nextInt();
        System.out.println(checkLogin(username, pwd));
    }

    public static boolean checkLogin(String username,int pwd) throws SQLException {
        Connection con = null;
        Statement sta = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
//        获取链接对象:url地址,数据库用户名和密码
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8", "root", "root");
//            sta = con.createStatement();

            // 这里的字符串拼接要注意,数据库中的对应字段都有单引号 ' ,所以这块拼接会复杂一点。
//            String sql = "select * from admin where username='"+username+"'"+"and pwd='"+pwd+"'";
//            rs = sta.executeQuery(sql);     //  向数据库发送查询指令,并接收返回的结果

            String sql = "select * from admin where username=? and pwd=? ";     //  占位符:?
            PreparedStatement ps = con.prepareStatement(sql);   //  判断该sql语句是否有问题,然后返回相应的对象

            ps.setString(1,username);   //  把数据放到第一个占位符
            ps.setInt(2,pwd);   //  把数据放到第二个占位符

            System.out.println(sql);      // 看看 sql 语句

            rs = ps.executeQuery();     //  向数据库发送查询指令,并接收返回的结果

            if (rs.next()){     //  迭代。如果查找到了数据,则能执行 next 语句,意味着用户名跟密码都输入正确
                return true;
            }
            return false;       //  没找到数据,返回失败

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {       //  关闭资源
            if (rs!=null){
                rs.close();
            }
            if (sta!=null){
                sta.close();
            }
            if (con!=null){
                con.close();
            }
        }
        return false;
    }

9、工具类的封装(练习)

可以发现,上面的代码太多重复了,每次需要用的时候都一大串代码。可以把他们封装起来,只需要输入 sql 语句,再输入相应的数据,即可完成想要的功能。

工具类:

public class BaseDao {
    // 把常用的不变的设置为 静态常量
    public static final String url = "jdbc:mysql:///test";      //  链接本机
    public static final String driver = "com.mysql.jdbc.Driver";    //  驱动路径
    public static final String username = "root";       //  数据库用户名
    public static final String password = "root";       //  数据库密码


    public static Connection getCon(){		//	链接数据库
        Connection con = null;
        try {
            Class.forName(driver);  //  加载驱动

            con = DriverManager.getConnection(url,username,password);   //链接数据库

            return con;     //  返回链接的对象
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static int update(String sql,Object obj[]){      //  增删改功能。executeUpdate方法会返回 int 类型数值,这里返回这个数值判断是否成功
        int num = 0;
        Connection con = null;
        PreparedStatement ps = null;
        try {
            con = getCon();     //  取得链接对象
            ps = con.prepareStatement(sql);     //  用 prepareStatement 校验 sql 语句
            if (obj != null && obj.length>0){   //  数组非空验证
                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i+1,obj[i]);   //  将对应的数据一一跟占位符对应。因为下标从 1 开始,所以这里要 +1。
                }
            }
            num = ps.executeUpdate();   //  执行 sql 语句,并获得结果集
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            closeAll(con,ps,null);
        }
        return num;     //  返回结果集
    }

    public static ResultSet getResultSet(String sql,Object obj[]){      //  查询功能。返回 ResultSet 结果集
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            con = getCon();             //  取得链接对象
            ps = con.prepareStatement(sql);      //  用 prepareStatement 校验 sql 语句
            if (obj != null && obj.length>0){
                for (int i = 0; i < obj.length; i++) {
                    ps.setObject(i+1,obj[i]);
                }
            }
            rs = ps.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return rs;
    }

    public static void closeAll(Connection con,PreparedStatement ps,ResultSet rs){  //  关闭资源
        try {
            if (con != null){
                con.close();
            }
            if (ps != null){
                con.close();
            }
            if (con != null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

测试类:

public static void main(String[] args) throws SQLException {
        //  增加数据
//        String sql = "insert into admin(username,pwd)values(?,?)";
//        Object obj[] ={"admin",1234};
//        int num = BaseDao.update(sql,obj);
//        System.out.println(num);
        
        //  查询数据
        String sql = "select * from admin where username=?";
        Object obj[] ={"admin"};
        ResultSet rs = BaseDao.getResultSet(sql,obj);
        while (rs.next()){
            System.out.println(rs.getString("username"));
        }
    }
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 11:07:42  更:2021-12-10 11:08:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:04:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码