数据库基础知识

原文链接: https://blog.csdn.net/weixin_44458228/article/details/86680365

数据库基础知识

  • 1、什么是数据库
  • 2、SQL语句
  • 3、JDBC 概述
  • 4、连接池概述
  • 5、开源数据库连接池-C3P0
  • 6、事物介绍
  • 7、设置隔离级别

数据库在应用程序中占据着非常重要的地位。从原来的Sybase数据库,发展到今天的SQLServer、MySQL、Oracle等高级数据库,数据库已经相当成熟了。

1、什么是数据库

数据库是一种存储结构,它允许使用各种格式输入、处理和检索数据,不必再每次需要数据时重新输入。如:给某人打电话时,需要看电话簿,电话簿就像一个数据库。
数据库具有以下特点:
a. 实现数据共享
b. 减少数据的冗余度
c. 数据的独立性
d. 数据实现集中控制
e. 数据的一致性和可维护性,以确保数据的安全性和可靠性
数据库的基本结构:
a. 物理数据层-----数据库最内层(用户加工的对象,内部指令操作处理的字符和字组成)
b. 概念数据层-----数据库中间层(属于数据库整体逻辑的表示,指出了数据的逻辑定义及数据间的逻辑联系)
c. 逻辑数据层-----用户所看到和使用的数据库(是逻辑记录的集合)
数据库的种类及功能
a. 层次型数据库:类似于树结构,特点是记录之间的联系通过指针实现
b. 网状型数据库:网络模型是使用网络结构表示实体类型、实体间联系的数据模型
c. 面向对象型数据库:建立在面向对象的基础上
d. 关系型数据库:是目前最流行的数据库,是基于关系模型建立的数据库。比较典型的就是:Mysql数据库了,是免费开源的关系型数据库。具有功能强、使用简便、管理方便、运行速度快、安全可靠性强等特点。

2、SQL语句

在应用程序中使用最多的是数据操纵语言,也是最常用的核心SQL语言。

增------insert语句-------向表中插入新数据
格式:insert into 表名 values(属性值1,属性值2…)

//向名为tb_emp的数据表,添加id为2,name=丽丽 sex=女 department=销售部的数据
insert into tb_emp values(2,‘丽丽’,‘女’,‘销售部’) ;
1
2
删-----delete语句---------删除数据
格式:delete from 数据表名 where 条件表达式

//假设要删除数据表tb_emp中编号为6的员工;
delete from tb_emp where id=6;

改--------update语句-------更新数据表的某些记录
格式:update 数据表名 set 字段名 = 新的字段值 where 条件表达式

//假设将数据表tb_emp中2号员工的年龄修改为24
update tb_emp set age=24 where id=2;
1
2
查-------select语句-------从表中查询数据
格式:select 所选字段列表 from 表名 where 条件表达式 group by 字段名 having 条件表达式(指定分组的条件) order by 字段名[asc/desc]-------------查询语句在日常业务中比较复杂需要灵活运用

//假设将tb_emp表中所有女员工的姓名、年龄,按年龄升序的形式查询出来。
select name,age from tb_emp where sex=‘女’ order by age;

3、JDBC 概述

什么是JDBC
JDBC( Java DataBase Connectivity ) 翻译过来就是Java数据库连接,其实就是通过Java语言操作数据库的一门技术。

JDBC的由来
由于数据库厂商提供的数据库驱动(操作数据库的jar包)各不相同,导致开发人员的学习成本十分的高。因此SUN公司提出了JDBC这套规范,用来统一访问数据的标准。JDBC本质上是一套接口,SUN要求所有的数据库厂商在设计驱动时,都要实现JDBC这套标准。因此开发人员只要学会JDBC这套接口,所有的数据库驱动就都会使用了。

JDBC主要是由java.sql 和javax.sql包组成的,并且这两个包已经被集成到J2SE的规范中了,这意味着,只要一个普通的java程序就可以使用JDBC。
需要注意的是,JDBC包中大部分都是接口,因此在开发数据库程序时,除了如上的两个包,还需要手动的导入具体的数据库驱动。

JDBC开发细节(六步)-------这是原理,后期不用这么复杂
a. 注册数据库驱动;
b. 获取数据库连接;
c. 获取传输器;
d. 利用传输器发送SQL到数据库执行,并返回执行结果;
e. 处理结果:将表中所有的记录输出在控制台;
f. 释放资源;

代码实现:
//a.注册数据库驱动
Class.forName(“com.mysql.jdbc.Driver”);

//b.获取数据库连接
Connection conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/jt_db? useUnicode=true&characterEncoding=utf-8”, “root”, “root”);
在这里插入图片描述
//c.获取传输器
Statement stat = conn.createStatement();

//d.利用传输器发送SQL到数据库执行,并返回执行结果
ResultSet rs = stat.executeQuery(“select * from account”);

//e.处理结果:将表中所有的记录输出在控制台
while (rs.next()) {
int id = rs.getInt(“id”);
String name = rs.getString(“name”);
double money = rs.getDouble(“money”);
System.out.println(id+" : “+name+” : "+money);
}

//f.释放资源
rs.close();
stat.close();
conn.close();
执行结果:
.在这里插入图片描述

PreparedStatement对象
在开发中我们用的更多的传输器对象是PreparedStatement,PreparedStatement是Statement的子接口,比Statement更加安全,并且能够提高程序执行的效率。

SQL注入攻击
SQL注入攻击:由于后台的SQL语句是拼接而来的。其中的参数是由用户提交的,如果用户在提交参数时,在其中掺杂了一些SQL关键字或者特殊符号,就可能会导致SQL语句的语意发生变化。从而执行一些意外的操作。

防止SQL注入攻击
如果防止SQL注入攻击? 使用PreparedStatement对象来替代Statement对象。
添加loginByPreparedSatement方法,在方法中,使用PreparedStatement来代替Statement作为传输器对象使用!

4、连接池概述

什么是连接池
在开发中,所谓的池就是一个容器,来存储程序的中的数据.
而数据库连接池就是用来存储数据库连接的池子,用于在整个程序中共享连接,减少连接开关的次数,实现连接的复用,从而提高程序执行的效率.

为什么要使用数据库连接池?
对于数据库来说,频繁的开关连接会非常的耗费资源,也会导致程序执行效率的低下。
我们可以在程序中创建一个池子,在程序启动时就初始化一批连接放在连接池中,当用户需要链接时,就直接从池子中拿一个连接使用,当用完连接后,也不要将连接关闭,而是将连接还回池中,下一个用户需要连接时也是如此。
这样可以减少链接开关的次数,从而提供程序执行的效率.
传统方式操作数据库:
数据库基础知识_第1张图片

使用连接池操作数据库:
数据库基础知识_第2张图片

5、开源数据库连接池-C3P0

使用C3P0连接池开发步骤:
a、导入开发包
在这里插入图片描述

b、创建数据库连接池
ComboPooledDataSource cpds = new ComboPooledDataSource();

c、设置数据库连接的基本信息
(1)方式一:(不推荐)
cpds.setDriverClass(“com.mysql.jdbc.Driver”);
cpds.setJdbcUrl(“jdbc:mysql:///jt_db?useUnicode=true&characterEncoding=utf-8”);
cpds.setUser(“root”);
cpds.setPassword(“root”);
(2)方式二:(推荐)
在类目录下(开发时可以放在src或者类似的源码目录下), 添加一个c3p0-config.xml文件, 配置内容如下:

com.mysql.jdbc.Driver jdbc:mysql:///jt_db?useUnicode=true&characterEncoding=utf-8 root root

6、事物介绍

什么是事务
数据库事务(Database Transaction),是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。
简单的说:事务就是将一堆SQL(通常是增删改操作)的执行绑在一起,要么都执行成功,要么都执行失败,即都执行成功才算成功,否则就会恢复到这堆SQL执行之前的状态。
下面以银行转账为例,张三转100块到李四的账户,这至少需要两条SQL语句:
给张三的账户减去100元;
update 账户表 set money=money-100 where name=‘张三’;
给李四的账户加上100元。
update 账户表 set money=money+100 where name=‘李四’;
如果在第一条SQL语句执行成功后,在执行第二条SQL语句之前,程序被中断了(可能是抛出了某个异常,也可能是其他什么原因),那么李四的账户没有加上100元,而张三却减去了100元。这肯定是不行的。
你现在可能已经知道什么是事务了吧!在上面整个转账过程中执行的所有SQL语句会在一个事务中,而事务中的多个操作,要么全都成功,要么全都失败,不可能存在成功一半的情况。
也就是说给张三的账户减去100元如果成功了,那么给李四的账户加上100元的操作也必须是成功的;否则,给张三减去100元以及给李四加上100元都是失败的。

事务的四大特性
(1)原子性(Atomicity):事务中所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
(2)一致性(Consistency):事务执行后,数据库状态与其它业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
(3)隔离性(Isolation):隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。也就是说,在事中务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。例如:在A事务中,查看另一B事务(正在修改张三的账户金额)中张三的账户金额,要查看到B事务之前的张三的账户金额,要么查看到B事务之后张三的账户金额。
(4)持久性(Durability):一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

MySQL中的事务
在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务中包含多条SQL语句,那么需要开启事务和结束事务。
开启事务:start transaction;
结束事务:commit(提交事务)或rollback(回滚事务)。
在执行SQL语句之前,先执行strat transaction,这就开启了一个事务(事务的起点),然后可以去执行多条SQL语句,最后要结束事务,commit表示提交,即事务中的多条SQL语句所做出的影响会持久化到数据库中。或者rollback,表示回滚,即回滚到事务的起点,之前做的所有操作都被撤消了!

事务并发读问题
多个事务对相同的数据同时进行操作,这叫做事务并发。
在事务并发时,如果没有采取必要的隔离措施,可能会导致各种并发问题,破坏数据的完整性等。这些问题中,其中有三类是读问题,分别是:脏读、不可重复读、幻读。
(1)脏读(dirty read):读到另一个事务的未提交更新数据,即读取到了脏数据;
例如:A给B转账100元但未提交事务,在B查询后,A做了回滚操作,那么B查询到了A未提交的数据,就称之为脏读。
(2)不可重复读(unrepeatable read):对同一记录的两次读取不一致,因为另一事务对该记录做了修改(是针对修改操作)
例如:在事务1中,前后两次查询A账户的金额,在两次查询之间,另一事物2对A账户的金额做了修改,此种情况可能会导致事务1中,前后两次查询的结果不一致。这就是不可重复度
(3)幻读(虚读)(phantom read):对同一张表的两次查询不一致,因为另一事务插入了一条记录(是针对插入或删除操作);

事务隔离级别
事务隔离级别分四个等级,在相同数据环境下,对数据执行相同的操作,设置不同的隔离级别,可能导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力也是不同的。
(1)、READ UNCOMMITTED(读未提交数据)—一般不使用此方法
可能出现任何事务并发问题
性能最好

(2)、READ COMMITTED(读已提交数据)(Oracle默认)
防止脏读,没有处理不可重复读,也没有处理幻读;
性能比REPEATABLE READ好

(3)、REPEATABLE READ(可重复读)(MySQL默认)
防止脏读和不可重复读,不能处理幻读问题;
性能比SERIALIZABLE好

(4)、SERIALIZABLE(串行化)
不会出现任何并发问题,因为它是对同一数据的访问是串行的,非并发访问的;
性能最差;

MySQL的默认隔离级别为REPEATABLE READ,即可以防止脏读和不可重复读

7、设置隔离级别

MySQL查询当前的事务隔离级别
select @@tx_isolation;

a、MySQL设置事务隔离级别
(1) set tx_isolation=‘read-uncommitted’; 
安全性最差,容易出现脏读、不可重复读、幻觉读,但性能最高
(2) set tx_isolation=‘read-committed’;
安全性一般,可防止脏读,但容易出现不可重复读、幻觉读
(3) set tx_isolation=‘repeatable-read’;
安全性较好,可防止脏读、不可重复读,但是容易出现幻读
(4) set tx_isolation=‘serialiable’;
安全性最好,可以防止一切事务并发问题,但是性能最差。

b、JDBC设置事务隔离界别
JDBC中通过Connection提供的方法设置事务隔离级别:
Connection. setTransactionIsolation(int level)
参数可选值如下:
Connection.TRANSACTION_READ_UNCOMMITTED 1(读未提交数据)
Connection.TRANSACTION_READ_COMMITTED 2(读已提交数据)
Connection.TRANSACTION_REPEATABLE_READ 4(可重复读)
Connection.TRANSACTION_SERIALIZABLE 8(串行化)
Connection.TRANSACTION_NONE 0(不使用事务)

提示:在开发中,一般情况下不需要修改事务隔离级别

版权声明:本文为CSDN博主「奋斗中的小码农」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44458228/article/details/86680365

你可能感兴趣的:(数据库,数据库事务,数据库基础,Mysql,数据库)