黑马程序员技术交流社区

标题: 【石家庄校区】mysql的单表多表及JDBC的使用 [打印本页]

作者: 空降的蛙崽    时间: 2018-5-9 15:27
标题: 【石家庄校区】mysql的单表多表及JDBC的使用
本帖最后由 小石姐姐 于 2018-5-11 09:41 编辑

mysql的单表多表及JDBC的使用
SQL结构化查询语言SQL的分类DDL: 数据定义语言
Create, Drop,Alter
Grant(授权), if...
DML:数据操纵语言
insert, update, delete,
DQL:数据查询语言
select
对数据库进行操作创建数据库
create database 数据库名称 character set 字符集 collate 字符集校对规则;
查看数据库
查看数据库服务器中所有的数据库:
show databases;
查看某个数据库的定义信息:
show create database 数据库名;
修改数据库
alter database 数据库名称  character set 字符集 collate 校对规则;
删除数据库
drop database 数据库名称;
切换数据库
use 数据库名;
查看当前正在使用的数据库
select database( );
对数据库表进行操作创建表
create table 表名称(字段名称 字段类型(长度) 约束, 字段名称 字段类型(长度) 约束.....);
字段类型:
一个实体对应一个表,一个实体属性对应表的一个字段.
java中的类型:                                                                        mysql中的类型:
byte/short/int/long                                                                tinyint/smallint/int/bigint
float                                                                                        float
double                                                                                        double
boolean                                                                                        bit(0/1)非零为真
char/string                                                                                char和varchar
date                                                                                        date/time/datetime/timestamp
file                                                                                                BLOB/TEXT
char 和 varchar的区别?
char:  通常代表的是固定长度的字符或字符串
定义类型char(8),向这个字段存入字符串hello,那么数据库使用三个空格将其补全.
varchar:  代表的是可变长度的字符串
​        定义类型是varchar(8),向这个字段存入字符串hello,那么存入到数据库的就是hello.
datetime 和 timestamp的区别?
datetime:        就是既有日期又有时间的日期类型,如果没有像这个字段中存值,数据库使用null存入到数据库中
timestamp:        也是既有日期又有时间的日期类型,如果没向这个字段中存值,数据库会使用当前的系统时间存入到数据库中
约束
约束作用:保证数据的完整性
单表约束分类:
主键约束: primary key 主键约束默认就是唯一  非空的
唯一约束:unique
非空约束:not null
建表语句create database web_test1;

use web_test1;

create table user(

•   id int primary key auto_increment, //自动增长,id递增

•   usename varchar(20) unique,

•   password varchar(20) not null,

•   age int,

•   birthday date

);查看表
查看某个数据库下的所有的表

show tables;
查看某个表的结构信息

desc 表名;删除表
drop table 表名;修改表
修改表: 添加列
alter table 表名 add 列名 类型(长度)约束;
修改表:修改列类型,长度和约束
alter table 表名 modify 列名 类型(长度) 约束;
修改表: 删除列
alter table  表名 drop 列名;
修改表: 修改列名称
alter table 表名 change 旧列名 新列名 类型(长度) 约束;
修改表: 修改表名
rename table 表名 to 新的表名;
修改表: 修改表的字符集
alter table  表名  character set 字符集;
添加列/添加字段*
alter table  表名 add 字段名 字段类型(长度) 字段的约束;
修改字段的类型或长度*
alter table  表名 modify  字段名 字段类型(长度) 字段的约束;
对数据库表的记录进行操作(重点)添加表的记录
向表中插入某些列:
insert into 表名 (列名1,列名2,列名3...) values (值1,值2,值3...);
向表中插入所有列:
insert into 表名 values(值1,值2,值3...);
注意事项(重要):
1 值的类型要与数据库中表的列的类型一致
2 值的顺序要与数据库中表的列的顺序一致
3 值的最大长度不能超过列设置的最大长度
4 值的类型是字符串或日期类型, 需要使用单引号引起来
添加记录
添加某几列

insert into 表名(id,username,password) values (null,'aaa','123');
添加所有列

insert into 表名 values(null,'bbb','123',23,'1996-12-17'); // 和表中字段顺序保持一致
select * from 表名   //即可查看
添加中文记录

insert into 表名 values(null,'张三','123',23,'1996-12-17');直接向数据库中插入中文记录会出现错误!!!!!
解决办法:
show variables like '%character%';   查看数据库与字符集相关参数
需要将mysql数据库服务器中的客户端部分的字符集改为gbk
找到mysql安装路径: my.ini文件,修改文件中[client]下的字符集
重启mysql服务器  services.msc
修改表的记录
update 表名 set 列名=值,列名=值 [where 条件];
注意事项:
1 值的类型要与列的类型一致
2 值的最大长度不能超过列设置的最大长度
3 字符串类型和日期类型添加单引号
修改某一列的所有值

update 表名 set  password = 'abc';
按条件修改数据:

update 表名 set password = 'xyz' where usename = 'bbb';
按条件修改多个列

update 表名  set password = '123', age = 34 where username = 'aaa';删除表的记录
delete from 表名 [where 条件];
注意事项:
1 删除表的记录, 指的是删除表中的一行记录
2 删除如果没有条件, 默认是删除表中的所有记录
删除某一条记录

delete from 表名 where id = 2;
删除表中的所有记录

delete from 表名;
删除表中的记录有两种做法:
delete from 表名;
​        删除所有记录, 属于DML 语句,一条记录一条记录的删除,事务可以作用在DML语句上的
truncate table 表名;
​        删除所有记录,  属于DDL 语句 ,将表删除,然后重新创建一个结构一样的表,事务不能控制DDL
rollback: 回滚
查看表的记录(重点)
环境的准备:

create table exam(

•    id int primary key auto_increment,

•    name varchar(20),

•    english int,

•    chinese int,

•    math   int

);




insert into exam values (null,'张三',85,74,91);

insert into exam values (null,'李四',95,90,83);

insert into exam values (null,'王五',85,84,59);

insert into exam values (null,'赵六',75,79,76);

insert into exam values (null,'田七',69,63,98);

insert into exam values (null,'李老八',89,90,83);
基本查询

select [distinct] * |列名 from 表[条件];
查询所有学生考试成绩信息

select * from exam;
查询所有学生的姓名和英语成绩

select name, english from exam;
查询英语成绩信息(不显示重复的值)

select distinct english from exam;
查看学生的姓名和学生的总成绩

select name,english+chinese+math from exam;
别名查询

select name,english+chinese+math  sum from exam;
条件查询
使用where子句
大于>  , <     , >=   ,    <=   <>    ,=   
like:  模糊查询
in  :  范围查询
条件关联: and  or  not
查询李四学生的成绩:

select * from exam where name = '李四';
查询名称叫李四并且英语大于90分的

select * from exam where name = '李四' and english>90;
查询姓李的学生的信息

select * from exam where name like '李%';
like可以进行模糊查询,在like子句中可以使用下划线或百分号作为占位符
下划线只能代表一个字符,而百分号可以代表多个字符

like '李_' : 名字中必须是两个字,而且是姓李的

like '李%' : 名字中姓李的学生,李字后可以是一个或人任意个字符

like '%四'  : 以四结尾的

like '%王%' : 只要名称中包含这个字就可以
查询英语成绩是69,75,89学生的信息

select * from exam where english in(69,75,89);
排序查询
使用 order by 字段名称  asc升序/desc降序        默认升序
查询学生信息并按照语文成绩进行排序

select * from exam order by chinese;
查询学生信息并按照语文成绩倒序排序

select * from exam order by chinese desc;
查询学生信息,先按照语文成绩倒序排序,如果成绩相同就按照英语成绩升序排序

select * from exam order by chinese desc, english asc;
查询姓李的学生的信息,按照英语成绩的降序排序

select * from exam where name like '李%'  order by english desc;
分组统计查询
聚合函数使用
​        sum():
获取所有学生的英语的成绩的总和
select sum(english) from exam;

获取所有学生的英语成绩总和和数学成绩总和
select sum(english),sum(math) from exam;

查询姓李的学生的英语成绩总和
select  sum(english) from exam where name like '李%';        

查询所有学生各科的总成绩
select sum(english)+sum(chinese)+sum(math) from exam;

select sum(english+chinese+math) from exam;

有什么不同?
第一行: 按照列的方式统计,英语成绩总和+语文成绩总和+数学成绩总和
第二行: 先计算英语+数学+语文   然后再求和
count():
获得学生的总数
select count(*) from exam;

​        max():
获得数学成绩的最高分
select max(math) from exam;

​        min():
获得语文成绩的最低分
select min(chinese) from exam;

​        avg():
获得英语成绩的平均值
select avg(english) from exam;

分组查询
使用 group by 字段名称
环境准备:
create table orderitem(    id intprimary key auto_increment,    productvarchar(20),    pricedouble);insert into orderitem values (null,'电视机',2999);insert into orderitem values (null,'电视机',2999);insert into orderitem values (null,'洗衣机',1000);insert into orderitem values (null,'洗衣机',1000);insert into orderitem values (null,'洗衣机',1000);insert into orderitem values (null,'冰箱',3999);insert into orderitem values (null,'冰箱',3999);insert into orderitem values (null,'空调',1999);

按商品名称统计,每类商品所购买的个数
select product, count(*) from orderitem group by product;

按商品名称统计,每类商品所花费的总金额
select product,sum(price) from orderitem group by product;

按商品名称统计,花费金额在5000以上的商品
where 子句后边不能跟着聚合函数 如果现在要使用带有聚合函数条件的过滤(分组后的条件过滤) 需要使用一个关键字 having
select product,sum(price) from orderitem group by product having sum(price) >5000;

按商品名称统计,统计没类商品花费的总金额在5000以上的商品, 总金额升序
select product,sum(price) from orderitem group by product having sum(price) >5000 order by sum(price) asc;

总结
S(select)...F(from)...W(where)...G(group by)...H(having)...O(order by);
数据库的备份
第一步: 在cmd命令行窗口 输入mysqldump -u root -p  要备份的数据库名称   > 备份路径
数据库的还原一
第一步:在数据库服务器内部创建数据库
mysql -u root -p
create database 数据库名
第二步:在命令行窗口
mysql -u root -p 要还原数据的名字 < 备份的路径
数据库的还原二
第一步:在数据库服务器内部创建数据库
mysql -u root -p
create database 数据库名
第二步: 切换到该数据库使用source命令还原
use 数据库名
source  备份的路径
mysql多表多表约束
外键约束: 用来保证数据完整性(多表之间)
alter table 表名  add foreign key(要添加外键的字段) reference key dept (要和哪个表的哪个字段关联);
表与表之间的关系
一对多关系
​             一个部门下可以有多个员工,一个员工只能属于某一个部门
建表原则: 在多的一方创建外键指向一的一方的主键
多对多关系
​        一个学生可以选择多门课程,一门课程也可以被多个学生选择
建表原则:需要创建第三张表(中间表), 在中间表中至少两个字段,分别作为外键去指向多对多双方的主键。
一对一的关系
​        一个公司可以有一个注册地址,一个注册的地址只能对应一个公司
唯一外键的对应的方式:假设一对一是一个一对多关系,需要在多的一方创建外键指向一怼的一方的主键,将外键设置为唯一(unique)
主键对应的方式:将两个表的主键建立关系即可
多表查询的分类连接查询
交叉连接: cross jion        查询到的是两个表的笛卡尔积。
​        语法: select * from 表一 cross join表二;
​                        select * from 表一,表二;
内连接:inner join(inner是可以省略的)
显示内连接:在SQL中显示的调用inner join关键字
​        语法:select * from 表一 inner join 表二 on 关联条件;
隐式内连接:在SQL中没有调用inner join 关键字
​        语法:select * from 表一,表二 where 关联条件;
外连接:outer join(outer 可以省略)
左外连接:
语法:select * from 表一 left outer join 表二 on 关联条件;
以左边为基准,根据关联条件去右表查询,如果匹配上了,则返回匹配上的数据,如果匹配不上则返回null
右外连接:
语法:语法:select * from 表一 right outer join 表二 on 关联条件;
内连接和外连接的区别?子查询
一个查询语句条件需要以来另一个查询语句的结果。
带in的子查询
查询学生生日在91年之后的班级的信息。
select * from classes where cid in(select cno from student where birthday > '1991-01-01');
带exists的子查询
查询学生生日大于91年1月1日,如果记录存在,执行语句

select * from classes where exists(select cno from student where birthday > '1991-01-01');
带any的子查询
大于任意一个

select * from classes where cid> any(select cno from student);
带all的子查询

select * from classes where cid > all(select cno from student);多表查询练习
查询班级名称,和班级总人数

select c.cname,count(*) from classes c, student s where c.cid = s.cno  group by c.cname;
查询学生的姓名和学生所选的总课程平均分

select s.sname,avg(sc.score) from student, s,stu_cour sc where s.sid = sc.sno group by s.sname;
查询学生的姓名和学生的选课总数,显示选课超过2门的学生姓名

select s.name, count(*) from student, s,stu_cour sc where s.sid = sc.sno group by s.sname;
查询平均趁成绩大于80 的学生成绩

select count(*) from student s where s.sid in(select sc.sno,avg(sc.score) from stu_cour sc group by sc.sno having avg(sc.score)>80);
查询学生和平均成绩,但是平均成绩大于01班的任何一个学生的平均成绩。

select s.sname,avg(sc.score) from student s,stu_cour sc where s.sid = sc.sno group by
s.sname having avg(sc.score) > any(SELECT AVG(sc.score) FROM student
s,stu_cour sc,classes c WHERE s.sid = sc.sno AND s.cno = c.cid AND c.cname= '01班' GROUP BY s.sname);事务的概念
指的是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么全都成功,要么全都失败
开启事务:

start transaction;
提交事务:

commit;
回滚事务:

rollback;事务的特性
原子性
事务的不可分割,组成事务的各个逻辑单元不可分割
一致性
事务执行的前后,数据完整性保持一致
隔离性
事务执行不应该受到数据库中其他事务的干扰
持久性
事务一旦结束(包括提交和回滚),数据就持久化到数据库中。
隔离性
事务执行不应该受到数据库中其他事务的干扰
如果不考虑隔离性(一个事务执行收到其他的事务的干扰),引发一些安全问题,主要体现在读取数据上
在读取数据上:
脏读:一个事务都到了另一个事务未提交的数据,导致查询结果不一样
不可重复读:一个事务读到了另一个事务已经提交的update的数据,导致多次查询结果不一致
虚读/幻读: 一个事务读到了另一个事务已经提交的insert的数据,导致多次查询结果不一致
解决这些安全性问题:
设置事务的隔离级别
read uncommitted:         脏读, 不可重复读,虚读都有可能发生
read committed:                 避免脏读,但是不可重复读和虚读是有可能发生
repeatable read:                 避免脏读和不可重复读,但是虚读有可能发生
serializable:                         避免脏读,不可重复读,虚读
JDBC开发步骤步骤1:注册驱动:Class.forName()
步骤2:获得连接:Connection conn = DriverManger.getConnection(url,username,password)// Connection java.sql包下的
步骤3:编写SQL语句,String sql ="",以前的值的地方用占位符代替  ?就是占位符
步骤4:预编译sql并且获得可执行sql语句的对象PreparedStatement ps = conn.prepareStatemet(String sql)
步骤5:为sql语句设置值,用值代替sql语句中的?   ps.setXXX(int n,值) n:代表第几个问号的意思,n从1开始
步骤6:执行sql语句
    如果是查询:ResutSet rs = ps.executeQuery();
        遍历结果集:
        while(rs.next()){
            rs.getXXX(String columnName)/rs.getObject(String columnName) ;
            //columnName默认是表地段名,如果取了别名,用别名
        }
    如果是增删改:int num = ps.executeUpdate() ;// num 代表影响的行数
步骤7:释放资源

工具类的抽取:Properties对象的使用Properties prop = new Properties();
prop.load(new FileInputStream(String path));
prop.getProperty(String key)
   
属性文件:.properties
key=value
aaa=adfadf
bbb=dafda









欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2