主线2:SQL & MySQL

184 阅读16分钟

MySQL

1.MySQL基础

    (1).登录MySQL:(两种方法)

        ①在DOS命令中,==mysql -u+用户名 -p+密码;==(加号相当于紧挨着无空格)         ②在DOS命令中,==mysql -u+用户名 -p----->回车----->输入密码==(可隐藏密码)

    (2).修改密码:(两种方法)

        ①在DOS命令中,进入mysql>界面后,输入以下指令:==set password for 用户名@localhost=password('新密码在此处');==         ②在DOS命令中,输入==mysql -u+用户名 -p+旧密码 password 新密码==

    (3).退出mysql:

输入:==exit==或者==quit==或者 ==\q==

    (4).mysql的卸载:(易遗漏)

        ①Windows10系统中,打开==文件==点击==选项==进入==文件夹选项==,进入==查看==的==高级设置==中找到==显示隐藏文件、文件夹及驱动器==,选中;         ②点开mysql安装包卸载;         ③进入安装目录卸载==MySQL==目录;         ④进入==C盘==中隐藏的==ProgramData==目录找到MySQL,删除即可。 Tips:②、③、④三步缺一不可,走完三步走才算作删除干净。

2.SQL语言

(1)概念:

    结构化查询语言,属于高级语言,同为先编译后运行。

(2)编译与执行操作:

    DBMS(执行)-->SQL(操作)-->DB。

(3)数据库的组成:

    ①==表(table)==是数据库的基本组成单元;     ②在表中,行叫 作==数据==,列叫作==字段==;     ③在表中,每个字段都有相应的==字段名和数据类型等==。

(4)分类:

    ①==DQL==(DateQueryL):数据查询语言,例:select......;     ②==DDL==(DataDefinition):数据定义语言,例:create,drop,alter...(对表结构的增删改);     ③==DML==(DataManipulation):数据操作语言,例:insert,delete,update...(对表中数据的增删改);     ④==TCL==(TransactionalControl):事务控制语言,例:commit(提交事务)...     ⑤==DCL==(DataControl):数据控制语言,例:grant(授权),revoke(撤权)...;

(5)常用命令:(+处加空格)

    ①查看当前数据库:select database();     ②查看mysql版本号:select version();     ③结束一条语句:==\c==;     ④查看创建表的语句:show create table+表名。

(6)导入数据的语句:(+处加空格)

    ①登录Mysql;     ②查看全部数据库:==show databases;==     ③创建数据库:==create database+数据库名;==     ④使用数据库:==use+数据库名;==     ⑤查看数据库中的表:==show tables;==     ⑥初始化数据:==source+绝对路径\数据库名.sql;==     ⑦查看表中的结构:==desc+表名;(describe)==     ⑧查看表中的数据:==select * from+表名;==     ⑨删除数据库:==drop database+数据库名;==

(7)查询语句(DQL语句):

<1>.简单查询:

①简单查询语法格式:

    ==select+字段名1,字段名2,...+from+表名;==

②字段重命名:

select         字段名1 (as)+重命名,字段名2 (as)+重命名 from         表名

③查询所有数据:

    select * from+表名; Tips:使用*的缺点有:    ①效率低;②可读性差。

④查询结果的去重:

select         distinct+字段名 from         表名;

Tips:distinct关键字只能出现在字段最前面。

<2>.条件查询:

①条件查询语法格式:

select         字段1,字段2... from         表名 where         条件;

Tips:执行顺序from--->where--->select。

②查询介于两数之间的表达:

...... (例如,查xxx字段在1100-3000之间的数据) where         xxx>=1100 and xxx<=3000; 或者⬇ where         xxx between 1100 and 3000;

Tips:between ... and ...语句前后都为闭区间。

③某字段的定点查询or/in:

...... (例如,查xxx字段等于‘A’或者等于'B'的数据) where         xxx ='A' or xxx ='B'; 或者⬇ where         xxx in ('A','B');

Tips:==and==的优先级大于==or==;         ==in==前可加==not==表示否定。

④模糊查询like:

... (例如,查xxx字段以‘a’开头的数据) where         xxx like 'a%'

Tips:'%'代表任意多个字符,'_'代表任意一个字符。

⑤排序order by:

... (例如对xxx字段进行排序) order by         字段名 by+(asc/desc);

Tips:默认升序排列;         by后面的==asc==代表升序,==desc==代表降序。         当同时对多个字段进行排序时,前字段相同时才会比较后字段。

<3>.分组查询:

①定义:

        按照某个或某些字段进行分组;

②语法格式:

==select+分组函数 from+表名 (where+条件) group by+字段xxx having+条件。==

③group by与having:

        A.有分组参与的查询各语句执行顺序: ==from找表->where初过滤->group by分组->having过滤->select查找->order by排序==         B.一条语句中有group by 时,select后仅能跟==分组函数==或==参与分组的字段==;         C.调用avg(xxx)函数时,不能使用where,会改变平均值,使用having;         D.where后不能跟分组函数但having后可以。(执行顺序推论)

④分组函数:

        A.count(字段xxx);        //对字段进行==计数==(忽略null);         B.sum(字段xxx);        //对字段数据==求和==(忽略null);         C.max(字段xxx);        //求字段的==最大值==;         D.min(字段xxx);        //求字段的==最小值==;         E.avg(字段xxx);        //求字段的==平均值==;

⑤单行处理函数:

        A.ifnull(字段xxx,0);        //若xxx字段为NULL时,被当作0处理;         B.count(*);                     //统计总记录条数

<4>.连接查询:

①笛卡尔积现象:

两张表连接查询时,无条件限制,查询结果条数是两表条数乘积;

Tips:笛卡尔积现象使查询效率降低,where后设置筛选条件可避免该现象;

②表的别名法连接查询:

select         表别名1.字段名1,表别名2.字段名2... from         表名1 表别名1,表名2 表别名2;

Tips:起别名的方法提高了程序执行效率且可读性高。

③内连接:
A.等值连接:条件1是等值关系;

语法格式:

select         字段1,字段2... from         表名1 (innner) join         表名2 on         条件1 where         条件2;

B.非等值连接:条件是不等值关系;

语法格式:

与等值连接相似,条件on处使用非等值语句即可,比如between...and...等;

C.自连接:一张表看作两张,我连我自己;

同分为等值与非等值连接;

实例:员工的领导表和领导的员工表。

select        //一样的表的不同别名         e.name,m.name from        //连接员工表e与m         employee e join         employee m on        //设置条件e表的领导编号等于m表的员工编号         e.managerNo = m.employeeNo;

④外连接:
A.左连接:左边的表是主表;

语法格式:

select         字段 from         表名1 left (outer) join         表名2 on         条件;

B.右连接:右边的表是主表;

语法格式:

与左连接语法格式相似,将left关键字改为right即可。

⑤外内连接的区别:

        ①内连接两表平等,无主副之分;         ②外连接分主副表,主要查询主表数据,若副表无与之匹配的数据,自动模拟为NULL;         ③主表的数据无条件全部查出。(比如,领导King的领导名被模拟为NULL)

⑥全连接:左右两表均为主表;

<5>.三张表连接进行查询:

语法规则:

select         字段1,字段2,... from         表名1 (left/right) join         表名2 on         条件 (left/right) join         表名3 on         条件;

<6>.子查询:select语句嵌套,内部的select;

例如:

select         employeeName,salary from         employee where         salary>(select min(salary) from employee);

Tips:a.从内而外一层一层看,将子查询结果当作一张临时表。         b.子查询嵌套的select只能返回一条,多于一条会报错。

<7>.union关键字:连接两条查询语句

例如:

select         employeeName,job from         employee where         job = 'manager' or job = 'salesman';

可用union关键字改写为:

select         employeeName,job from         employee where         job = 'manager' ==union== select         employeeName,job from         employee where         job = 'salesman';

Tips:         a.union有着连接两条查询语句的作用,效率更高,克服笛卡尔积现象;         b.union使用时必须保证两个结果列数相同

<8>.limit关键字:取出一部分结果

语法格式:

limit         //startIndex是起始下标,length是长度;         startIndex,length; ②limit        //numble是取前n个查询结果;         numble;

Tips:limit在“order by”之后执行。

<9>.关于查询语句关键字执行顺序汇总:

语法规则:

select         字段名,... from         表名 where         条件 group by         字段名 having         条件 order by         字段名 (asc/desc) limit         过滤参数

执行顺序:

from找表-> where初筛-> group by分组-> having细筛-> select查找-> order by排序-> limit过滤。

(8)表的相关语句:

<1>.MySQL中的数据类型:

①字符串类:

varchar(10) 动态分配存储空间,节省空间;(姓名字段) char(10) 定长字符串,分配速度快;(性别字段)

最长可储存255位。

②整型数类:

int 常规整型类,等同于java中的int; bigint 长整型,等同于java中的long;

最长可储存11位。

③浮点型类:

float 常规浮点型,等同于java中的float; double 长浮点型,等同于java中的double;

④日期类:

date 短日期类型,存储年月日信息; datetime 长日期类型,存储年月日时分秒信息;

<2>.表的创建(DDL语句):

语法格式:

create table 表名(字段名 数据类型(default 'm'),字段名 数据类型,... );

Tips:①表名的命名规范:以t_或者tbl_开始,比如t_students;         ②default 'm'作用为指定字段默认值为'm'。

<3>.表的删除:

语法格式:

①drop table 表名; 表不存在时会报错; ②drop table if exists 表名; 不会报错。

<4>.表中数据插入(DML语句):

①常规插入语法格式:

insert into 表名(字段名1,字段名2,...) values(值1,值2,...),(值1,值2,...),...;

Tips:         A.insert语句一旦执行,必然多一条记录,未赋值元素为NULL;         B.字段名在传入所有值情况下字段名可省略。

②日期的插入:
A.MySQL中的日期格式:

%Y        %m        %d        %h        %i        %s 年            月          日          时        分        秒 date默认格式:        %Y-%m-%d; datetime默认格式:        %Y-%m-%d-%h-%i-%s;

B.字符串日期转换为日期类型函数:

str_to_date('字符串日期','日期格式'); //将字符串日期varchar类型转换为date类型;

Tips:当字符串为‘%Y-%m-%d’格式时,自动转换为date类型;

C.日期格式化函数:

date_format(日期类型数据,'日期格式'); //将日期格式转换为所需类型的字符串。

D.获取当前时间函数:

now(); //获得到当前时间的datetime类型数据。

<5>.表中数据修改(DML语句):

语法格式:

update 表名 set 字段名1=值1,字段名2=值2,...where 条件; //必须加where后的条件,否则会修改字段所有行。

<6>.表中数据删除:

①delete删除语法格式:(DML语句)

delete from 表名 where 条件; //切记加where后条件,否则会全部删除。 数据被删除,但存储空间不会被释放; 删除效率较低,但是可回滚

②truncate删除语法格式:(DDL语句)

truncate table 表名; 完全删除,删除效率高,但数据不可回滚。

<7>.表的复制:

①全部复制语法格式:

create table 新表名 as select * from 拷贝表名; //将拷贝表名中的所有数据拷贝到新表中。

②部分复制语法格式:

create table 新表名 as select 字段名1,字段名2,... from 拷贝表名 where 条件; //将拷贝表面的满足条件的某字段数据复制到新表中。

JDBC——Java语言连接数据库

1.所属类库与配置工作

类库:

所属于(java.sql.*)包下,该包下都是JDBC的接口。

准备工作:

①找到mysql-connector-java-bin.jar(mysql的驱动); ②配置环境变量:classpath = .;(jar包的绝对路径)。 注:“.”表示当前路径。

JDBC特点:

①降低程序耦合度,提高文件扩展力; ②面向接口编程。

2.JDBC的编程六步

(1).注册驱动(需要抛出SQLException异常)

方法1:

java.sql.Driver driver = new com.mysql.jdbc.Driver();
DraverManager.registerDriver(driver);

方法2:(常用)

//利用反射原理,Class类中的forName(完整包名)方法调用会使Driver类中的静态代码块执行(类加载)
Class forName("com.mysql.jdbc.Driver");
//此处需要处理Exception异常。

(2).获取数据库连接

方法1:手动赋值url,user和password参数

//url包括“协议+IP地址+port端口号+资源名”
String url = "jdbc:mysql://localhost:3306/(数据库名)";
String user = "(mysql用户名)";
String password = "(mysql登录密码)";

//获取数据库连接操作
Connection conn = DriverManager.getConnection(url,user,password);

方法2:资源绑定器控制属性文件: <1>.书写一个属性配置文件(XXX.properties):

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/(数据库名)
user = (mysql用户名)
password = (mysql登陆密码)

<2>.在java程序中使用资源绑定器绑定属性配置文件:

//资源绑定器
ResourceBundle bundle = ResourceBundle.getBundle("(从src下的目录路径(不带后缀))");
String driver = bundle.getString("driver");
String url = bundle.getString("url");
String user = bundle.getString("user");
String password = bundle.getString("password");

//获取数据库连接操作
Connection conn = DriverManager.getConnection(url,user,password);

(3).获取数据库操作对象

情况1:需进行字符串拼接,但会发生SQL注入

Statement stmt = conn.createStatement();

SQL注入现象:

①在登录界面随意输入账号密码,登录成功; ②原因:输入的用户名与密码中有SQL关键字,其与原SQL语句发生字符串拼接而导致参与了SQL语句的编译,导致SQL语句被扭曲; ③本质是该种方式先进行字符串拼接,再编译SQL语句。 例如:密码输入('djalksd' or 'a'='a),登陆成功。

情况2:有效防止了SQL注入,但无法进行字符串的拼接

//原用户名与密码处用“?”代替
String sql = "(SQL语句)";
preparedStatement ps = conn.preparedStatement(sql);
//给预编译的“?”处传值(JDBC中下标均是从1开始的)
ps.setString(int index,String value);
//同理也可以使用ps.setDatatype(int index,datatype value);

(4).执行SQL语句

!!!注:当(3)步骤使用了情况2时,该步骤无需传入sql语句。以下采用(3)步骤中情况1的情况。!!! 情况1:执行增删改操作

String sql = "(SQL语句)";
//返回的count是被改动的条数
//该sql语句只能传入增删改操作语句
int count = stmt.executeUpdate(sql);

情况2:执行查询操作

String sql = "(SQL语句)";
//返回的rs是结果集,用于后续处理
//该sql语句只能传入查询操作语句
ResultSet rs = stmt.executeQuery(sql);

(5).处理查询结果集

相关方法简介:

(boolean) rs.next();
>//将数据库的光标初始化在表头,该方法使光标向下一位
>//若数据库光标位置存在数据,则返回true。
(String) rs.getString(int index);
>//取当前行的第index个数据
>//同理还有rs.getDatatype(int index);
(datatype) getDatatype(String name);
>//根据查询结果的列名纵向取值。

(6).释放资源(放入try...catch...语块的finally)

	finally{
     		 //释放资源
      		if (rs != null) {
           		try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }

3.JDBC的事务(transaction)

//手动开启或关闭事务(获取数据库连接后)
//isOpen为true时,说明开启了自动提交事务
conn.setAutoCommit(boolean isOpen);
//手动事务提交(放在处理结果集后)
conn.commit();
//手动事务回滚(放在catch语块中)
//由于如果程序执行失败会进入catch语块,回滚不至于数据丢失
if(conn!=null){
	conn.rollback();
}

4.JDBC工具类的书写

代码:

import java.sql.*;
import java.util.ResourceBundle;

//JDBC的工具类
public class DBUtils {

    //添加一个私有的构造方法,防止new对象。
    private DBUtils(){}

    //类加载时加载属性资源文件
    public static ResourceBundle bundle = ResourceBundle.getBundle("Resource/login");

    //注册驱动(写入静态代码块中,仅在类加载时执行一次)
    static{
        try {
            Class.forName(bundle.getString("driver"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获得数据库连接
    public static Connection getConnection() throws SQLException {
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password = bundle.getString("password");
        Connection conn = DriverManager.getConnection(url,user,password);
        return conn;
    }

    //释放资源
    public static void closeAll(Connection conn, Statement stmt, ResultSet rs){
        if (rs != null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    //释放资源方法重载
    public static void closeAll(Connection conn,Statement stmt){
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}