学习JavaWebDAY5-参考黑马程序员
-
数据库:DataBase,存储和管理数据的仓库
-
数据库管理系统DBMS DataBase Management System,操纵和管理数据库的大型软件
-
SQL,操作关系型数据库的编程语言,定义了一套操作关系型数据库的统一标准
MySQL
下载地址:MySQL :: Download MySQL Community Server
数据模型
关系型数据库:建立在关系模型基础上,由多张相互连接的二维表组成的数据库
特点:使用表存储数据,格式统一,便于维护;使用SQL语言操作,标准统一,使用方便,可用于复杂查询
MySQL语句
| 分类 | 全称 | 说明 |
|---|---|---|
| DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库、表、字段) |
| DML | Data Manipulation Language | 数据操作语言,用来对数据库表中的数据进行增删改 |
| DQL | Data Query Language | 数据查询语言,用来查询数据库中表的记录 |
| DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
DDL
-
查询所有数据库
-
show databases;
-
-
查询当前数据库
-
select database();
-
-
使用/切换数据库
-
use 数据库名;
-
-
创建数据库
-
create databse [if not exists] 数据库名 [default charset utf8mb4];
-
-
删除数据库
-
drop database [if exists] 数据库名;
-
创建表
create table user( id int comment 'ID,唯一标识', username varchar(50) comment '用户名字段', name varchar(10) comment '姓名', age int comment '年龄', gender char(1) comment '性别' )comment '用户信息表';
约束
作用域表中字段上的规则,用于限制存储在表中的数据
目的:保证数据库中数据的正确性、有效性和完整性
| 约束 | 描述 | 关键字 |
|---|---|---|
| 非空约束 | 限制该字段值不能为null | not null |
| 唯一约束 | 保证字段的所有数据都是唯一、不重复的 | unique |
| 主键约束 | 主键是一行数据的唯一表示,要求非空且唯一 | primary key |
| 默认约束 | 保存数据时,如果未指定该字段值,则采用默认值 | default |
| 外键约束 | 让两张表的数据建立连接,保证数据的一致性和完整性 | foreign key |
-- 创建表 create table user( id int primary key comment 'ID,唯一标识', -- auto_increment自增 username varchar(50) not null unique comment '用户名字段', name varchar(10) not null comment '姓名', age int comment '年龄', gender char(1) default '男' comment '性别' )comment '用户信息表';
数据类型
-
数值类型
-
选取原则:满足业务需求的前提下,选择占用磁盘空间小的数据类型
-
| 类型 | 大小byte | 有符号范围 | 无符号范围 | 描述 | 备注 |
|---|---|---|---|---|---|
| tinyint | 1 | -128,127 | 0,255 | 小整数值 | |
| smallint | 2 | -32768,32767 | 0,65535 | 大整数值 | |
| mediumint | 3 | -8388608,8388607 | 0,1677215 | 大整数值 | |
| int | 4 | 大整数值 | |||
| bigint | 8 | 极大整数值 | |||
| float | 4 | 单精度浮点数值 | float(5,2):5表示整个数字长度,2表示小数位个数 | ||
| double | 8 | 双精度浮点数值 | double(5,2):5表示整个数字长度,2表示小数位个数 | ||
| decimal | 小数值(精度更高) | decimal(5,2):5表示整个数字长度,2表示小数位个数 |
-
字符串类型
-
char:定长字符串
-
优势:性能略高
-
劣势:浪费磁盘空间
-
-
varchar:变长字符串
-
优势:节约磁盘空间
-
劣势:性能略低
-
-
-
日期时间类型
-
date:YYYY-MM-DD
-
time:HH:MM:SS
-
year:YYYY
-
datetime:YYYY-MM-DD HH:MM:SS
-
timestamp:YYYY-MM-DD HH:MM:SS
-
案例
创建表
-- 案例:设计员工表emp -- 基础字段:id主键 create_time 创建时间 update_time 修改时间 create table emp( id int unsigned primary key auto_increment comment '主键', username varchar(20) not null unique comment '用户名', password varchar(32) default '123456' comment '密码', name varchar(10) not null comment '姓名', gender tinyint unsigned not null comment '性别,1:男 2:女', phone char(11) not null unique comment '电话', job tinyint unsigned comment '职位,1班主任 2讲师 3学工主管 4教研主管 5咨询师', salary int unsigned comment '薪资', entry_data date comment'入职日期', image varchar(255) comment '图像', create_time datetime comment '创建时间', update_time datetime comment '修改时间' )comment '员工表';
操作表
-
利用图形化工具更方便
-- 查看当前数据库所有表 show tables; -- 查看指定表的表结构 desc emp; -- 查询建表语句 show create table emp; -- 字段:添加字段 qq varchar(13) alter table emp add qq varchar(13) comment 'QQ号码'; -- 字段:修改字段 qq varchar(15) alter table emp modify qq varchar(15) comment 'QQ号码'; -- 字段:修改字段名 alter table emp change qq qq_num varchar(15) comment 'QQ号码'; -- 字段:删除字段 alter table emp drop column qq_num; -- 修改表名 alter table emp rename to employee; -- 删除表 drop table employee;
DML
操作数据的增删改
insert - 添加数据
-
每个字段的长度应该在规定的范围内
-
推荐使用单引号
-
指定的字段顺序需要与值的顺序一一对应
-- DML数据操作语言
-- 插入数据 - 为指定字段插入值
insert into emp(username, password, name, gender, phone) values ('jean','12345678','jean','1','13685902000');
-- 插入数据 - 所有字段插入值
insert into emp(id, username, password, name, gender, phone, job, salary, entry_data, image, create_time, update_time)
values (null, 'tom','12345678','汤姆',1,'13685900000',1,6000,'2020-01-01','1.jpg',now(),now());
insert into emp values(null, 'michael','12345678','麦克',1,'13685900001',1,6000,'2020-01-01','1.jpg',now(),now());
-- 插入数据 - 批量插入数据 使用逗号间隔
insert into emp(username, password, name, gender, phone) values ('may','12345678','五月','1','13685902100'),
('july','12345678','七月','1','13685901000');
update - 修改数据
-
最好有更新的条件;不带条件的更新比较危险
-- 更新数据 - 多个字段之间用逗号分隔 update emp set username='zhangsan', name='张三' where id = 1
delete - 删除数据
-
同样需要有删除的条件
-- 删除数据 delete from 表名 + 条件 delete from emp where id = 1;
DQL
数据查询语言,用来查询数据库表中的记录
-
关键字:select
-
基本语法:select 字段 from 表名 where 条件 group by 分组字段 having 过滤条件 order by 排序字段 limit 起始索引,查询记录数;
基本查询
-- =================== DQL: 基本查询 ====================== -- 1. 查询指定字段 name,entry_date 并返回 select name, entry_date from emp; -- 2. 查询返回所有字段 不建议用通配符* 影响效率 不够直观 select * from emp; -- 3. 查询所有员工的 name,entry_date, 并起别名(姓名、入职日期) - 没有空格有无引号都可以,有空格必须要引号 select name as '姓名', entry_date as '入职日期' from emp; -- 4. 查询已有的员工关联了哪几种职位(不要重复) select distinct job from emp;
条件查询
-- =================== DQL: 条件查询 ====================== -- 1. 查询 姓名 为 柴进 的员工 select * from emp where name = '柴进'; -- 2. 查询 薪资小于等于5000 的员工信息 select * from emp where salary <= 5000; -- 3. 查询 没有分配职位 的员工信息 select * from emp where job is null; -- 4. 查询 有职位 的员工信息 select * from emp where job is not null; -- 5. 查询 密码不等于 '123456' 的员工信息 select * from emp where password != '123456'; -- 6. 查询 入职日期 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间的员工信息 - between 最小值 and 最大值 select * from emp where entry_date between '2000-01-01' and '2010-01-01'; -- 7. 查询 入职时间 在 '2000-01-01' (包含) 到 '2010-01-01'(包含) 之间 且 性别为女 的员工信息 select * from emp where (entry_date between '2000-01-01' and '2010-01-01') and gender = 2; -- 8. 查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息 select * from emp where job = 2 or job = 3 or job = 4; select * from emp where job in (2,3,4); -- 9. 查询 姓名 为两个字的员工信息 select * from emp where name like '__'; -- 10. 查询 姓 '李' 的员工信息 select * from emp where name like '李%'; -- 11. 查询 姓名中包含 '二' 的员工信息 select * from emp where name like '%二%';
分组查询
where和having的区别:
-
执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;having是分组之后对结果进行过滤
-
判断条件不同:where不能对聚合函数进行判断,having可以
聚合函数
-- =================== DQL: 分组查询 ====================== -- 聚合函数:所有的聚合函数不参与null的统计 -- 1. 统计该企业员工数量 -- count(字段) select count(id) from emp; -- count(*) 优先推荐 select count(*) from emp; -- count(常量) select count(null) from emp; -- 2. 统计该企业员工的平均薪资 select avg(salary) from emp; -- 3. 统计该企业员工的最低薪资 select min(salary) from emp; -- 4. 统计该企业员工的最高薪资 select max(salary) from emp; -- 5. 统计该企业每月要给员工发放的薪资总额(薪资之和) select sum(salary) from emp;
-- 分组 -- 1. 根据性别分组 , 统计男性和女性员工的数量 select gender, count(*) from emp group by gender; -- 2. 先查询入职时间在 '2015-01-01' (包含) 以前的员工 , 并对结果根据职位分组 , 获取员工数量大于等于2的职位 select job, count(*) from emp where entry_date <= '2015-01-01' group by job having count(*) >= 2;
排序查询
升序asc 降序desc 默认是升序
多字段排序,只有当第一个字段相同时,才会按照第二个字段进行排序
-- =================== 排序查询 ====================== -- 1. 根据入职时间, 对员工进行升序排序 select * from emp order by entry_date asc; -- 2. 根据入职时间, 对员工进行降序排序 select * from emp order by entry_date desc; -- 3. 根据 入职时间 对公司的员工进行 升序排序 , 入职时间相同 , 再按照 更新时间 进行降序排序 select * from emp order by entry_date asc, update_time desc;
分页查询
limit是mysql的方言
-- =================== 分页查询 ====================== -- 1. 从起始索引0开始查询员工数据, 每页展示5条记录 select * from emp limit 0, 5; -- 2. 查询 第1页 员工数据, 每页展示5条记录 - 索引从0开始 select * from emp limit 0, 5; -- 3. 查询 第2页 员工数据, 每页展示5条记录 select * from emp limit 5, 5; -- 4. 查询 第3页 员工数据, 每页展示5条记录 select * from emp limit 10, 5;
图形化工具DataGrip
DataGrip安装和激活_datagrip激活-CSDN博客
-- 查询所有数据库 show databases ; -- 创建数据库 create database db01; -- 使用数据库db01 use db01; -- 查询当前使用的数据库 select database(); -- 删除数据库 drop database db01;
JDBC
使用Java语言操作关系型数据库的一套API
引入依赖
<dependencies> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.9.3</version> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.30</version> </dependency> </dependencies>
编写JDBC程序,操作数据库
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JDBCTest {
@Test
public void testUpdate() throws Exception {
//1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取数据库的连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/web01", "root", "****");
//3.获取sql语句执行对象
Statement statement = connection.createStatement();
//4.执行sql
statement.executeUpdate("update user set age = 25 where id = 1");
//5.释放资源
statement.close();
connection.close();
}
}
@Test
public void testSelect(){
String DB_URL = "jdbc:mysql://localhost:3306/web01";
String USER = "root";
String PASS = "******";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null; // 封装查询返回的结果
try {
// 1. 注册 JDBC 驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2. 打开连接
System.out.println("连接数据库...");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
// 3. 执行查询
String sql = "SELECT id, username, password, name, age FROM user WHERE username = ? AND password = ?";
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "daqiao");
pstmt.setString(2, "123456");
// 4. 获取结果集
rs = pstmt.executeQuery();
// 5. 处理结果集
while (rs.next()) {
// 创建新的 User 对象,并填充数据
User user = new User(
rs.getInt("id"),
rs.getString("username"),
rs.getString("password"),
rs.getString("name"),
rs.getInt("age")
);
// 输出 User 对象的数据
System.out.println(user);
}
} catch (SQLException se) {
// 处理 JDBC 错误
se.printStackTrace();
} catch (Exception e) {
// 处理 Class.forName 错误
e.printStackTrace();
} finally {
// 6. 关闭资源
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
if (conn != null) conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
}
预编译SQL
String sql = "SELECT id, username, password, name, age FROM user WHERE username = ? AND password = ?";
-
优势1:防止SQL注入,更安全
-
SQL注入:通过控制输入来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法
-
-
优势2:性能更高
-
缓存编译结果
-
MyBatis
优秀的持久层框架,用于简化JDBC开发
数据库连接池
容器,负责分配、管理数据库连接
优势
-
资源重用
-
提升系统响应速度
-
避免数据库连接遗漏
实现
标准接口:DataSource
常见产品:Druid Hikari(Springboot默认)
删除操作
@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);
@Test
public void testDeleteById()
{
userMapper.deleteById(5);
}
新增操作
更新操作
查询操作
多个参数需要使用param注解,若是springboot骨架创建的项目,也不需要param注解
@Select("select * from user where username=#{username} and password=#{password}")
public User findByUserNameAndPassword(@Param("username") String username, @Param("password") String password);
XML映射配置
在mybatis中,既可以通过注解配置SQL语句,也可以通过XML配置SQL语句
规则
-
XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下
-
XML映射文件的namespace属性为Mapper接口全限定名一致
-
XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致
1365

被折叠的 条评论
为什么被折叠?



