MYSQL基础

MYSQL基本操作

一、数据库简介

1.1 简介

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

数据库管理系统(Database Management System, 简称DBMS):指的是一种用来管理和操作数据的大型软件,用于建立、使用、维护数据,对数据库进行统一的管理和控制,以保证数据的完整性和安全性。用户可以通过数据库管理系统访问数据库中的数据。

数据库:存储、维护和管理数据的集合。

数据库管理系统:数据库软件,数据库是通过这些软件进行创建和操作的。

1.2 常见的数据库管理系统
  • Oracle:被认为是目前业界比较成功的关系型数据库的管理系统。Oracle可以运行在Windows、UNIX等主流的操作系统平台,完全支持所有的工业标准,并获得了最高级别的ISO标准安全性认证。
  • MySQL:是一种关系型数据库管理系统。由瑞典MySQL AB公司开发,目前属于Oracle旗下产品。MySQL是目前最流行的关系型数据库管理系统(RDBMS:Relational DBMS)之一。
  • SQLServer:是由微软推出的关系型数据库管理系统。
  • DB2:是IBM的
1.3 关系型数据库、非关系型数据库
  • 非关系型数据库:
    • 采用了没有特定关系模型来组织数据。
    • NOSQL基于键值对
  • 关系型数据库:
    • 依据所有存储数据的模型之间的关系建立的数据库。
    • 所谓关系模型,指的是“一对一、一对多、多对多”等关系模型

二、MySQL的安装与卸载

2.1 安装

如果在安装的过程中缺少依赖:https://www.microsoft.com/zh-cn/download/details.aspx?id=40784

2.2 卸载
  1. 控制面板 -> 程序 -> 卸载程序 -> 找到MySQLServer -> 右键 -> 卸载
  2. 打开C盘 -> 打开ProgramData文件夹 -> 删除MySQL文件夹
  3. 清除注册表信息:
    1. 打开注册表:win+r 输入:regedit
    2. HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\EventLog\Application\MySQL
    3. HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\EventLog\Application\MySQL
    4. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\MySQL
2.3 启动、停止MySQL服务
  1. 以管理员的身份运行命令行

    1. 开始菜单 -> windows系统 -> 命令提示符 -> 右键 -> 以管理员身份运行

    2. 输入指令:

      net start mysql57			// 开启服务
      net stop mysql57			// 停止服务
      
2.4 登录到数据库
  1. 打开命令行

  2. 输入指令:

    如果输入mysql提示“不是内部命令,也不是外部命令”,说明需要配置环境变量:

    1. 此电脑 -> 右键 -> 属性 -> 高级系统设置 -> 环境变量 -> 系统变量 -> Path
    2. 将MySQLServer安装路径下的bin配置进来
      1. C:\Program Files\MySQL\MySQLServer 5.7\bin
    1. mysql -u root -p				// 这种方式的登录,敲回车后需要输入密码
    2. mysql -uroot -p123456		// 将用户名和密码都写到指令中,注意:没有空格
    

SQL语言

SQL简介

SQL: Structure Query Language(结构化查询语言),SQL最早是被美国国家标准局(ANSI)确定为关系型数据库语言的美国标准。后来被国际化标准组织(ISO)采纳为关系型数据库语言的国际标准。

各种数据库厂商都支持ISO标准的SQL,类似于普通话。

各个数据库厂商在标准的基础上,定义了若干自己的扩展,类似于方言。

SQL是一种标准化的语言,允许你在数据库上进行操作,如:创建项目、查询内容、更新内容和删除内容等操作。

这些操作:Create、Read、Update、Delete,通常被称为 CRUD操作

1.SQL分类
  • DDL(Data Definition Language):数据定义语言,用来定义数据库对象(数据库、表、列)
  • DML(Data Manipulation Language):数据操作语言,用于定义数据库记录(数据)
  • DCL(Data Control Language):数据控制语言,用于定义访问权限和安全级别
  • DQL(Data Query Language):数据查询语言,用于查询记录(数据)

SQL语句大小写是不区分的。

CREATE / create / Create / CrEaTe

但是,一般情况下,我们会大写。

2.DDL使用(数据库)
  1. 创建数据库

    # 创建数据库
    CREATE DATABASE mydb1;
    # 创建数据库,并采用指定的字符集
    CREATE DATABASE mydb2 CHARACTER SET UTF8;
    
  2. 查看数据库

    # 查看当前数据库服务器中的所有的数据库
    SHOW DATABASES;
    # 查看创建数据库mydb1定义的信息
    SHOW CREATE DATABASE mydb1;
    
  3. 修改数据库

    # 将数据库mydb1的字符集修改为GBK
    ALTER DATABASE mydb1 CHARACTER SET GBK;
    
  4. 删除数据库

    DROP DATABASE mydb1;
    
  5. 其他操作

    # 切换当前使用的数据库
    USE mydb1;
    # 查询当前使用的数据库
    SELECT DATABASE();
    
3. DDL使用(表)

表:数据在数据库中的存储是以表的形式存在的。一个表中有若干个字段,将数据按照这些字段进行存储。

每一个字段在设计表的时候都要去指定类型:

int:整型

double:浮点型,例如double(5,2):表示最多有5位,其中必须有两位是小数,即最大值是 999.99

char:固定长度的字符串,例如char(5) : ‘aa’ 占5位

varchar:可变长度的字符串,例如varchar(5):‘aa’ 占2位

text:字符串类型

blob:字节类型

date:日期类型,格式是:yyyy-MM-dd

time:时间类型,格式为:hh:mm:ss

timestamp:时间戳类型,yyyy-MM-dd hh:mm:ss,会自动赋值

datetime:时间类型,yyyy-MM-dd hh:mm:ss

# DDL操作(表)
# 创建表格
CREATE TABLE t_users(name varchar(50), age INT, gender VARCHAR(10), height INT, weight INT);
# 删除表格
DROP TABLE t_users;
# 查看当前数据库中所有的表
SHOW TABLES;
# 查看创建一个表的信息
SHOW CREATE TABLE t_users;
# 查看一张表的字段信息
DESC t_users;
# 给一张表添加一个字段
ALTER TABLE t_users ADD score DOUBLE(5,2);
# 修改一张表的字段类型
ALTER TABLE t_users MODIFY score INT;
# 修改一张表的字段名
ALTER TABLE t_users CHANGE name uname VARCHAR(50);
# 修改一张表的字符集
ALTER TABLE t_users CHARA CTER SET GBK;
#修改表的名字
RENAME TABLE t_users TO t_new_user;
# 删除一张表中的字段
ALTER TABLE t_users DROP score;
4. DML

DML指的是对数据库中的数据进行增、删、改的操作。不要和DDL搞混了。

在SQL中,字符串类型和日期类型需要用单引号括起来

空值:null / NULL

1.插入数据

# 增:INSERT INTO
# 向表t_users插入一条数据,并且给每一个字段进行赋值,小括号中的是字段对应的值。要保证顺序。
INSERT INTO t_users VALUES('lily', 21, 'female', 172, 60);
INSERT INTO t_users VALUES('lucy', 21, 'female', 171, 60);
# 向表t_users插入一条数据,并且对部分字段进行赋值
INSERT INTO t_users (uname, age, gender) VALUES('JimGreen', 22, 'male');
# 向表t_users插入一条数据,并且对部分字段进行赋值,字段的顺序可以随意,但是要保证values后面的值要和前面的字段匹配
INSERT INTO t_users (age, gender, uname) VALUES(10, 'male', 'polly');

2.where

在进行数据删除、修改、查询的时候,可以使用where对数据进行一个过度。

= :相等比较(类似于Java中的==)

!= <> :表示不相等

< > >= <= :大小比较

BETWEN…AND…:在xxx和xxx之间

IN(set):在括号所有值之间取 /NOT IN

IS NULL /IS NOT NULL

AND、OR、NOT

3、删除数据

# 删除数据
DELETE FROM t_student;
# 按照条件进行删除 WHERE
DELETE FROM t_student WHERE sname = '韦一笑';
# 删除掉表中所有的数据(创建了一个新表)
TRUNCATE TABLE t_student;

DELETE 和 TRUNCATE

  1. delete删除表中的数据,表结构还在;删除的数据可以恢复。
  2. truncate是直接将表DROP掉,然后再按照原来的结构重新创建一张表。数据不可恢复。
  3. truncate删除效率比delete高。

4、修改数据

UPDATEset 字段=xx where 

DQL数据查询

DQL:数据库在执行DQL操作的时候,不会对数据造成修改。而是直接将查询后的结果集返回给客户端。查询的结果是一张虚拟的表。

关键字:SELECT

注意:在执行SQL的时候,后面可能跟上很多的限定。这些限定的顺序:

子句执行顺序from -> where -> group by -> having -> select -> order by

据此: 所以需要注意 as 别名的使用位置,不能先使用后声明

1 基础查询
# * :所有列
select * from *
2 模糊查询
# '_':通配符,表示一位
# '%':通配符,表示若干位
# 关键字:LIKE
3 字段控制查询

1.去重,去除重复记录,关键字:DISTINCT

# 去除两个列都相同的字段
select distinct xx,yy from 

2.常见计算

#只有数值类型可以做相加
#NULL值和其他数值做运算,结果还是NULL
#IFNULL(colum,defaultValue)
#如果指定的Colum列的值是NULL,则按照defaultValue进行计算处理

3.列别名 AS

AS 是可以省略的

4.查询结果排序 ORDER BY

# 查询结果排序
# ASC 升序(可以省略的)
# DESC 降序
# 默认是按照升序排序的
# 查询结果按照score_java做降序,如果score_java相同,再按照score_hadoop做升序
SELECT sname, score_java, score_hadoop FROM t_student ORDER BY score_java DESC, score_hadoop ASC;

5.聚合函数

聚合函数的特点

1.每个组函数接收一个参数(字段名或者表达式) 统计结果中默认忽略字段为NULL的记录

2.要想列值为NULL的行也参与组函数的计算,必须使用IFNULL函数对NULL值做转换。

3.不允许出现嵌套 比如sum(max(xx))

聚合函数无法用在where子句中 , 聚合函数包括count avg sum min max

# 聚合函数是用来做纵向计算的函数
# COUNT():统计个数
# COUNT(xx or null): 不会统计NULL值(其余都会+1)
# MAX():求最大值
# MIN():求最小值
# AVG():求平均值
# SUM():求和

6.分组 GROUP BY

# HAVING:对数据做一个简单的约束(限制),类似于where
# 查询Java平均成绩 > 75 的组号和平均成绩
SELECT groupid, AVG(score_java) FROM t_student GROUP BY groupid HAVING AVG(score_java) > 75;

HAVING 和 WHERE的区别:

  1. HAVING后面可以写聚合函数、WHERE后面是不可以写聚合函数的。

  2. HAVNIG是对分组后的数据做的过滤、WHERE是对分组前的数据做的过滤。

    1. WHERE对分组前的数据做过滤。如果没有满足WHERE条件过滤的数据,将不参加分组。
    2. HAVING是分组后的数据做过滤。

7.分页 LIMIT

分页可以分为:假分页(逻辑分页)、真分页(物理分页)

  • 假分页:
    • 可以将表中的数据一次性全部读取出来,存到一个集合中。可以自己设计程序,每次从这个集合中取指定部分的元素。
    • 优点:效率高
    • 缺点:如果表中的数据量过大,可能会造成内存溢出
  • 真分页:
    • 每次从表中查询指定数量的数据。
LIMIT 0, 1000:
# 第一个参数0: 从哪一条数据开始查询
# 第二个参数1000: 每次查询多少数据(相当于一个分页中有多少数据)

数据的完整性

在创建表的时候对某些字段进行约束,确保数据的完整性。

保证用户输入的数据添加到数据库中的时候是正确的。

  • 实体完整性
  • 域完整性
  • 引用完整性
1 实体完整性

实体:表中的每一行数据,代表一个实体(Entity)

实体完整性:标识每一行数据不重复。

约束:

主键约束(primary key)

唯一约束(unique)

自增约束(auto_increment)

主键约束

主键:可以将表中的某些键设置为主键。

特点:不允许重复,且不能是NULL值。

用途:可以使用主键,作为一个实体(一条数据)的唯一标识。

一般情况下,一张表中是需要有主键的。主键的数量:如果没有什么特殊需求,一个就可以。

# 设置主键
# 1. 在建表的时候,设置某一个键为主键
CREATE TABLE t_class (
		id int PRIMARY KEY,
		cname	VARCHAR(20)	
);
CREATE TABLE t_class(
		id INT,
		cname	VARCHAR(20),
		PRIMARY KEY(id,cname)
);
# 2. 给一个已经创建好的表添加主键(这个键是一个已经存在的键)
ALTER TABLE t_class ADD PRIMARY KEY(id);

唯一约束

数据不允许重复,但是可以是NULL

在创建表的时候,用关键字 UNIQUE 来修饰

# 设置唯一约束unique
CREATE TABLE t_class(
	id INT PRIMARY KEY,
	cname VARCHAR(20) UNIQUE
);

自增约束

自动增长 AUTO_INCREMENT

*如果使用auto_increment设置自增字段,没有与主键约束一同使用,则使用auto_increment的字段必须添加索引,否则创建数据表会出错*

CREATE TABLE t_class(
	id INT PRIMARY KEY AUTO_INCREMENT,
);
2 域完整性

限制单元格内容的正确性

数据类型、非空约束、默认值约束

非空约束

NOT NULL

CREATE TABLE t_teacher(
	gender VARCHAR(10) NOT NULL
);

默认值约束

修饰某一个字段的值有一个默认值

# 默认值约束
CREATE TABLE t_teacher(
	gender VARCHAR(10) DEFAULT 'male'
);
CREATE TABLE t_teacher(
	gender VARCHAR(10) NOT NULL DEFAULT 'male'
);

3 引用完整性

参考完整性

将多一方(student)表中的用来维系关系的键,作为外键(forigen key)

外键约束:FOREIGN KEY

约束外键列的值,只能在另外的一张关联的表中进行设置

设置外键约束需要注意:

查看一张表的存储引擎,如果希望某张表支持外键,则需要将存储引擎设置为 InnoDB

MyISAM: 也是一种存储引擎,采用这种存储引擎的表,存取效率高,但是不支持事物和外键

ALTER TABLE 表名 ENGINE = 'InnoDB';

SQL 添加外键

# 设计一个表,并设置一个外键
# 外键:class_id
# 关联表:t_class
# 关联字段:id
CREATE TABLE t_stu(
	id INT PRIMARY KEY,
	class_id INT,	# 外键的类型一定要和关联表中的关联字段类型相同
	CONSTRAINT fk_class_id FOREIGN KEY(class_id) REFERENCES t_class(id)
);

# 给一个已经创建好的表添加外键
ALTER TABLE t_stu ADD CONSTRAINT fk_class_id FOREIGN KEY(class_id) REFERENCES t_class(id);

多表查询

联合多个表中的数据进行数据查询。

1 多表的关系
  1. 一对一

    在实际开发中应用不多。因为一对一的关系,完全可以放到一个表中

  2. 一对多

    一对多建表原则:在多的一方,创建一个字段,作为外键作为指向另外一的那一方的主键。

  3. 多对多

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

2 多表查询
  1. 合并查询结果集

    作用:合并结果集就是把两个select到的结果集合并到一起

    注意事项:需要合并的两个结果集要求:列数和类型必须相同

    1. UNION:合并结果集,去重。
    2. UNION ALL:合并结果集,不去重。
    SELECT * FROM t_union_user1 UNION SELECT * FROM t_union_user2;
    SELECT * FROM t_union_user1 UNION ALL SELECT * FROM t_union_user2;
    
  2. 连接查询

    连接查询,就是求出多个表的乘积,例如 t1连接t2表,查询结果就是t1 * t2

    连接查询,一般情况下要查询的两张表之间是需要有关联的。

    连接查询会出现笛卡尔积:

    假设有两个 集合A{a, b} 和 集合B {0, 1, 2},

    这两个集合的笛卡尔积是 {(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}

    这样的话,这个查询结果很多的数据都不是我们想要的。所以我们要去除重复的或者无用的数据。通过条件过滤。

    1. 内连接

      查询两张表中都出现的数据(外键)

    2. 外连接

      特点:可能会出现不满足条件的数据

      1. 左外连接

        先查询出左表,再查询右表,将满足条件的数据列出,同时再列出左表中不满足条件的数据。

      2. 右外连接

        先查询出右表,再查询左表,将满足条件的数据列出,同时再列出右表中不满足条件的数据。

# 连接查询
# 查询两张表中所有的数据
# 这种查询就是一个内连接(但是这种语法是MySQL单独为自己设计的语法,方言)
SELECT * FROM t_student, t_class WHERE t_student.cid = t_class.id;
SELECT sname, t_student.sage, t_student.sgender, t_class.cname FROM t_student, t_class WHERE t_student.cid = t_class.id;

# 内连接标准SQL
# INNER可以省略
SELECT * FROM t_student INNER JOIN t_class ON t_student.cid = t_class.id;
SELECT * FROM t_student JOIN t_class ON t_student.cid = t_class.id;
SELECT * 
	FROM t_student stu 
	JOIN t_class cls 
	ON stu.cid = cls.id
	where stu.xxx= cls.xxx;


# 外连接
# OUTER 也可以省略
SELECT * 
	FROM t_student stu
	LEFT OUTER JOIN t_class cls
	ON stu.cid = cls.id;

SELECT *
	FROM t_student stu
	RIGHT JOIN t_class cls
	ON stu.cid = cls.id;

子查询

子查询就是一个嵌套查询。就是一个SELECT语句中嵌套另外一个SELECT。

select xxx from xxx where xxx 关系运算 (select xxx from xxx )

CASE-WHEN

可以做一些简单的分支逻辑,类似于if-else和switch-case

select xxx,
CASE      #相当于if
		WHEN xxxx
		THEN xxx
END AS xxx
from xxx

select xxx,
CASE  xxxx    #相当于switch
	WHEN 1 THEN xxx
END AS xxx
from xxx


# 行转列
# group  by 只取分组后的第一条数据展示
# 先执行group by 再执行聚合函数
# 分组函数一定和聚合函数一同存在
SELECT sname, 
SUM(CASE subject WHEN '语文' THEN score ELSE 0 END) AS '语文成绩',
SUM(CASE subject WHEN '数学' THEN score ELSE 0 END) AS '数学成绩',
FROM t_scores GROUP BY sname;

SELECT sname, 
SUM(IF(subject = '语文', score, 0)) AS '语文成绩',
SUM(IF(subject = '数学', score, 0)) AS '数学成绩',
FROM t_scores GROUP BY sname;

JDBC

第一个JDBC程序

JDBC:Java Database Connectivity

JAVA中的数据库连接,是用来连接各种数据库的中间件。

由于市面上的数据库管理系统(DBMS)种类繁多,如果我们的程序需要和多种数据库进行交互,则需要设计多套逻辑来进行处理。这多套逻辑之间有很大一部分是重叠的,而且还需要针对不同的数据库进行分别处理。程序设计就会很繁琐。于是JDBC就诞生了。

JDBC是一套访问数据库规范,让不同的数据库厂商去实现这些规范即可。对于我们写程序来说,就不用再针对不同的数据库进行区分处理,直接使用JDBC的API即可。

1 使用JDBC的基本步骤
  1. 注册驱动
  2. 建立连接
  3. 创建Statement
  4. 执行SQL,得到结果集
  5. 处理结果集中的数据
  6. 释放资源
2 通用JDBC组件
  1. DriverManager:用来管理数据库驱动程序列表。
  2. Driver:驱动对象。
  3. Connection:程序与数据库的连接对象。
  4. Statement:用来执行SQL语句。
  5. ResultSet:SQL执行结束后的结果集。
  6. SQLException:在执行数据库操作的过程中遇到的异常。
3 第一个JDBC程序

创建项目,导入jar包,在jar包上右键,BuildPath -> Add to BuildPath

注册驱动

// 1. 注册驱动
// registerDriver方法的参数是一个java.sql.Driver接口,所以我们要传一个实现类对象
// com.mysql.jdbc.Driver这个类对象才是我们需要的参数
// DriverManager.registerDriver(new com.mysql.jdbc.Driver);

// 因为在com.mysql.jdbc.Driver类中的静态代码段中已经实现了注册,所以我们不需要重复注册
// 只需要去触发静态代码段即可
Class.forName("com.mysql.jdbc.Driver");

建立连接

// 2. 建立连接
// url: 连接到指定的数据库路径
// jdbc:mysql://主机名(数据库所在的机器IP,名字):端口号/数据库名字
// user: 登录用户名
// password: 密码
// Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/数据库名", "root", "123456");
// 将数据库路径与用户名、密码都封装到一个url中
String url="jdbc:mysql://localhost:3306/数据库名?user=用户名&password=密码"
conn = DriverManager.getConnection(url);

创建Statement对象

//静态SQL的语句
Statement st=coon.createStatement();

执行SQL,得到结果

// 4. 执行SQL语句
// executeUpdate(String sql): 执行一个DDL、DML语句,并返回这个操作影响的行数 int
// executeQuery(String sql): 执行一个DQL语句,并返回一个ResultSet

处理结果集中的数据

// 5. 处理这些数据
while (set.next()) {//一条条查询,没有数据就返回false
    //得到的结果可以用列序号获取,也可以用列名(字段名)来获取
    //返回的数据对类型没有强制要求
	int id = set.getInt(1);  
	String name = set.getString("sname");
}

释放资源

// 6. 释放资源
// 需要释放的资源有:ResultSet、Statement、Connection
//按ResultSet、Statement、Connection 的顺序依次释放
	set.close();
	st.close();
	conn.close();

DAO层设计

程序设计最基本原则:

1.可复用性。减少程序中的重复代码。

2.可扩展性。当需要添加功能的时候,只需要在现有的架构上添加模块即可,不需要对现有的代码进行改动

3.可维护性。当需求变更的时候,能够用最少的改动实现效果。

高内聚,低耦合

DAO:数据访问模型(Data Access Object),用来访问数据库的。用来数据库中的数据存取。

DAO包的设计:

设计规范:

DAO包是由DAO接口和DAO 实现类和描述类组成(开发中还有一个测试类)

命名规范:

公司域名倒写.项目名称.DAO:主包

.domain 存放描述类

.dao dao接口

.dao.imp dao实现类

.dao.test 测试类

关于dao接口命名规范:

  1. I开头,以DAO做结尾
  2. 中间写domain描述类

优化

使用 properties

private static Properties pro = new Properties();
// 使用ClassLoader来加载一个Properties里面的数据
// 1. 创建ClassLoader对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
		// 2. 获取用于操作某个文件的字节流对象
InputStream in = loader.getResourceAsStream("db.properties");
		// 3. 加载数据
pro.load(in);
Class.forName(pro.getProperty("driverName"));

预编译语句 PreparedStatement:

优点:

  1. 使用预编译语句,可以提高代码的可读性。
  2. 最大的好处:还可以提高性能!(预编译)
    1. MYSQL不支持!Oracle是支持的!
  3. 保证安全
// 提供一个“模板”, 用?做占位, 在实际使用的时候, 需要先对占位的部分进行赋值。
PreparedStatement ps = conn.prepareStatement(sql);
// 给占位赋值(注意类型)
ps.setInt(1, 10);
ps.setString(2, "Uncle wang");
ps.setString(3, "男");
ps.close();

批处理操作

可以将多条SQL语句分组到一个批处理中,同时去执行这多条SQL。

  • 获取Statement对象

  • 将自动提交关闭

    conn.setAutoCommit(false);
    
  • 使用addBatch()方法将需要执行的SQL添加进来

    st.addBatch("insert into t_teacher values (3, '郭靖', '男')");
    
  • 使用executeBatch()处理所有的SQL

    int[] rows = st.executeBatch();
    
  • 最后使用commit()方法进行提交

    conn.commit();
    

事务

是数据库操作的一个执行单元。一组要么同时执行成功,要么同时执行失败的SQL语句。

1 事务的特点(ACID)
  1. atomtity(原子性)
    1. 表示一个事务内的所有操作是一个整体。要么全部成功,要么全部失败。
  2. consistency(一致性)
    1. 表示一个事务中有一个操作失败,所有更改过的操作都必须回滚到操作之前的状态。
  3. isolatioin(隔离性)
    1. 事务在查看数据的状态。要么查询到的是一个事务执行之前的状态,要么是一个事务执行之后的状态。不会查询到一个事务执行过程中的状态。
  4. durability(持久性)
    1. 持久性事务执行完成后,对系统的影响是持久的。
2 事务的隔离级别

SQL 定义了四类标准的隔离级别

  1. 读取未提交内容(Read Uncommitted):
    1. 在开发中使用的极少。读取未提交的内容:脏读(Dirty Read)
  2. 读取提交内容(Read Committed):
    1. 绝大部分的数据库的默认的隔离级别。(MySQL不是)。一个事务只能看到已提交的事务所做的改动。
  3. 可重复读(Repeatable Read)
    1. 是MySQL默认的隔离级别
  4. 可串行化(Serializable)
3 Java中的事务

首先需要将Connection的自动提交功能关闭

Savepoints:保存点

Connection:

setSavepoint(String savePointName):定义一个保存点,并设置一个名字,返回一个Savepoint对象

releaseSavepoint(Savepoint savePointName):删除一个保存点

事务开始于

  1. 连接到指定的数据库,并执行一条DML语句(insert、update、delete)
  2. 前一个事务已经结束,此时又执行一条DML语句

事务结束于

  1. 执行commit或者rollback语句
  2. 执行一条DDL语句,例如:建表。此时会自动执行一个commit
  3. 断开与数据库的连接

连接池

去操作数据库的时候,我们使用到一个Connection对象,如果使用传统的JDBC操作方式,每次进行操作的时候都需要创建一个新的连接,创建Connection的过程,非常消耗性能和时间的过程,所以会带来不必要的性能损耗和时间损耗。为了解决这个问题,我们引入一个”池子“的概念。如果需要Connection对象的时候,直接从这个池子中去获取。当不用这个Connection的时候,不是将其释放,而是放到池子中,等待下次继续使用。实现一个Connection对象的复用。

1 自定义连接池

属性:集合,存储Connection对象

方法:获取连接对象、

// 1. 判断复用池中有没有Connection对象
if (list.size() > 0) {
	// 2. 说明此时连接池中是有Connection对象
	// 3. 从池子中取出一个对象返回即可
	return list.removeFirst();
}
// 如果此时池子中没有连接对象
// 理论上需要做一个等待时间:在等待时间内,如果有Connection归还,可以直接获取。如果等待超时,则直接创建一个新的Connection对象返回
// 不去模拟等待时长,直接返回一个新的
return JDBCUtil.getConnection();

归还连接对象

// 1. 判断池子的容量是不是达到了最大值
if (list.size() >= capcity) {
// 说明池子已经存满了,这个conn直接释放即可,不用添加到池子中
try {
	conn.close();
} catch (SQLException e) {
	e.printStackTrace();
}
}
else {
// 说明复用池还不满,此时将归还的conn添加到集合中即可
		list.add(conn);
	}
2 DBCP

Database Connection Pool(数据库连接池),是apache上的一个Java连接池项目。

// 1. 实例化一个连接池对象
BasicDataSource ds = new BasicDataSource();
// 2. 设置连接信息
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/mydb1");
ds.setUsername("root");
ds.setPassword("123456");
// 设置最大连接数
ds.setMaxActive(20);
// 3. 获取连接
Connection conn = ds.getConnection();
// 在ds.getConnection()方法中返回的是一个DBCP中已经做好的Connection接口的实现类对象
// 在这个Connection接口的实现类中,已经对close做了一个复用的操作。
conn.close();

DataSource: 是一个接口,定义了几个用来做连接池的规范

需要使用到jar包:

  • jdbc.jar
  • commans-dbcp.jar
  • commans-pool.jar
3 c3p0

C3P0是一个开源的JDBC连接池。

和DBCP的区别:

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

  2. DBCP不需要手动设置配置文件,C3P0需要手动设置配置文件。(source 下创建 c3p0-config.xml文件)

    <!-- C3P0中,关于数据库连接的配置 -->
    <!-- 
    
    driverClass: 驱动类名
    jdbcUrl: 数据库路径
    user: 用户名
    password: 密码
    
    initialPoolSize : 实例化的时候连接池中的连接数量
    maxPoolSize : 最大连接数量
    
     -->
    
    <c3p0-config>
    	<default-config>
    		<property name="driverClass">com.mysql.jdbc.Driver</property>
    		<property name="jdbcUrl">jdbc:mysql://localhost:3306/mydb1</property>
    		<property name="user">root</property>
    		<property name="password">123456</property>
    		<property name="initialPoolSize">10</property>
    	</default-config>
    </c3p0-config>
    
ComboPooledDataSource ds = new ComboPooledDataSource();
// 获取连接
Connection conn = ds.getConnection();
Statement st = conn.createStatement();

需要使用到jar包:

  • jdbc.jar
  • c3p0.jar

关于配置文件:

  • 是一个xml文件:c3p0-config.xml
  • 这个文件需要放到source下面
4 Druid(阿里巴巴)

使用比较流行的。

DruidDataSource ds = new DruidDataSource();

需要使用到jar包:

  • jdbc.jar
  • druid.jar

DBUtils

是apache上的一个开源项目,是对JDBC进行了一个简单的封装。可以使用这个工具类来用简洁的代码实现数据库的操作,并且不影响性能。

需要类库:

  • jdbc.jar
  • dbutils.jar
  • c3p0.jar
//通过创建C3P0Utils获取一个DataSource连接池
//ds=C3P0Utils.getDataSource()
QueryRunner runner = new QueryRunner(DataSource ds);
// 指定查询语句的时候:
runner.query(String sql, ResultSetHandler handler);
// ResultSetHandler:
// org.apache.commons.dbutils.handlers;
// BeanHandler:	将ResultSet中的第一行数据转成一个数据模型(类的对象)
// BeanListHandler: 将ResultSet中的所有的数据每一行都转成一个数据模型,然后存入一个集合中。
// ArrayHandler: 将ResultSet中的第一行数据转成一个对象数组
// ArrayListHandler: 将ResultSet中的所有的数据每一行都转成一个对象数组,然后存入一个集合中。

// MapHandler :将ResultSet中第一行的数据存成Map映射
// MapListHandler :将ResultSet中所有的数据存成List。List中存放的是Map
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值