SQL—MySQL基础教程(新手向)


前言

文章主要讲述数据库相关概念,MySQL的基本使用。我觉得这些都是MySQL中比较重要且精华的部分,有些没有提到的点都是基本不会用到的(当然了,也可能是我菜,根本没学)


一、数据库

1.概念

数据库:(DB,DataBase):安装在操作系统之(windows,Linux,mac)上的数据仓库软件。可以存储大量的数据

2.分类

  1. 关系型数据库:(SQL):
    - MySQL, Oracle, SQL Server, DB2, SQLite
    - 通过表和表之间,行和列之间的关系进行数据的存储
  2. 非关系型数据库:(NoSQL) Not Only SQL
    - Redis, MongDB
    - 非关系型数据库,对象存储,通过对象自身的属性来决定。

二、MySQL基本概念

1.概念

MySQL是一个关系型数据库管理系统

2.安装

这里给出 官方下载网址
(建议不建议下载压缩包,有点麻烦)
跟着百度下载教程走就好了

3.启动关闭连接

安装完成之后记得配置环境变量,然后cmd

net start --查看mysql80是否开启
net start mysql80 --开启
net stop mysql80  --关闭

mysql -u 用户名 -p密码  --连接数据库
quit  --退出数据库

4.操作数据库

数据库里的操作是大小写不敏感的

--创建数据库
CREATE DATABASE IF NOT EXISTS mysql01; 
--删除数据库
DROP DATABASE IF EXISTS mysql01;
--使用数据库
USE mysql01;
--查看数据库
SHOW DATABASES;

5.变量类型

  1. 数值:
    - int:标准的整数 4字节
    - float:浮点数 4字节
    - double:浮点数 8字节
  2. 字符串:
    - char:字符串长度大小固定 0~55
    - varchar:可变字符串 0~65535
    - text:文本串 2^16-1
  3. 时间:
    - data:YYYY-MM-DD
    - time:HH:mm:ss
    - datatime:YYYY-MM-DD HH:mm:ss
    - timestamp:时间戳 1970.1.1到现在的毫秒

6.字段属性

  1. 每个表都必须存在五个字段:
    - id 主键
    - version 乐观锁
    - is_delete 伪删除
    - gmt_create 创建时间
    - gmt_update 修改时间)
  2. unsigned:无符号整数
  3. zerofill:int(3) 1–>001
  4. auto_increment:自增,自动在上一条记录的基础上+1。可以设置起始值和步长。通常用来设计主键
  5. NULL not null:非空

7.表

  1. 数据表引擎(ENGINE):INNODB和MYISAM(了解)
  2. 创建表
    --格式
    CREATE TABLE [IF NOT EXISTS] `表名`(	
    `字段名` 列类型 [属性] [索引] [注释],
    `字段名` 列类型 [属性] [索引] [注释],
    PRIMARY KEY(`id`)
    )[表类型][表字符集设置][注释]
    
    --举例
    CREATE TABLE IF NOT EXISTS `student` (    	
    `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
     `name` VARCHAR(20) NOT NULL DEFAULT '匿名' COMMENT '姓名',
     PRIMARY KEY(`id`)
    )ENGINE=INNODB DEFAULT CHARSET=utf8
    
    SHOW CREATE DATABASE school -- 查看创建数据库的语句
    SHOW CREATE TABLE student -- 查看student数据表的定义语句
    DESC student -- 显示表的结构
    
  3. 修改表
    -- 修改表名:ALTER TABLE 旧表名  RENAME AS 新表名
    ALTER TABLE teacher RENAME AS teacher1
    
    -- 增加表的字段 ALTER TABLE  表名  ADD 字段名 列类型
    ALTER TABLE teacher ADD age INT(11)
    
    --修改表的字段  
    -- ALTER TABLE 表名 MODIFY 字段名 列类型[]
    ALTER TABLE teacher1 MODIFY age VARCHAR(10)-- 修改约束
    -- ALTER TABLE 表名 CHANGE 旧名字  新名字 列类型[]
    ALTER TABLE teacher1 CHANGE age age1 INT(1)--修改表的字段
    -- ALTER TABLE 表名 DROP 字段名
     ALTER TABLE teacher1 DROP age1--删除表的字段:
    

三、MySQL数据管理

1.CRUD

  1. insert

    -- 插入语句(添加)--
    -- insert into `表名` (`字段1`,`字段2`,`字段3`) values('值1'),('值2'),('值3')
    INSERT INTO `user` (`id`) VALUES ('1'),('2');-- 匹配一个字段,插入两个值
    INSERT INTO `user` (`name`,`id`,`pwd`) VALUES('a','1','a');-- 匹配多个字段,插入一个值
    INSERT INTO `user` (`name`,`id`,`pwd`) VALUES('a','1','a'),('b','2','b');-- 匹配多个字段,插入多个值
    
  2. update

    -- UPDATE `表名` SET `字段名`='value',[`字段名`='value',...] where [条件]
    UPDATE `user` SET `pwd`='a' WHERE `name` = 'a';
    
  3. delete

    -- delete from 表名 [where 条件]
    DELETE FROM `user` WHERE id=1;
    
  4. select

    -- 查询指定的字段  SELECT 字段,[字段2],[字段3] FROM 表
    -- 数据库的列可以是表达式:文本值,列,null,函数,计算表达式,系统变量…
    SELECT `id`+ 1 AS 编号,`name` AS 姓名 FROM user;
    -- 顺序
    SELECT * FROM user;
    [left | right | inner join table_name]  --联合查询
    [where ...]  	-- 指定结果满足的条件
    [group by ...]  -- 指定结果按照哪几个字段来分组
    [having]    -- 过滤分组的记录必须满足的次要条件
    [order by ...]  -- 指定查询记录按一个或多个条件排序
    [limit {[offset,]row_count | row_countOFFSET offset}];
    
    

2.其他语法

  1. 操作符

    操作符含义范围结果
    =相等5=6false
    <>或!=不等于5<>6true
    >大于5>6false
    <小于5<6true
    <=小于等于5<=6true
    >=大于等于5>=6false
    BETWEEN … AND …在某个范围内,闭合区间[2,5]true
    AND相当于 &&5>1 and1>2false
    OR相当于 ||5>1 or 1>2true
  2. 运算符

    运算符语法描述
    is nulla is null如果操作符null,则为真
    is not nulla is not null如果操作符为 not null ,则为真
    betweena between b and c若a在b和c之间,则为真
    likea like b%(代表0到任意个字符) ,_(代表一个字符)
    ina in(a2,a3,a4…)假设a在a2,a3…其中的某一个值中,则结果为真
  3. where

    SELECT * FROM `user` where 'id' BETWEEN 1 AND 3 AND 'name' != 'a';
    SELECT * FROM `user` where 'name' like '%a_' AND 'id' in (1,2,3);
    SELECT * FROM `user` where 'name' IS NOT NULL OR 1 = 1;
    
  4. join
    分为三种操作:
    - left join
    - right join
    - inner join

    每种操作都可以用where限制查询条件
    在这里插入图片描述

    -- 嵌套查询
    SELECT s.`studentno`, `studentname`
    FROM `student` s
             INNER JOIN `result` r
                        ON s.`studentno` = r.`studentno`
             INNER JOIN `subject` sub
                        ON r.`subjectno` = sub.`subjectno`
    WHERE `SubjectName` = 'a'
      AND `studentresult` > 80
    ORDER BY `studentresult`
            DESC;
            
    -- 子查询
    SELECT s.`studentno`, `studentname`
    FROM `student` s
             INNER JOIN `result` r
                        ON s.`studentno` = r.`studentno`
    WHERE `studentresult` > 80
      AND `subjectno` = (
        SELECT `subjectno`
        FROM `subject`
        WHERE `SubjectName` = 'a')
    ORDER BY `studentresult` DESC;
    
  5. order by

    -- 升序ASC(默认),降序DESC
    SELECT * FROM `user`  where 'id' BETWEEN 1 AND 5 ORDER BY 'id' DESC;
    
  6. limit

    -- limit(查询的起始下标,pageSize)
    SELECT * FROM `user`  where 'id' IS NOT NULL limit 0,2;
    
  7. group by

    SELECT * from user GROUP BY 'name';
    

3.函数

  1. 常用函数
    大概了解一下就可以,不常用
    -- 数学运算
    SELECT ABS(-8) -- 绝对值
    SELECT CEILING(6.6) -- 向上取整
    SELECT FLOOR(6.6) -- 向下取整
    SELECT RAND()  -- 返回一个0~1的随机数
    SELECT SIGN(10) -- 判断一个数的符号 0-0 负数返回-1  正数返回1
    -- 字符串函数
    SELECT CHAR_LENGTH('length') -- 字符串长度
    SELECT CONCAT('con','cat')  -- 拼接字符串
    SELECT INSERT() -- 从某个位置开始替换某个长度
    SELECT LOWER() -- 转小写
    SELECT UPPER() -- 转大写
    SELECT INSTR() -- 返回字符第一次出现的索引
    SELECT REPLACE() -- 替换出现的指定字符
    SELECT SUBSTR() -- 返回指定的字符串(原字符串、截取的位置、截取的长度)
    SELECT REVERSE() -- 反转字符串-- 时间和日期函数(记住)
    SELECT CURRENT_DATE() -- 获取当前日期
    SELECT CURDATE() -- 获取当前日期
    SELECT NOW()  -- 获取当前时间
    SELECT LOCALTIME() -- 本地时间
    SELECT SYSDATE() -- 系统时间
    SELECT YEAR(NOW) -- 获取当前日期的年份
    SELECT SYSTEM_USER()  -- 获取当前用户
    SELECT USER()SELECT VERSION()
    
  2. 聚合函数
    SELECT COUNT(studentname) FROM student; -- count(指定字段),会忽略null值
    SELECT COUNT(*) FROM student; -- 不会忽略null值
    SELECT COUNT(1) FROM result; -- 不会忽略null值
    SELECT SUM(`studentresult`) AS 总和 FROM `result`
    SELECT AVG(`studentresult`) AS 平均分 FROM `result`
    SELECT MAX(`studentresult`) AS 最高分 FROM `result`
    SELECT MIN(`studentresult`) AS 最低分 FROM `result`
    

四、事务

将一组SQL放在一个批次中去执行,这些语句要么都成功,要么都失败
原则:
1. 原子性(atomicity):要么都成功,要么都失败
2. 一致性(consistency):事物前后得数据完整性要保证一致
3. 持久性(durability):事物一旦提交则不可逆,被持久化到数据库中
4. 隔离性(isolation):事物得隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干预,事务之间要相互隔离

五、三大范式

  1. 第一范式(1NF)
    原子性:保证每一列不可再分
  2. 第二范式(2NF)
    前提:满足第一范式
    确保数据库中的每一列都和所有主键相关,而不能只与某一部分主键相关
  3. 第三范式(3NF)
    前提:满足第一范式和第二范式
    确保数据表中的每一列数据都和主键之间相关,而不能间接相关

根据阿里规范:关联查询的表不得超过三张表
考虑商业化的需求和目标,数据库的性能更加重要,我们有时会故意在表中增加一些冗余的字段来提高性能

六、JDBC

1.概念

早期由于有多个数据库厂家,而每个厂家的语法不同,对程序员造成了很大困扰。SUN 公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库的)规范,俗称JDBC。各大数据库厂家只需要实现这个规范就可以了,而程序员只需要学习JDBC语法即可实现对所有数据库的操作。
在这里插入图片描述

2.第一个JDBC

  1. 创建一个maven项目
  2. pom.xml导入相关配置,这里只给出jdbc驱动配置
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>JDBC_01</artifactId>
        <version>1.0-SNAPSHOT</version>
    
         <dependencies>
             <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
                 <version>8.0.25</version>
             </dependency>
         </dependencies>
    
    
        <properties>
            <maven.compiler.source>16</maven.compiler.source>
            <maven.compiler.target>16</maven.compiler.target>
        </properties>
    
    </project>
    
  3. 在resources下创建db.properties,作为连接数据库的资源文件(便于后期修改)
    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    user=root
    password=****
    
  4. 创建JDBC工具类,方便连接数据库
    package Utils;
    
    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;
    
    @SuppressWarnings("all")
    public class JDBCutil {
        private static String driver;
        private static String url;
        private static String user;
        private static String password;
    
        static {
            try {
                //1.新建属性集对象
                Properties properties = new Properties();
                //2.通过反射,新建字符输入流,读取db.properties文件
                InputStream input = JDBCutil.class.getClassLoader().getResourceAsStream("db.properties");
                //3.将输入流中读取到的属性,加载到properties属性集对象中
                properties.load(input);
                //4.根据键,获取properties中对应的值
                driver = properties.getProperty("driver");
                url = properties.getProperty("url");
                user = properties.getProperty("user");
                password = properties.getProperty("password");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        //获取连接
        public static Connection getConnection() {
            try {
                //注册数据库的驱动
                Class.forName(driver);
                //获取数据库连接
                Connection connection = DriverManager.getConnection(url, user, password);
                //返回数据库连接
                return connection;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        //关闭连接,释放资源
        public static void release(ResultSet rs, Statement st, Connection conn) {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
    
  5. 创建测试类
    package test;
    
    import Utils.JDBCutil;
    
    import java.sql.*;
    import java.util.stream.StreamSupport;
    
    public class jdbc01 {
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            test01("1", "1");
        }
    
        public static void test01(String username, String pwd) {
            //获取数据库连接
            Connection connection = null;
            //执行SQL的对象 SQL注入问题 下面会讲
            PreparedStatement statement = null;
            //结果集对象
            ResultSet resultSet = null;
    
            try {
                connection = JDBCutil.getConnection();
                //拼接成SQL语句
                String sql = "select * from mybatis.user where 'id'= ?";
                statement = connection.prepareStatement(sql);
                statement.setInt(1, 1);
    
                //增删改 返回受影响行数
                //int i = statement.executeUpdate();
    
                //查询 返回结果集对象
                //resultSet = statement.executeQuery();
    
                //结果集对象的方法及使用
                //resultSet.getString();
                //resultSet.getObject();
                //resultSet.getInt();
                //resultSet.next();//下一个数据 遍历
                //while (resultSet.next()) {
                //    System.out.println(resultSet.getInt("id"));
                //}
    
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                //关闭jdbc连接
                JDBCutil.release(resultSet, statement, connection);
            }
        }
    }
    
  6. 整个项目结构大概就是这样
    在这里插入图片描述

3.SQL注入

SQL注入攻击是指恶意拼接SQL作为参数,传递给Web服务器,进而传给数据库服务器以执行数据库命令,获取数据库的信息以及提权。
举例:

SELECT * FROM user WHERE name = '" + name + "' AND psw = '"  + psw + "';
String name = "' or '1=1"
String psw = "' or '1=1"

拼接成

SELECT * FROM user WHERE `name` = '' or '1=1' AND `psw` = '' or '1=1'

此SQL语句相当于SELECT * FROM user,即不需要name和psw,通过SQL注入查出了所有用户

我们使用PreparedStatement,也就是这个原因
我们先写出SQL语句,使用?占位符作为参数 ,PreparedStatement会执行预编译,然后我们再去补参数,这样就可以有效的防止SQL注入问题

4.处理事务

public static void main(String[] args) {
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;
    try {
        connection = JdbcUtils.getConnection();

        //关闭数据库的自动提交事务,自动会开启事务
        connection.setAutoCommit(false);
        String sql1 = "UPDATE account SET money=money-500 WHERE NAME = 'A'";
        statement = connection.prepareStatement(sql1);
        statement.executeUpdate();
        String sql2 = "UPDATE account SET money=money+500 WHERE NAME = 'B'";
        statement = connection.prepareStatement(sql2);
        statement.executeUpdate();

        //业务完毕,提交事务
        connection.commit();
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }
    try {
        connection.rollback();
        //失败,自动回滚事务
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    } finally {
        JdbcUtils.release(resultSet, statement, connection);
    }
}

总结

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值