学习JavaWebDAY5-参考黑马程序员

学习JavaWebDAY5-参考黑马程序员

  • 数据库:DataBase,存储和管理数据的仓库

  • 数据库管理系统DBMS DataBase Management System,操纵和管理数据库的大型软件

  • SQL,操作关系型数据库的编程语言,定义了一套操作关系型数据库的统一标准

MySQL

下载地址:MySQL :: Download MySQL Community Server

数据模型

关系型数据库:建立在关系模型基础上,由多张相互连接的二维表组成的数据库

特点:使用表存储数据,格式统一,便于维护;使用SQL语言操作,标准统一,使用方便,可用于复杂查询

MySQL语句

分类全称说明
DDLData Definition Language数据定义语言,用来定义数据库对象(数据库、表、字段)
DMLData Manipulation Language数据操作语言,用来对数据库表中的数据进行增删改
DQLData Query Language数据查询语言,用来查询数据库中表的记录
DCLData 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 '用户信息表';
约束

作用域表中字段上的规则,用于限制存储在表中的数据

目的:保证数据库中数据的正确性、有效性和完整性

约束描述关键字
非空约束限制该字段值不能为nullnot 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有符号范围无符号范围描述备注
tinyint1-128,1270,255小整数值
smallint2-32768,327670,65535大整数值
mediumint3-8388608,83886070,1677215大整数值
int4大整数值
bigint8极大整数值
float4单精度浮点数值float(5,2):5表示整个数字长度,2表示小数位个数
double8双精度浮点数值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的区别:

  1. 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;having是分组之后对结果进行过滤

  2. 判断条件不同: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开发

官网:MyBatis 3 | 简介 – mybatis

数据库连接池

容器,负责分配、管理数据库连接

优势

  • 资源重用

  • 提升系统响应速度

  • 避免数据库连接遗漏

实现

标准接口: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语句

规则

  1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下

  2. XML映射文件的namespace属性为Mapper接口全限定名一致

  3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值