文章目录
前言
内容主要是MySQL 数据库的基本知识,以及Java中对其的基本使用和操作 (JDBC)
一、了解MySQL
1.1数据库分类
关系型数据库:(SQL)
MySQL,Oracle,Sql Server, DB2 , SQL lite
通过表和表之间,列和列 之间的关系进行数据的存储。学生信息表,考勤表等等。
非关系型数据库:(no SQL)
Redis ,MongDB
非关系型数据库,对象存储通过对象自身的属性来决定。
DBMS(数据库管理系统)
MySQL,一个数据库管理系统
安装方式:可以直接去MySQL官网下载exe文件。但个人建议下载压缩包进行安装,exe文件安装之后卸载较为麻烦。
压缩包下载地址: https://dev.mysql.com/downloads/mysql/5.5.html#downloads
具体安装教程可以参考下面这篇朋友的博客,个人感觉比较清楚。
https://blog.csdn.net/weixin_43605266/article/details/110477391
二、初识MySQL
2.1常用命令
所有语句都要有;结尾
数据库语言:
DDL:定义
DML:管理
DQL:查询
DCL:控制
连接数据库 : mysql -u账号 -p密码
修改密码: alter user ‘root’@‘localhost’ identified with mysql_native_password by ’ 这里填写新密码 ';
创建一个数据库 :create database xxx;
查询所有数据库:show databases
切换数据库: use xxx
查看数据库中所有的表:show tables
显示数据库中所有的表的信息:describe xxx
退出连接:exit
单行注释:–
多行注释:/* */
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
三.操作数据库
3.1操作类型
操作数据库
create database [if not exists] xxx;
drop database [if not exists] xxx;
use xxx
show databases
注意:如果字段或者名字是关键字就用~ ~。
操作数据库中的表
create table if not exists xxx(
id int(4) not null auto_increment comment 学号,
name
)
操作数据库中表的数据
3.2数据库的列类型
数值:
tinyint 一个字节
smallint 2
mediumint 3
int 4
big 8
float 4
double 8
decimal 字符串形式的浮点数 金融计算的时候使用
字符串:
char 固定大小的0-255
varchar 可变字符串 0-65535 常用
tinytext 微型文本 2^8-1
text 文本串 2^16-1 用来保存文本
时间日期:
date YYYY-MM-DD 日期
time HH:MM:SS 时间
datetime YYYY-MM-DD HH:MM:SS 最常用时间格式
timestamp 时间戳 1970.1.1 到现在的毫秒数
null
3.3数据库的字段类型
Unsigned:无符号的整数,不能声明为负数
zerofill:不足位数使用0填充。 如5——005
自增:必须是整数,通常用在主键上。可以设置起始站和步长。
null not null :非空
default :默认值
拓展:
每一个表必须存在的五个字段:
id :主键
version 乐观锁
is_delete 伪删除
gmt_create 创建时间
gmt_update 修改时间
CREATE TABLE `student` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '密码',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb3
3.4常用命令:
SHOW CREATE DATABASE test; 查看创建表的语句
SHOW CREATE TABLE student;
DESC student;
修改删除表
操作
增加,修改
修改表名
ALTER TABLE student RENAME AS teacher;
增加表的字段
ALTER TABLE teacher ADD age INT(11);
修改表的字段
ALTER TABLE teacher MODIFY age VARCHAR(11); 修改约束
ALTER TABLE teacher CHANGE age age1 INT(11); 字段重命名且可以修改约束
删除
删除表
DROP TABLE IF EXISTS student;
四. MySQL数据管理
4.1外键(了解)
删除有外键关系的表的时候,需要把引用该表作为外键的表先删除。
创建外键的方式:
一、在创建表的时候
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号',
`name` VARCHAR(30) NOT NULL COMMENT '姓名',
`gradeid` INT(10) NOT NULL COMMENT '学生年级',
PRIMARY KEY(`id`),
KEY `FK_gradeid` (`gradeid`),
CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
二、创建表成功后,添加外键
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`);
4.2 DML语义(全部记住)
添加插入语句
INSERT INTO `mygrade`(`grade`) VALUES('大三'),('大四');
INSERT INTO `student`(`name`,`id`) VALUES('zzk','01'),
(上面是一次插入两行记录)
修改:
update ·表名· set ·字段·=xxxx where id= xxx;
***注意:如果不限定条件,则会把所有行的该字段都修改。 ***
删除:
delete命令
truncate :清空表。
delete from 表名 where id=1;
4.3 DQL查询数据(重重点)
4.3.1DQL:数据查询语言
查询所有字段:select * from student;
查询指定字段,并赋予别名:
select studentnm as 学号 ,studentname as 姓名 from student;
拼接函数:concat(a,b)
select concat(‘姓名’,srudentname) as 新名字 from student;
去重: distinct
select distinct studentname from result;
select 100*2-1 as 计算结果;
数据库中的表达式:文本值,列,null,函数,计算表达式,系统变量。。。
select 表达式 form 表;
where 条件子句:
逻辑运算符:
模糊查询:
like
% 表示任意个字符,_ 表示一个字符
SELECT * FROM student WHERE name
LIKE ‘刘%’;
SELECT * FROM student WHERE name
LIKE ‘刘_’;
SELECT * FROM student WHERE name
LIKE ‘刘__’;
SELECT * FROM student WHERE name
LIKE ‘%刘%’;
in
SELECT * FROM student WHERE name
IN (‘刘备’);
连表查询
INNER JOIN:内连接,也可以只写JOIN。只有进行连接的两个表中,都存在与连接标准相匹配的数据才会被保留下来,相当于两个表的交集。如果前后连接同一张表,也叫自连接。
LEFT JOIN: 左连接,也称左外连接。操作符左边表中符合 WHERE 子句的所有记录将会被返回,操作符右边表中如果没有符合 ON 后面连接条件的记录时,那么从右边表指定选择的列的值将会是 NULL。
RIGHT JOIN: 右连接,也称右外连接。会返回右边表所有符合 WHERE 语句的记录。左表中匹配不上的宇段值用 NULL 代替。
**FULL JOIN:**全连接,返回所有表中符合 WHERE 语句条件的所有记录。如果任一表的指定宇段没有符合条件的值的话,那么就使用 NULL 替代。
select s.studentnum,s.studentname,subjectname,grades
freom result as r
left join student as s
on r.studentnum = s.studentnum
left jion grade as g
on r.subjectno = g.subjectno
4.3.2 自连接
自己的表和自己的表连接,其实就是拿两张一样的表进行连接操作
SELECT a.categoryname AS '父栏目' ,b.categoryname AS '子栏目'
FROM category a,actegory b
WHERE a.categoryid = b.pid
自连接大多数情况就是一个表当中的某几个属性之间存在一定的关系,想根据自己表里面的两个不同属性之间的关系查出一个新的数据集。
4.3.3 分页和排序
limit(起始值,页面大小)
order by 字段名 desc/asc
desc :降序
asc :升序
4.3.4 子查询
子查询可以将上面的连表查询进行分解。select 查询是一个由里及外的查询过程。
select s.studentno,studentname
from student s
inner join result r
on s.studentno = r.studentno
inner join subject sub
on r.subjectno = sub.subjectno
where subjectname = '高等数学' and studentresult >=80
转化为子查询后:
select distinct s.studentno,studentname
from student s
inner join result r
on r.studentno = s.student.no
where studentresult>80 and subjectnpo = (
select subjectno from subject
where subjectname = '高等数学'
)
五. 常用函数:
分组和过滤:
如果是在select语句中单纯的使用聚会函数。则无论该表格有多少行,最终都只会返回一行数据。
SELECT id,SUM(`gradeid`),AVG(`gradeid`),MIN(`gradeid`)
FROM student
如果指定了分组,则会按分组进行计算和显示
SELECT `id`,`name`,SUM(`gradeid`),AVG(`gradeid`),MIN(`gradeid`)
FROM student
GROUP BY `name`
数据库级别的MD5加密
MD5(‘123456’)
六. 事务
事务中的sql语句要么都成功,要么都失败。
事务原则:ACID
A:原子性
C:一致性
I:持久性
D:隔离性
手动处理事务:
事务开启:start transaction (标记一个事务开启,接下来的sql语句都属于该事务)
事务提交:commit (持久化,成功)
回滚 :rollback (回到原来的样子,失败!)
了解:保存点 savepoint --设置一个事务的保存点
rollback to savepoint --回滚到保存点
release savepoint --删除保存点
七. 索引
索引分类:
主键索引:primary key,主键的值不能重复,且一个表只能一个索引。
唯一索引:unique key,唯一索引的值可以有多个,但一个表可以声明多个。
常规索引:key/index 默认的
全文索引:full text 快速定位数据
索引原则
索引不是越多越好
不要对经常变动的数据加索引
小数据量的尽量不要加索引
索引一般用在查询的字段上
八.权限管理和备份
8.1用户管理
8.2 数据库备份
方式:
1:拷贝物理文件
2:在可视化工具中手动导出
3:使用命令行导出
导出:
mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql
导入:
source d:/a.sql
九. 数据库规范设计
当数据库比较复杂的时候,就需要就行设计的。
糟糕的数据库设计:
数据冗余,浪费空间
插入删除麻烦(尽量少使用物理外键)
良好的数据库设计:
节省内存空间
保证数据库完整性
方便开发
三大范式
第一范式:保证每一列的内容都不可再分。
第二范式:满足第一范式的前提下,保证每张表只描述一件事情。
第三范式:在满足第二范式的基础上,确保每条表中中的数据都和主键直接相关,而不是间接相关。
了解:
十. JDBC(重点)
10.1 数据库驱动
Java程序通过驱动和数据库连接。
10.2 JADC
JAVA 对所有数据库操作的统一规范,检查JABC
具体规范操作由各大厂商自己实现。
10.3 第一个JDBC程序
1.创建普通项目
步骤:
1:加载驱动。
2:连接数据库DriveManager。
3: 获得执行sql的对象Staterment。
4:获取返回的结果集。
5:释放连接。
//1.加载驱动。//固定写法,加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.用户信息和url
//useUnicode=true&characterEncoding=utf8&useSSL=false
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";
String username = "root";
String password = "123456";
//3.连接成功,数据库对象 Connection 代表数据库
Connection connection = DriverManager.getConnection(url,username,password);
//4.执行sql语句,需要使用Statement对象进行操作
Statement statement =connection.createStatement();
//5.使用对象进行相应操作
String sql ="SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println("id:"+resultSet.getObject("id"));
System.out.println("name:"+resultSet.getObject("name"));
System.out.println("pwd:"+resultSet.getObject("password"));
}
//6.释放连接
resultSet.close();
statement.close();
connection.close();
10.4 SQL 注入的问题(拼接字符串技巧)
对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作。
例如:当where筛选条件是 where id = [变量]时。攻击者直接在传入的变量后面加一个 or 1=1。这样判断条件就恒等于了,就可以直接筛查所有的 id的数据。 where id = 123 or (1=1)。
10.5 PreparedStatement 对象
是Staterment 的子类,在Staterment上面做了进一步的拓展。其执行效率更高,且可以防止SQL 注入的问题。
可以考虑写一个utils工具类,这样加载驱动,连接数据库,和关闭加载的对象。这样重复的操作直接调用方法就行了。
//可以建一个参数配置文件,专门用来保存各种变量
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username = root
password = 123456
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try{
InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(inputStream);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
// 1.驱动只用加载一次就行
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @return Connection
* @introduce 连接数据库
*/
public static Connection connection() throws SQLException {
Connection connection = DriverManager.getConnection(url,username,password);
return connection;
};
public static void release(Connection connection, Statement statement, ResultSet resultSet){
if (resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
};
if (statement != null){
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
};
if (connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
};
}
}
//一个使用PreparedStatement 对象完成查询操作的实例。
public class PreparedTest {
public static void main(String[] args) throws SQLException {
//1.加载驱动。2.完成数据库连接.
Connection connection = JdbcUtils.connection();
//3.定义SQL语句
String sql ="select * from users where id = ?";
//4.创建数据库操作对象,并先传入sql语句进行初始化
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.给刚刚sql中的占位符传具体的值
preparedStatement.setInt(1,1);
//6.用preparedStatement对象执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){
System.out.println(resultSet.getString("NAME"));
}
}
}
10.6 Idea 使用JDBC
连接成功后可以选择数据库
修改完数据后记得提交:
小tips:
事务:
回顾:
原子性:要么全部完成,要么都不完成。
一致性:总数不变
**隔离性:**多个进程互不干扰
持久性:事务一旦提交就不可逆,不可再回滚。持久化到了数据库
隔离性的问题(重点):
脏读:一个事务读取了另一个没有提交的事务。
不可重复读:在同一个事务内,重复读取表中的数据,表中的数据发生了改变。
虚度(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来结果不一致。
事务的代码实现步骤:
1:开启事务: Connection.setAutoCommit(false);
2: 一组业务执行完毕,提交事务。(commit)
3:可以在catch语句中显示的声明回滚。(但其实就算不声明,事务执行失败的话系统也会默认回滚)
10.7 数据库连接池
准备一些预先的资源,我们可以直接使用这个操作对象,不需要有数据库连接的步骤。
常用连接数
最小连接数
最大连接数(业务最高承载上限)
排队等待
等待超时
开发数据源实现
DBCP
C3P0
Druid:阿里巴巴
使用数据库连接池需要操作的步骤:
1.导入数据源包
2.创建一个配置文件Properties ,添加相应配置。
3.加在配置文件流,获取数据源和连接对象。
//参考
public class Demo05Druid {
public static void main(String[] args) throws Exception {
// Properties extends Hashtable<Object,Object> 实现了HaseTable接口,可以用来读取一些配置文件
Properties properties = new Properties();
// 不要通过具体路径去读,把配置文件当成有个资源getResourceAsStream
InputStream is = Demo05Druid.class.getClassLoader().getResourceAsStream("jdbc2.properties");
// load 函数的输入是一个流
properties.load(is);
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
for(int i = 0 ; i<10 ; i++){
Connection conn1 = dataSource.getConnection();
System.out.println(i+"-------->"+conn1);
// 注意有close和没有close的区别
// conn1.close();
}
}
配置文件:利用DruidDataSourceFactory.createDataSource创建连接池时,配置项名称必须和官方文档保持一致。
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/fruitdb?useSSL=false&useUnicode=true&characterEncoding=utf-8
username=root
password=123456
initialSize=2
maxActive=5
maxWait=5000
总结
JAVA 数据库的学习内容其实大备份都在学数据库的相关知识,如果有数据库基础来学Java操作数据库的话其实很快。主要是就是JDBC ,看看Java是怎么连接数据库,用什么对象对数据库中的表进行sql操作的。
最后大家能看到这的也是不容易,哈哈。希望大家都能进大厂,成大佬。
zzk