SQL笔记

  • 数据库(DB)

1.是什么:

存储数据,管理数据的仓库。

结构:(库名)数据库—(表名)表—(内容)数据

2.常见的数据库分为:

关系型数据库: Oracle、MySQL、MariaDB(与MySQL同一作者,使用数据库引擎不同) 、SQLServer、Access

非关系型数据库: MongoDB、Redis、Solr、ElasticSearch、Hive、HBase(分布式使用较广)

3.sql语言:

3.1概念:

结构化查询语言(Structured Query Language)简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统

是高级的非过程化编程语言,允许用户在高层数据结构上工作。

Sql语言文件扩展名为.Sql

3.2分类

DML(Data Manipulation Language)数据操纵语言

如:insert,delete,update,select(插入、删除、修改、检索)简称CRUD操新增Create、查询Retrieve、修改Update、删除Delete

DDL(Data Definition Language)数据库定义语言

如:create table之类

DCL(Data Control Language)数据库控制语言

如:grant、deny、revoke等,只有管理员才有相应的权限

DQL(Data Query Language)数据库查询语言

如: select 语法

注意:SQL不区分大小写

3.3 常用操作:

          3.3.1对库操作:

                  建库:create database cgb2022 DEFAULT CHARACTER SET utf8;

                  删库:drop database cgb2022;

        查看所有数据库:show databases;

修改数据库字符类型为utf8:  alter database cgb21080  character set utf8; 

          如果出现中文出错,临时改当前窗口(本次连接)为中文:set names gbk;

             3.3.2对表操作:

查看某个库表:先进入使用数据库use 库名;

展示使用的库的所有表:show tables;

创建表:create table student(字段名 varchar (10 ),字段名 int(10));

查看某个表数据结构:desc 表名;

删除表:drop table 表名;

添加列:alter table 表名 add column 列名 字符类型(10);

3.3.2对数据操作:

查询某表下的所有数据:select*from 表名;

给表添加数据:insert into 表名 values(各列对应的数据,有几列写几列);

给表特定列添加数据:insert into 表名(列1,列2)values(列1数,列2数);

修改数据:update 表名 set 要修改的字段=新数据 where 判断的字段=1;

删除整行数据:Delete from表名where 要删除数据的字段=要删除的数and隔开;

3.3.3 drop、delete和truncate之间的区别

drop删除库或者表,数据和结构定义

delete和truncate只是删除表的数据

delete可以指定where条件,删除满足条件的记录,tuncate删除所有记录

对于自增字段的表,delete不会自增值清零,而truncate是把表记录和定义都删除了,然后重建表的定义,所以自增主键会重头开始计数

3.4数据类型

3.4.1命名规则

字段名必须以字母开头,尽量不要使用拼音

长度不能超过30个字符(不同数据库,不同版本会有不同)

不能使用SQL的保留字,如where,order,group

只能使用如下字符az、AZ、0~9、$ 等

Oracle习惯全大写:USER_NAME,mysql习惯全小写:user_name

多个单词用下划线隔开,而非java语言的驼峰规则

3.4.2字符

char长度固定,不足使用空格填充,最多容纳2000个字符,char(11)存储abc,占11位。查询速度极快但浪费空间

varchar变长字符串,最多容纳4000个字符,varchar(11)存储abc,只占3位。查询稍慢,但节省空间。Oracle为varchar2

大文本: 大量文字(不推荐使用,尽量使用varchar替代)

以utf8编码计算的话,一个汉字在u8下占3个字节

注:不同数据库版本长度限制可能会有不同

3.4.3数字

tinyint,int整数类型(int类型限制不住长度,所以也没必要设置)

float,double小数类型(double不能设置具体长度)

numeric(5,2) decimal(5,2)—也可以表示小数,表示总共5位,其中可以有两位小数

decimal和numeric表示精确的整数数字

3.4.4日期

date 包含年月日

time时分秒

datetime包含年月日和时分秒

timestamp时间戳,不是日期,而是从1970年1月1日到指定日期的毫秒数

3.4.5图片

blob 二进制数据,可以存放图片、声音,容量4g。早期有这样的设计。但其缺点非常明显,数据库庞大,备份缓慢,这些内容去备份多份价值不大。同时数据库迁移时过大,迁移时间过久。所以目前主流都不会直接存储这样的数据,而只存储其访问路径,文件则存放在磁盘上。

4.mysql: 我们使用的MariaDB是其孪生兄弟引擎不同 

4.1服务器端:保存数据,它来处理具体数据维护,保存磁盘

         Mysql server :数据存在Mysql server 的my.ini配置文件中

4.2客户端:操作数据,CRUD新增,修改,删除,查询

        操作方法一(DOS命令):

              第一种进入DOS方法:打开MariaDB软件下的Mysql Client 然后输入密码

              第二种进入DOS方法:打开CMD,输入mysql -u用户名(-uroot) -p密码(-proot)

        操作方法二(可视化工具):

                  SQLyog工具

5.SQLyog工具:管理数据库的可视化工具

5.1创建库

     1.空白位置右键或ctrl+d

     2.命名同时选择字符集 (DOS中的create database DEFAULT CHARACTER SET utf8;

5.2创建表

     1.对应库的表右键创建表。

     2.填入前三列(列名,数据类型,长度)然后填入表名即可:类似于DOS中的create table 表名(字段名 varchar (长度),字段名 int); 

5.3 插入数据记录

     在表中相应位置双击即可键入。

 

注意:

存在多条sql语句时,如果存在分号;则所有语句都要用分号隔开,否则不执行,或者所有语句都不使用分号,执行单行语句时需要选取整行然后执行,或者使用分号与上下语句分开则不用选取整行。

     

6.字段约束

6.1主键约束:primary key

         如果为一个列的字段添加了主键约束,那么这个列就是主键,主键的特点是值唯一且不能为空。通常情况下,每张表都会有主键。

   例1:将id设置为主键:

      创建一张表a时create table a( id int primary key );//声明字段id为主键约束:

      此时字段id列记录数据时数据不能为null且值必须唯一。

   例2:将id设置为主键,且进行主键自增(只有主键可以加自增自减)。

      创建一张表b时create table b( id int primary key auto_increment );

      INSERT INT  b  VALUE( 8 ); //id不可以为null

例3:给已存在的列添加主键自增

alter table 表名 modify 列名 int  auto_increment;

      录入数据时id值不需要再手动键入,初始值为1,当需要id值,数据库负责从AUTO_INCREMENT获取一个id值,作为主键值插入到表中,而且每次用完AUTO_INCREMENT值,都会自增1,即使前面的值删除,后面再键入时会按上一次自增后最大值继续自增(Oracle数据库中可以设置自增多少从何处自增,sql中不可以,因为系统已经设置好了)。

6.2非空约束:NOT NULL

   如果为一个列添加了非空约束,那么这个列的值就不能为空,但可以重复。

    例1:将id设置为主键自增,pwd 设置为非空约束:

    CREATE TABLE c(

  id INT PRIMARY KEY AUTO_INCREMENT,

  pwd VARCHAR(10) NOT NULL);

     执行INSERT INT  c  VALUE(NULL,’7’ ); // id可以为null,pwd不可以为null但可重复

6.3唯一约束:unique

        如果为一个列添加了唯一约束,那么这个列的值就必须是唯一的(即不能重复),但可以为空。

create table d(

id int primary key auto_increment,

username varchar(50) unique);

执行INSERT INTO d VALUES(NULL,'8');// id可以为null, username可以为null,但不可以重复

6.4 默认约束:default

       给字段使用default添加默认值。

    create table e(

id int primary key auto_increment,

sex varchar(10) default "男" //添加性别列默认值为“男”。

);

6.5检查约束:check

   给字段使用check添加合法性的检查。

create table f(

id int primary key auto_increment,

age int,

check (age<100) //设置age字段的检查依据。不符合要求就报错。

);

6.6 外键约束foreign key

通过两个表的主键描述两个表的关系,子表主键不可设置自增。

约束内容

1.子表主键的值需要取自主表(被包含于主表),添加的子表主键的值如果在主表中不存在则会报错。

2.主表删除主键数据时,对应的子表主键不存在,如果子表有对应的主键则会报错。

  (1)创建主表

   create table tb_user(

id int primary key auto_increment,

name varchar(20),

password varchar(20)

);

  (2)创建子表

create table user_id_addr(

user_id int primary key ,

address varchar(100),

foreign key(user_id) references tb_user(id)

//添加外键约束格式:foreign key(本表主键名) references 对方表名(对方表主键)

);

7.基础函数

   类似于java中的方法,也有()作为标记,主要也是用来提高SQL的效率,有的也要传递参数。

lower :select 列字段, lower (列字段或'指定内容') X from 表名; //数据转小写,()中为指定列字段或”指定内容”,输出后指定内容为小写。from前的X为给临时列字段命名为X。同理以下函数都可以。

upper : select列字段, upper (列字段或'指定内容') from表名; //数据转大写,()中为指定列字段或”指定内容”, 输出后指定内容为大写。

Length: select ename,LENGTH(ename),job,LENGTH(job) FROM 表名;//查询指定列各数据的长度,utf-8中每个汉字长度为3.

Substr:select ename,SUBSTR(ename,2,3) FROM表名; //从第2个字符开始截取3个字符。

       select ename,SUBSTR(ename, 3) FROM表名; //从第3个字符开始截取剩下字符。

Concat:select ename,CONCAT(ename,123,"ABC") FROM表名;//拼接123和ABC,除了数字都需要加双引号。

Replace: select ename,replace(ename,'a','666') FROM表名;//替换ename列中a元素为666。

Ifnull:select IFNULL(comm,10) comm FROM tb_emp;// 判断如果comm列有NULL值则赋值为10 。

round :select  ROUND(comm)  from  tb_emp;// comm列四舍五入只保留整数。

      select comm,ROUND(comm,1)  from  tb_emp;// comm列四舍五入保留一位小数。

ceil和floor: select comm,ceil(comm) ,floor(comm) from tb_emp//ceil向上取整保留整数,floor向下取整保留整数。

Now:select  now();//获取当前时间

select  YEAR(now());//获取当前时间的年

select  month(now());//获取当前时间的月

select  day(now());//获取当前时间的日

select  hour(now());//获取当前时间的时

select  minute(now());//获取当前时间的分

select  second(now());//获取当前时间的秒

select  curdate()//获取年月日

      select  curtime()//获取时秒分

转义字符:\

'A'BC': 单引号是一个SQL语句的特殊字符,一对单引号中需要用单引号时需要在单引号前加转义符号\('A\'BC'),但是如果在双引号中使用单引号则不用转(“A'BC”)。

8条件查询:

   distinct select  distinct  列字段名  from  表名;// 去除某列字段重复的数据

   where注意where判断里不能用别名,不能出现聚合函数。

select * from 表名where  数据判断条件  //查找某表指定条件的行数据。

select * from 表名 where empno =100;//在全部列数据中查找某表empno列数据为100的行的值。

          select * from 表名 where empno >100;//在全部列数据中查找某表empno数据大于100的行的值。

          select * from 表名 where 1=1;//在全部列数据中查找某表1=1(true)的行的值。

          select * from 表名 where empno>100 and job="员工"; //在全部列数据中查找某表empno列数据大于100,且job=员工的行的值。

          select * from表名where empno>100 or job="员工"; //在全部列数据中查找某表empno列数据大于100,或者job=员工的行的值。

          select * from表名where  sal  in(10,20,30); //在全部列数据中查找某表sal =10或者20或者30的行数据。

          select * from表名where  sal not  in(10,20,30); //在全部列数据中查找某表   sal不等于10或者20或者30的行数据。

   like (像): 通配符%代表0到n个字符,通配符下划线_代表1个字符

        select * from emp where ename like 'a%';  //以a开头的 (只有这种会让索引生效)

select * from emp where ename like '%a';  //以a结束的 (会让索引失效)

select * from emp where ename like '%a%'; //中间包含a的(会让索引失效)

select * from emp where ename like 'a_' ; //a后面有一个字符的(下划线_代表一个字符位置)

    null数据处理:

        使用 comm=null 无法查出含null值的数据行。

        要查找记录为null的数据需要使用comm is null;

要查找记录为非null的数据需要使用comm is not null;

   between...and:

         select*from 表名where sal between 100 and 900 ;//查找100<=sal <=900的值,且顺序不能反。 

 limit n,m: 限制从n+1条开始查询展示m条  ,limit放在判断条件where后面

      select * from emp limit 2;// --列出前两条

select * from emp limit 1,2;/ --从第1+1条开始,展示2条记录

select * from emp limit 0,3; /--从第0+1条开始,展示3条记录--前三条

order by:排序 , order by放在判断条件where后面

      select * from  emp order by sal //#默认升序 (sal 后面省略了ASC)

select * from  emp order by sal desc// #降序(使用desc)

字母是按a~z的先后顺序,日期是按数字大小排序,中文是按编码表文字对应的数字。

统计案例

入职统计:统计2019年以后入职的

select*from tb_emp where year(hiredate)<2019;

           select*from tb_emp where hiredate<2019-1-1;

年薪统计:(月薪+奖金)*13薪  如果源值有null 用ifnull(列,要换的值)

          select sal,comm,(sal)*13+ifnull(comm,0)*13 year from tb_emp; 

9聚合函数 aggregation:根据一列统计结果

    count():统计一列数据个数

           select count(sal) from tb_emp;//统计sal列数据个数, null值不被统计

           select count(*) from tb_emp;//统计各列数据行数(低效)null值也统计

           select count(1) from tb_emp;//统计各列数据行数(高效)null值也统计

max / min():统计最大值/最小值

select max(sal) from tb_emp;

select min(sal) from tb_emp;

select max(sal),min(sal)  from tb_emp;

sum / avg():统计一列数据总值/平均值

select sum(sal) from tb_emp;

select avg(sal) from tb_emp;

select sum(sal),avg(sal)  from tb_emp;

错误的查询方式:

select  sal ,  min(sal)  from tb_emp;  // sal为非聚合列,min()为聚合列,混合查询会报错,或不报错出现错误数据,所以要进行分组group

10.分组 group:

用于对查询的结果进行分组统计,group by表示分组, having 子句类似where过滤返回的结果

    group by:对数据分组

          select job ,avg(sal) from tb_emp group by job;//按job列不同类型分组统计,如果不使用group by job,则平均值默认是非聚合列第一个数据的类型。

      select deptno, count(1) from tb_emp group by deptno;//按deptno列分类统计行数。

select year(hiredate),count(1) from tb_emp group by year(hiredate);//按年统计员工数。

select deptno,max(sal) from tb_emp group by deptno;//按部门分组,统计最大值。

having:分组后过滤

       having和where后面都是判断条件,但是where是先判断过滤再统计,having是先统计再判断过滤,所以加在group by 后面 的是having。

    select deptno,max(sal) from tb_emp group by deptno having max(sal)>8000;

  尝试where和having互换:注意where判断里不能用别名,不能出现聚合函数。

       //select count(1 ) , year(hiredate) a from emp where count(1)>1 group by a having count(1 )>1; //因where后面不能出现聚合函数所以无法判断。

11 select语句各部分顺序:

书写顺序是固定的:select ... from [on Expr] [where Expr] [group by]  [having]  [order by]  [limit]

执行顺序:from ->             选择表

          ON->               链接条件

    <join_type> JOIN->          链接

where语句 ->       条件过滤

group by ->          分组

AGG_FUNC->         聚合

 having ->           分组过滤

 select *| ->         开始查找

distinct  column->    选择字段、去重

order by ->           排序

limit->;            分页

12.事务 transaction

12.1事务是什么:

      数据库事务(Database Transaction),是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。

      就是将一堆的SQL语句(通常是增删改操作)绑定在一起执行,要么都执行成功,要么都执行失败,即都执行成功才算成功,否则就会恢复到这堆SQL执行之前的状态。

12.2事务4个特性ACID   

12.2.1概述

      一般来说,事务必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、隔离性(Isolation,又称独立性)、持久性(Durability)。

      原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中如果发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

一致性:底层使用同步锁保证数据安全,在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作,多线程下数据一致

隔离性:底层使用同步锁保证数据安全,数据库允许多个并发事务同时对其数据进行读写和修改的能力,多线程同时执行互不干扰,但数据库每次只接受一个请求

持久性:事务处理(增删改)结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

12.2.2隔离级别:四个

      读未提交(Read uncommitted:安全性最差,可能发生并发数据问题,性能最好(解决幻读,幻读:在同一事务中,对同一张表的两次查询结果不一致。)

读提交(read committed: Oracle默认的隔离级别(预防脏读:在一个事务中读取到另外一个事务中未提交的结果。)

可重复读(repeatable read:MySQL默认的隔离级别,安全性较好,性能一般

                            (预防不可重复读,同一个事务中对同一数据的再次查询结果不一致)

串行化(Serializable: 表级锁,读写都加锁,效率低下,安全性高,不能并发(解决以上三种问题)

12.2.3mysql事物

       MySQL默认的隔离级别是可重复读(repeatable read)

       在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务,每一条SQL语句默认自带start transaction和commit。但如果需要在一个事务中包含多条SQL语句,那么需要手动输入开启事务start transaction和结束事务commit或rollback。

        开启事务:start transaction;

         在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起

点),然后可以去执行多条SQL语句

结束事务:commit(提交事务,完成数据库修改)或rollback(回滚事务,不修改)。

如果不输入结束事物语句,执行的语句在临时区不会对真正的数据库产生影响,如果输入commit结束事物语句,则会让临时区语句对真正的数据库产生影响,如果输入rollback结束语句则临时区的语句会撤销,也不会对真正的数据库产生影响,回到开启事物状态。

13.索引 index

13.1定义:

排好序的快速查找的数据结构,拥有特定查找算法,高效但是会单独生成一张表,额外独自占据大量内存空间

13.2分类:

    单值索引:一个索引只包括一列(一个字段),一个数据表可以有多个列被索引。

唯一索引:被索引的列需要受到唯一约束;主键会自动创建唯一索引。

复合索引:一个索引可以同时索引多列(多个字段),但使用时遵循最左原则

13.3 怎么用

      13.3.1 查询索引:

            show index from 表名;

            查询是否使用了索引:

explain select  job from tb_emp where job="员工" ;

      13.3.2 创建单值索引:

             create index 索引名 on 表名(被索引列)

      13.3.3 创建唯一索引:

             create unique index 索引名 on 表名(被索引列)

      13.3.4 创建复合索引:

             create index 复合索引名 on表名(被索引列1,被索引列2..);

            最左原则:使用索引,使用时如果不包含被索引列1,则复合索引失效。

      13.3.5 删除索引:

alter table 表名 drop index 索引名 ;

13.3.6添加索引:

alter table 表名 ADD index 索引名(字段)。//添加单值索引

alter table 表名 ADD FULLTEXT (字段); //添加全文索引

alter table 表名 ADD unique(字段); //添加唯一索引

13.4优缺点:

13.4.1优点:

1.索引是数据库优化

2.表的主键会默认自动创建索引

3.每个字段都可以被索引

4.大量降低数据库的IO磁盘读写成本,极大提高了检索速度

5.索引事先对数据进行了排序,大大提高了查询效率

13.4.2缺点:

1.索引本身也是一张表,该表保存了主键与索引字段,并指向实体表的记录,所以索引列也要占用空间

2.索引表中的内容,在业务表中都有,数据是重复的,空间是“浪费的”

3.虽然索引大大提高了查询的速度,但对数据的增、删、改的操作需要更新索引表信息,如果数据量非常巨大,更新效率就很慢,因为更新表时,MySQL不仅要保存数据,也要保存一下索引文件

4.随着业务的不断变化,之前建立的索引可能不能满足查询需求,需要消耗我们的时间去更新索引

14.视图:

        14.1 作用:缓存了sql的执行结果,以视图呈现

        14.2 创建视图:create view 视图名 as select*from 表名; 

        14.3 查看视图:左侧刷新后点击视图可查看视图表或者select*from 表名; 

        14.4 优点:简化查询sql(相同sql不必再写sql,直接查看视图就行)

                  视图可以被共享,视图屏蔽了真是业务表的复杂性。

             缺点:视图一旦创建,SQL无法被优化。

15.表关联 association

15.1概念

     表table代表了生活中一个主体,如部门表dept,员工表emp。表关联则代表了表之间的关系。

15.2多表联查 join:

多表查询是指基于两个和两个以上的表的查询。在实际应用中,查询单个表可能不能满足你的需求,如显示员工表emp中不只显示deptno,还要显示部门名称,而部门名称dname在dept表中。一对一,一对多,多对一,多对多。

  1. 笛卡尔积 Cartesian product

原理:

把多个表的数据都拼接起来,多表查询都是先生成笛卡尔积,再进行数据的筛选过滤。实际开发中尽量少用多表联查,其根本原因就是,查询过程中,先在内存中构建一个大大的结果集,然后再进行数据的过滤。那这个构建过程,和所使用的内存资源,包括过滤时的判断,都是既耗费资源,又浪费时间。

方法:

select * from 表1,表2 where 表1.字段a=表2.字段a ;//如果字段唯一可不用使用表.。

查询表1表2的内容,选取指定字段,列出选取的字段值相同的拼接在一起形成结果表,where后可使用and或者or增加多个过滤条件。

  1. 连接查询

原则:小表驱动大表,左边表一最好是小表。

内连接 inner join:结果取两表交集

    select *from 1 inner  join2  on tb_dept.`deptno`=tb_emp.`deptno`;//取两个表交集

左(外)连接 left join: 结果取左表所有,右表不满足的用null代替

select *from left  join2  on tb_dept.`deptno`=tb_emp.`deptno`;

右(外)连接 right join: 结果取右表所有,左表不满足的用null代替

select *from 1  right  join2  on tb_dept.`deptno`=tb_emp.`deptno`;

  1. 子查询 subquery

 子查询是指嵌入在其他select语句中的select语句,也叫嵌套查询。子查询执行效率低慎用。记录少时效率影响不大、图方便直接使用,记录多时最好使用其它方式替代。

16.数据库优化:

1.若需要经常查询就创建索引。

2.查看时使用视图。//视图数据完整保存源数据,屏蔽原表复杂性,具有公开性

3.录入数据时,内容尽量不使用中文。

4查看内容最好具体到字段,而不是使用*查询全部内容。

5.查看使用分页。

6.查看最好不要使用笛卡尔积进行多表联查而是连接查询。

7.插入多数据时最好使用一条语句。

17.DOS命令数据库备份与恢复

17.1备份

1.方法:在cmd窗口中未登录mysql状态下,运行mysqldump命令。

语法: mysqldump -uuName -pdbName > BackupPath

说明:

mysqldump: 备份命令

-uuName:用户名

-p:指密码,后不跟密码,回车后,cmd会提示输入密码。

dbName:要备份的数据库名。

>:重定向运算符,将左侧的文件内容copy到右侧文件

BackupPath

2.备份内容:

mysqldump 仅备份dbName中所有的表和表记录,但并不备份dbName本身。因此如果dbName本身也不存在时,恢复数据时,首先要建库,再恢复内容。

3.备份方法:

将数据库中表和表记录以sql语句的形式写到文件中。主要有删表、建表、插入记录语句等。

4.备份所有库:

语法:mysqldump -uuName -p --all-databases > BackupPath。

说明:并非所有mysql版本支持该语法。

与备份某一库的区别:备份所有库的文件中,会包含建库语句。

17.2恢复

1.方式一:在未登录mysql状态下的cmd窗口中,使用mysql命令。

语法:mysql -uuName -p dbName < BackupPath

说明:

mysql:恢复命令。

<:文件重定向,将右侧的文件内容copy到左侧文件。

2.方式二:在登录mysql状态下的cmd窗口下,使用source命令

语法:source BackupPath

3.恢复步骤:

第一步:创建库。

第二步:恢复库。

  • JDBC:JAVA与数据库连接规范

https://img-blog.csdnimg.cn/20210608211430203.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTI5MzI4NzY=,size_16,color_FFFFFF,t_70

1.概述

  概念:完成JAVA和数据库连接的技术

  使用步骤:1.导入jar包。//JDBC提供的丰富的工具类

            2.提供链接数据库的参数(用户名root,密码自定,端口号3306)

    3.在JAVA程序中发起SQL语句操作数据库。

    4.如果数据库右查到结果,返回到程序。

  如何导入jar包:1.复制jar包到java内工作空间

                 2.java内右键jar包点击add.as.libery(能点开下级文件就是成功了)

2. 使用数据库步骤

2.1 .注册驱动

      Class.forName("com.mysql.jdbc.Driver");//输入反射对象的全路径即可注册   

2.2.获取数据库的连接(用户名/密码)

String url="jdbc:mysql://localhost:3306/cgb456";

解释:链接地址  "jdbc:mysql://ip地址:软件端口号/数据库名"

Connection c = DriverManager.getConnection(url, "root", "root");//链接地址,用户名,密码

防止中文乱码:url增加参数:characterEncoding=utf8

Stringurl="jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false";

2.3.获取传输器

Statement s = c.createStatement();

或PreparedStatement p = c.prepareStatement(sql);

2.3.1 Statement和PreparedStatement区别

     (1) Statement是PreparedStatement的父接口

     (2) Statement低效不安全PreparedStatement高效安全

     (3)执行代码不同

Statement

         Statement s = c.createStatement();

             String sql= "Select*from dept";

             ResultSet r = s.executeQuery( sql );

 PreparedStatement

String sql="select * from tb_emp where deptno>? and mgr>?";

      PreparedStatement p = c.prepareStatement(sql);

         p.setInt(1,1);  //  第1个? 传入1

         p.setInt(2,100);  //  第2个? 传入100

         如果sql语句不需要传入值不需要上述两句set

             ResultSet r = s.executeQuery(  );

2.4.执行SQL

    String sql= "Select*from dept";  //sql为要执行的sql语句

    ResultSet r = s.executeQuery(sql);//用来执行查询的方法

    int i  = s.executeUpdate();//用来执行增删改,返回影响行数

2.5.处理数据库返回结果

    使用循环语句把每个值获取。

    while (r.next()){         //通过ResultSet的next方法判断是否有下一个数据

           int a= r.getInt(1);  //获取第一列的int值

            System.out.println(a);

        };

2.6.释放资源

  r.close(); //关闭结果

  p.close(); //关闭结果

  s.close();//关机传输器

  c.close();//关闭连接

2.7 JDBC常见问题

2.7.1 Class.forName这句话有用没?

Class.forName可以指定class类路径进行动态创建对象实例,可JDBC这句话没有返回对象啊,那写这句有什么作用呢?看看java.sql.Driver.class的源码就找到真相了,原来它用了静态代码块创建对象。

 

2.7.2 写了创建了,那不写呢?怎么不写也能执行呢?

Java提供了SPI机制,用户可以自行配置类,JDBC高版本驱动就都引入了这个支持。如果用户使用了Class.forName方式就自己指定了驱动,如果未写这句话,则Java自动去META-INF/services/java.sql.Driver文件中找启动类。

2.7.3不同版本的mysql需要不同版本的驱动

Mysql5.0x mysql-connector-java-5.1.32.jar

Mysql8.0x mysql-connector-java-8.0.21.jar

Driver变成了: com.mysql.cj.jdbc.Driver,中间多了cj

url必须加时区参数: serverTimezone=Asia/Shanghai

2.7.4中文乱码

url增加参数:characterEncoding=utf8防止中文乱码

String  url ="jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8

&serverTimezone=Asia/Shanghai&useSSL=false";

3.jdbc总结

1, 什么是JDBC? java程序连接数据库的标准方案,全称是java database connectivity

2, 使用JDBC步骤? 导入jar包,注册驱动,获取数据库的连接,获取传输器,执行SQL,解析结果集(查询),关闭资源

3, 传输器Statement和PreparedStatement有什么区别? Statement不安全(可能发生SQL攻击),而且低效

4, Statement和PreparedStatement有什么关系? public interface PreparedStatement extends Statement ,是父子接口

5, SQL攻击? 原因是:SQL中出现了特殊符号#(注释符号)改变了SQL的语义 解决方案:使用新的传输器PreparedStatement

6, 执行SQL: 先执行SQL骨架,然后再给SQL设置参数

executeUpdate(): 用来执行增删改的SQL语句,并且返回了影响行数

executeQuery(): 用来执行查的SQL语句,并且返回了结果集ResultSet

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值