Advertisement

第五章笔记整理

阅读量:

数据库(DataBase):指长期保存在计算机的存储设备上,按照一定规则组织起来,可以被各种用户或应用共享的数据集合。

用户通过数据库管理系统(DataBase Management System)访问数据库中的数据。

常见的数据库管理系统:Oracle(甲骨文)、MySQL、DB2、Microsoft SQL Server。

什么是三大范式?

第一范式(1NF):无重复的列。

第二范式(2NF):属性完全依赖于主键[消除部分子函数依赖]。

第三范式(3NF):属性不依赖于其它非主属性[消除传递依赖]。

(面试)

SQL分类

DDL数据定义语言,用来定义数据库对象:库、表、列等。

DML数据操作语言,用来定义数据库记录。

DCL数据控制语言,用来定义访问权限和安全级别。

DQL数据查询语言,用来查询记录。

SQL以分号结尾(不区分大小写,关键字建议使用大写)

mysql -u (账号root) -p (密码123456)

DDL数据定义语言

创建数据库:create database if not exists 数据库名;(不存在时才创建)

创建库时,设置编码(UTF-8在MYSQL中使用:UTF8MB4替代):

create database 数据库名 character set UTF8MB4;

查看所有数据库:show databases;

删除数据库:drop database if exists 数据库名;(表存在时才删除)

查看当前使用的数据库:select database();

切换数据库:user 数据库名;

创建表:create table 表名(列名1 数据类型,列名2 数据类型...);

查看当前数据库的表:show tables;

查看表的字段信息:desc 表名;

查看表的创建细节:show create table 表名;

alter table 表名 add 列名 数据类型;

alter table 表名 change 列名 新列名 新的数据类型;

alter table 表名 rename 新表名;

alter table 表名 drop 列名;

alter table 表名 character set 编码方式;修改表的字符集(默认为UTF-8)

常用的数据类型:

1.int整型数字

2.bigint大整型数字

3.double浮点型数字

定义的格式:score double(5,2)--小数点前5位,小数点后2位。

4.date日期,只有年月日,使用时的格式:yyyy-MM-dd HH-mm-ss

5.datetime日期+时间,包含年月日时分秒,使用时的格式(同上)

6.timestamp时间戳,13位数字,从1970-01-01到现在的毫秒数

7.varchar变长字符串

定义的格式:name varchat(20)--姓名最大使用20个字符

在oracle中,varchar被废弃了,建议使用varchar2

(面试)

char(定长字符串)与varchar的区别在于:先扩充空间,再存放数据,即使用不完也要占着。

DML数据操作语言

插入操作:insert(非数值的列值两侧需要加上单引号)

insert into 表名(列名) values(数据值);

当给所有列添加数据的时候,可以将列名省略(数据值必须按顺序添加)。

多行新增:insert into 表名t1(列名1,列名2) values(第一行数据值1,值2),(第二行数据值1,值2);

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

整列修改:update 表名 set 列1=值1,列2=值2...;

修改符合条件的数据:update 表名 set 列1=值2 where 列1=值1 and ...;

(面试)

清空表格的删除方式:

delete from 表名 where 列名=值;(表删除后可以找回)

不建议使用,原因是记录过多时,效率很低。

truncate from 表名;(表删除后不能找回)

先删除表格文件,再创建,效率较高。

DCL数据控制语言

创建用户:create user 用户名@localhost(当前电脑IP) identified by ‘密码’;

指定IP才能登录:create user 用户名@‘客户端IP’ identified by ‘密码’;

任意IP均可登录:create user 用户名@‘%’ identified by ‘密码’;

给指定用户授权指定数据库的指定权限:

grant 权限1、权限2~权限n on 数据库名.* to 用户名@‘IP’;

开放所有数据库权限:grant all on . to 用户名@‘IP’;

用户权限查询:show grants for 用户名@‘IP’;

删除用户:drop user 用户名@‘IP’;

撤销用户权限:revoke 权限1~权限n on 数据库名.* from 用户名@‘IP’;

DQL数据查询语言

范围查询:select * from 表名 where 列名 (加not取反) in (列值1,列值2);

区间查询:select * from 表名 where 列名 between 开始值 and 结束值;

模糊查询:select * from 表名 where 列名 like ‘表达式’;(表达式必须是字符串)

通配符:_(下划线)代表任意一个字符 %代表0~n个字符

字段控制查询

去除重复记录:select distinct 列名 from 表名;

计算两列之和(横向运算,若列2的值为null,则赋值为0):

select 列1+ifnull(列2,0) as 自定义列名 from 表名;

null的比较运算不是通过=和!=来判断,而是用is null / is not null。

创建或覆盖视图

格式一:create or replace view 视图名称 as 查询语句;

格式二:create view 视图名称 as 查询语句;

排序

select * from 表名 order by 列名 asc(默认升序,可省略)/desc(降序);

多列排序:当前面的列值相同时,才会按后面的列值进行排序。

select * from 表名 order by 列1 asc,列2 desc;

聚合函数是用来做纵向运算的函数

select count(*) from 表名; 纵向统计排除null值

总和sum() 平均值avg() 计算数量count() 最大值max() 最小值min(*)

分组查询

select 可加列名用作区分 sum(*) from 表名 group by 列名;

注意:如果查询语句中有分组操作,则select后面只能添加聚合函数和被分组的列名。

分组之前用where进行判定,分组之后用having进行过滤(分组条件)。

limit 开始下标,显示条数;

pageindex页码值 pagesize每页显示条数

分页查询:limit (pageindex-1) * pagesize,pagesize;

数据库的完整性:用来保证存放到数据库中的数据是有效的,即数据的有效性和准确性。

(确保数据的完整性 = 在创建表时给表中添加约束)

完整性的分类:

实体完整性(行完整性)

主键约束:primary key:每个表中要有一个主键,且数据唯一,不能为null。

唯一约束:unique:数据不能重复。

自动增长:auto_increment:给主键添加自动增长的数值,列只能是整数类型。

域完整性(列完整性)

非空约束:not null 默认约束:default

引用完整性(关联表完整性)

外键约束:foreign key

create table 表名(字段列表,constraint 自定义外键名称 foreign key(外键字段) references 主键表名(主键字段));

建议:这些约束应该在创建表的时候设置,多个约束条件之间使用空格间隔。

追加约束:modify

alter table 表名 modify 字段名称 数据类型 约束关键字;

一对多关系建表原则:

在多的一方创建一个字段,字段作为外键指向一方的主键。

多对多关系建表原则:

需要创建第三张表,中间表中至少有两个字段,这两个字段分别作为外键指向各自一方的主键。

一对一关系建表原则:

唯一外键对应:假设一对一是一个一对多的关系,在多的一方创建一个外键指向一方的主键,将外键设置为unique。

主键对应:让一对一双方的主键建立关系。

多表关系处理数据:

1、数据库通过外键建立两表关系

2、实体类通过属性的方式建立两表关系 要求:类名=表名,列名=属性名

多表查询:

1.合并结果集:把两个select语句的查询结果合并到一起。

UNION(去重)、 UNION ALL(注意:列数、列类型必须相同才能合并)

2.连接查询:求多个表的乘积。

连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1), (a,2),(b,0),(b,1),(b,2)}。

使用主外键关系作为条件去除无用信息

内连接 INNER JOIN ON INNER可省略

select 字段列表 from 表1 inner join 表2 on 消除笛卡尔积的条件;

外连接 OUTER JOIN ON

左外连接 LEFT JOIN ON

右外连接 RIGHT JOIN ON

全外连接 FULL JOIN(MySQL不支持)

自然连接 NATURAL JOIN

3.子查询:一个select语句中包含另一个完整的select语句。

三表联查:select 列名 from 表1,表2,表3 where 表1.列名=表2.列名 and 表1/表2.列名=表3.列名;

now();获得当前系统时间

year(日期值);获得日期值中的年份

date_add(日期,inserval 计算值 计算的字段);

注意:计算值大于0表示往后推日期,小于0表示往前推日期。

数据库优化:

1.对查询进行优化,要尽量避免全表扫描,首先应考虑在where或order by涉及的列上建立索引。

2.应尽量避免在where子句中对字段进行null值判断,否则将导致引擎放弃使用索引,从而进行全表扫描。

3.应尽量避免在where子句中使用!=或<>操作符,否则引擎将放弃使用索引,从而进行全表扫描。

4.应尽量避免在where子句中使用or来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引,从而进行全表扫描。

5.in和not in也要慎用,否则将会进行全表扫描。

事务:将多条SQL语句看作一个整体,要么一起成功,要么一起失败。

SQL语句

开启事务:start transaction;或 begin;

提交事务:commit;使得当前的修改确认

回滚事务:rollback;事务在未提交之前都是可以回滚的

java操作:

java是通过链接对象使用事务的,事务之间的隔离是基于链接描述的,默认情况下,JDBC的事务是自动提交的。

开启事务:Connection对象.setAutoCommit(false);

提交事务:Connection对象.commit();

回滚事务:Connection对象.rollback();

(面试)

事务的ACID特性:

原⼦性(Atomicity)

事务开始后所有操作要么全部做完,要么全部不做,不可能停滞在中间环节。

⼀致性(Consistency)

事务在执⾏之前和执行之后,数据库都必须处于⼀致性状态。

隔离性(Isolation)

并发执行的各个事务是不能互相干扰的。

持久性(Duration)

事务⼀旦提交,数据必须被永久保存。

(面试)

事务的并发问题

脏读:读取到了没有提交的数据,事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。

不可重复读:同⼀条命令返回不同的结果集(更新)。事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据做了更新并提交,导致事务A多次读取同一数据时,结果不一致。

幻读:重复查询的过程中,数据就发⽣了量的变化(insert,delete)。

(面试)

事务隔离级别 脏读 不可重复读 幻读
读未提交READ_UNCOMMITTED 允许 允许 允许
读已提交READ_COMMITTED 禁止 允许 允许
可重复读REPEATABLE_READ 禁止 禁止 可能会
顺序读SERIALIZAB 禁止 禁止 禁止

从上往下,级别越高,并发性越差,安全性越高;⼀般数据默认级别是读已提交或可重复读。

(面试)

查看当前会话中事务的隔离级别:select @@tx_isolation;

修改隔离级别:set global transaction isolation level 隔离级别;

JDBC是一种用于执行SQL语句的java API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成。

1.连接数据库。

2.创建SQL或MySQL语句。

3.在数据库中执行SQL或MySQL查询。

4.查看和修改生成的记录。

JDBC核心组件

DriverManager:此类管理数据库驱动程序列表,使用通信子协议将来自java应用程序的连接请求与适当的数据库驱动程序匹配。

Driver:此接口处理数据库与服务器的通信,我们很少会直接与Driver对象进行交互,而是使用DriverManager对象来管理这种类型的对象。

Connection:该界面具有用于联系数据库的所有方法,连接对象表示通信上下文,即与数据库的所有通信仅通过连接对象。

Statement:使用从此接口创建的对象将SQL语句提交到数据库,除了执行存储过程之外,一些派生接口还接受参数。

ResultSet:在使用Statement对象执行SQL查询后,这些对象保存从数据库检索的数据。它作为一个迭代器,允许我们移动其数据。

SQLException:此类处理数据库应用程序中发生的任何错误。

Create、Read、Update and Delete通常称为CRUD操作。

RDBMS JDBC驱动程序名称 网址格式
MYSQL8 com.mysql.cj.jdbc.Driver jdbc:mysql://localhost:3306/databaseName?characterEncoding=utf8&useSSL=false &serverTimezone=UTC
MySQL com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/databaseName
ORACLE oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@hostname:port Number:databaseName
DB2 COM.ibm.db2.jdbc.net.DB2Driver jdbc:db2:hostname:port Number / databaseName
SYBASE com.sybase.jdbc.SybDriver jdbc:sybase:Tds:hostname:port Number / databaseName

JDBC的连接步骤:

1、引入jar文件

2、加载数据库驱动(JavaSE项目中可以省略,JavaWeb项目必须编写此步骤)

Class.forName(“JDBC驱动程序名称”);

3、获取链接

Connection conn = DriverManger.getConnection(“jdbc:mysql://本机地址localhost:端口号3306/数据库名?characterEncoding=utf8&useSSL=false&时区serverTimezone=UTC”,“账号”,“密码”);

4、创建状态通道

Statement state = conn.createStatement();

int resultSet = state.executeQuery(查);//.executeUpdate(增删改);

5、取出结果集信息

while(resultSet.next()){ //判断是否有下一条数据 }

6、非空则关闭资源

if(conn/state/resultSet!=null){ conn/state/resultSet.close();}

SQL注入是通过执行恶意的SQL命令,达到欺骗服务器的结果(把SQL命令插入到Web表单提交或输入域名或页面请求)。

批处理:将多条SQL语句放在一起批量处理,每一条语句的成功和失败都与其它语句无关。

Statement的批处理使用:

将一条SQL语句加入批处理:Statement对象.addBatch(SQL语句);

执行批处理:Statement对象.executeBatch();

清空批处理:Statement对象.clearBatch();

PreparedStatement的批处理使用:

预编译时,存在?可以通过多次的填充?来完成对多条相同语句的批处理添加。

前提:得到PreparedStatement对象:conn.prepareStatement(带有?的预编译语句);

填充预编译的参数:PreparedStatement对象.SetXXX(填充?);

把上面填充完毕?的内容添加到批处理:PreparedStatement对象.addBatch();

如需再次填充和添加,重复以上两步即可,最后执行、清空(同上Statement)。

(面试)

对比Statement和PreparedStatement:

1.Statement属于状态通道,PreparedStatement属于预状态通道。

2.预状态通道会先编译sql语句,再去执行,比statement执行效率高。

3.预状态通道支持占位符(?),给占位符赋值的时候,位置从1开始。

4.预状态通道可以防止sql注入,原因:预状态通道在处理值的时候以字符串的方式处理。

数据连接池原理:连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象;当使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。

最小连接数:数据库一直保持的数据库连接数,如果应用程序对数据库连接的使用量不大,将有大量的数据库资源被浪费。

初始化连接数:连接池启动时创建的初始化数据库连接数量。

最大连接数:连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求被加入到等待队列中。

最大等待时间:当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置参数为0或者负数使得无限等待(根据不同连接池配置)。

DBCP连接池

在项目的src文件夹下添加配置文件dbcp.properties:

driverClassName = com.mysql.cj.jdbc.Driver

url=jdbc:mysql://localhost:3306/demo

username=root

password=123456

initialSize=10 //初始化连接数

maxActive=50 //最大连接数

maxIdle=20 //最大空闲连接

minIdle=5 //最小空闲连接

maxWait=6000 //最大等待时间

public void test() throws SQLException{

// 硬编码,使用DBCP连接池

BasicDataSource source = new BasicDataSource();

// 设置连接的信息

source.setDriverClassName("com.mysql.jdbc.Driver");

source.setUrl("jdbc:mysql://localhost:3306/demo");

source.setUsername("root");

source.setPassword("123456");

Connection conn = source.getConnection();

String sql = "select * from student";

Statement state = conn.createStatement();

ResultSet rs = state.executeQuery(sql);

while (rs.next()) {

System.out.println(rs.getString(2));

}

conn.close(); //回收

}

C3P0连接池

C3P0是在外部添加配置文件,工具直接进行引用,要求固定的命名和文件位置。

文件位置:src

文件命名:c3p0-config.xml/c3p0-config.properties

com.mysql.cj.jdbc.Driver

jdbc:mysql://localhost:3306/demo

root

123456

30000

30

10

30

100

10

200

com.mysql.jdbc.Driver

jdbc:mysql://localhost:3306/demo

root

123456

5

20

10

40

20

5

定义代码:

Connection con=null;

ComboPooledDataSource db=new ComboPooledDataSource("abc");

public Connection getCon(){

try {

con=db.getConnection();

System.out.println("初始化的链接数量:"+db.getInitialPoolSize());

} catch (SQLException e) {

e.printStackTrace();

}

return con;

}

C3P0和DBCP的区别:

1、DBCP没有自动回收空闲连接的功能,C3P0有自动回收空闲连接的功能。

2、DBCP需要手动设置配置文件,C3P0不需要手动设置。

Druid连接池

/**

  • 阿里的数据库连接池

  • 是目前比较流行的、高性能的分布式列存储的OLAP框架(具体来说是MOLAP)

  • Druid(德鲁伊)

**/

public class DruidUtils {

//声明连接池对象

private static DruidDataSource ds;

static{

//实例化数据库连接池对象

ds = new DruidDataSource();

//实例化配置对象

Properties properties = new Properties();

try {

//加载配置文件内容

properties.load(DruidUtils.class.getResourceAsStream("dbcpconfig.properties"));

//设置驱动类全称

ds.setDriverClassName(properties.getProperty("driverClassName"));

//设置连接的数据库

ds.setUrl(properties.getProperty("url"));

//设置用户名

ds.setUsername(properties.getProperty("username"));

//设置密码

ds.setPassword(properties.getProperty("password"));

//设置最大连接数量

ds.setMaxActive(Integer.parseInt(properties.getProperty("maxActive")));

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

//获取连接对象

public static Connection getConnection() {

try {

return ds.getConnection();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return null;

}

}

全部评论 (0)

还没有任何评论哟~