数据库基础知识-----数据库、SQL语言、JDBC、连接池、事物笔记整理

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

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

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

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

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

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

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

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

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

三、JDBC 概述

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

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

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

  3. 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();
    执行结果:
    .在这里插入图片描述

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

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

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

四、连接池概述

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

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

使用连接池操作数据库:

在这里插入图片描述

  1. 开源数据库连接池-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文件, 配置内容如下:

<?xml version="1.0" encoding="UTF-8"?> com.mysql.jdbc.Driver jdbc:mysql:///jt_db?useUnicode=true&characterEncoding=utf-8 root root

五、事物介绍

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

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

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

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

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

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

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

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

  1. 设置隔离级别
    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(不使用事务)
    提示:在开发中,一般情况下不需要修改事务隔离级别

猜你喜欢

转载自blog.csdn.net/weixin_44458228/article/details/86680365