MySQL、Mybatis学习日记

MySQL:关系型数据库(多张二维表连接)

image

e.g.根据部门关联

配置环境变量

添加MYSQL_HOME
//路径:路径\MySQL
配置path
//路径:路径\MySQL\bin

MySQL连接

登录
mysql -u用户名 -p密码 [-h数据库服务器IP地址 -P端口号] //其中-h -P用来企业远程连接
退出
exit

不指定[]参数,则默认连接3306端口

SQL语法

image

DDL:数据库、表、字段

DDL语句、图形化:使用DataGrip

DataGrip安装

启动Mysql,使其运行状态

cmd + R
services.msc 后找到对应MySQL查看是否处于启动

下载驱动,然后测试链接显示succee即可

基础DDL语句

基础语句

查询所有数据库
SHOW DATABASES;

查询当前数据库
SELECT DATABASE();

使用/切换数据库
USE 数据库名;

创建数据库
CREATE DATABASE [IF NOT EXISTS] 数据库名 [DEFAULT CHARSET utf8mb4];

删除数据库
DROP DATABASE [IF EXISTS] 数据库名;

其中database可以替换为schema,databases->schemas

约束:制定规则限制,多个约束空格分开

image

-- 创建带约束的用户信息表
CREATE TABLE user(
    id INT PRIMARY KEY COMMENT 'ID, 唯一标识', -- 主键约束
    username VARCHAR(50) NOT NULL UNIQUE COMMENT '用户名', -- 非空 + 唯一
    name VARCHAR(10) NOT NULL COMMENT '姓名', -- 非空
    age INT COMMENT '年龄',
    gender CHAR(1) DEFAULT '男' COMMENT '性别' -- 默认值
) COMMENT '用户信息表';

实现自动增长auto_increment

id INT PRIMARY KEY  auto_increment COMMENT 'ID, 唯一标识', -- auto_increment

数据类型:满足需求下,尽可能选占用小的

image

无符号使用:int unsigned

字符串类型:音视频文件blob后缀
image

长度固定char,其余varchar

描述信息存文本用text等

日期类型
image

表-增删改查

-- 创建表的基本语法
CREATE TABLE tablename(
    字段1 字段类型 [约束] [COMMENT '字段1注释'],
    ...... 
    字段2 字段类型 [约束] [COMMENT '字段2注释']
) [COMMENT '表注释'];

e.g.

点击查看代码
CREATE TABLE user(
    id INT COMMENT 'ID, 唯一标识',
    username VARCHAR(50) COMMENT '用户名',
    name VARCHAR(10) COMMENT '姓名',
    age INT COMMENT '年龄',
    gender CHAR(1) COMMENT '性别'
) COMMENT '用户信息表';
查询当前数据库的所有表
SHOW TABLES;

查询表结构
DESC 表名;

查询建表语句
SHOW CREATE TABLE 表名;

添加字段
ALTER TABLE 表名 ADD 字段名 类型(长度) [COMMENT '注释'] [约束];

修改字段类型
ALTER TABLE 表名 MODIFY 字段名 新数据类型(长度);

修改字段名与字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度) [COMMENT '注释'] [约束];

删除字段
ALTER TABLE 表名 DROP COLUMN 字段名;

修改表名
ALTER TABLE 表名 RENAME TO 新表名;

删除表
DROP TABLE [IF EXISTS] 表名;

案例

DML:数据操作

insert插入

指定字段添加数据
INSERT INTO 表名(字段名1, 字段名2) VALUES (值1, 值2);

全部字段添加数据
INSERT INTO 表名 VALUES (值1, 值2, ...);

批量添加数据(指定字段)
INSERT INTO 表名 (字段名1, 字段名2) VALUES (值1, 值2), (值1, 值2);

批量添加数据(全部字段)
INSERT INTO 表名 VALUES (值1, 值2, ...), (值1, 值2, ...);

其内部顺序与值一一对应

update更新

修改数据
UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ...... [WHERE 条件];

若是不加以where约束十分危险,会更新整张表数据

多约束:数据使用AND/OR连接

e.g.

UPDATE 表名 SET 字段名1 = 值1, 字段名2 = 值2, ...... where id = 1;

delete:无法删某个字段,删字段用update将值改为NULL

delete from 表名 [where 条件];

无where删整张表

DQL:表查询

image

基本查询

查询多个字段
SELECT 字段1, 字段2, 字段3 FROM 表名;

查询所有字段(通配符)
SELECT * FROM 表名;

为查询字段设置别名,AS 关键字可以省略
SELECT 字段1 [AS 别名1], 字段2 [AS 别名2] FROM 表名;

去除重复记录
SELECT DISTINCT 字段列表 FROM 表名;

先写from表会自动识别字段,别名时若中间有空格(要引号)

条件查询:like模糊匹配,多条件之间可以添加括号

image

在20xx-9-1到20xx-7-1日,且X = 1的

(between '20xx-9-1' and '20xx-7-1) and X = 1;

查询是2,3,4的信息

in (2, 3, 4);

like_代表单个字符,%代表任意个字符

分组查询:按某字段分组,操作聚合,所以是(分组 + 聚合)

聚合函数: 将一列数据作为一个整体,进行纵向计算

聚合函数不参与null值统计

image

格式

select 聚合函数() from 表名;

分组查询:分组后,select后字段不能随意写,能写分组字段 + 聚合函数

分组查询
SELECT 字段列表 FROM 表名 [WHERE 条件列表] GROUP BY 分组字段名 [HAVING 分组后过滤条件];

按性别分组并统计男女员工数量

select gender, count(*) from 表名 group by gender;

查询入职时间在'20xx-xx-xx'及之前员工,并根据职位分组,最终获取员工数量>2的职位

SELECT job, COUNT(*) FROM 表名 WHERE entry_date <= '2015-01-01' GROUP BY job HAVING COUNT(*) >= 2;

where和having的区别:

image

执行顺序:where > 聚合函数 > having

排序查询:多字段只有一个字段值相同,才会根据第二个字段排序

image

排序查询
SELECT 字段列表 FROM 表名 [WHERE 条件列表] [GROUP BY 分组字段名 HAVING 分组后过滤条件] ORDER BY 排序字段 排序方式;

多字段排序:字段 方式,字段 方式,····

多字段只有一个字段值相同,才会根据第二个字段排序

分页查询(不同数据库这部分SQL不同):数据多分页展示,分页参数

-- 分页查询
SELECT 字段 FROM 表名 [WHERE 条件] [GROUP BY 分组字段 HAVING 过滤条件] [ORDER BY 排序字段] LIMIT 起始索引, 查询记录数;

起始索引:代表从哪条数据往后查,起点从0开始

查询记录数:每页展示多少条

image

查询第二页数据,每页展示5条数据

select * from 表名 limit 5, 5; //第一页0-4,第二页从5开始

页码,起始索引的计算:第x页的起始索引 = (x - 1) * 每页展示记录数

Mybatis:java程序操作数据库 ,优化JDBC

JDBC:java语言操作关系型数据库的一套API

JDBC是一套规范,本身不提供实现,而是对应数据库的厂商提供接口(驱动Jar包)
image

所以直接使用JDBC接口即可,最终执行的是Jar包的实现类

JDBC入门程序

基于JDBC程序,执行update语句(update user set age = 25 where id = 1)

步骤:

  1. 创建maven项目、引入依赖 并准备数据库表user
    pom.xml
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.0.33</version>
</dependency>
  1. 实现:编写JDBC操作数据库
    JDBC程序
//1. 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");

//2. 获取连接
String url = "jdbc:mysql://localhost:3306/web01";
String username = "root";
String password = "1234";
Connection connection = DriverManager.getConnection(url, username, password);//连接对象Connection

//3. 获取SQL语句执行对象
Statement statement = connection.createStatement();//创建Statement对象执行SQL语句

//4. 执行SQL
int i = statement.executeUpdate("update user set age = 25 where id = 1");

其中.executeQuery()查询语句; .executeUpdate()增删改;

//5. 释放资源
statement.close();
connection.close();

其中驱动链接获取: 两次shift,搜索Driver:com.mysql.cj.jdbc,赋值全类名放到()中

对于url:固定格式为"jdbc:mysql://localhost3306/具体数据库名"

Mybatis是Dao层操作数据库: Mybatis

Mybatis配置:Mybatis开发只需要定义Mapper接口,实现类会自动实现

  1. 创建Springboot工程、数据库表、实体类

保持让类中属性名 与 表中字段名保持一致,这样会自动封装

使用实体类时,推荐使用包装类型,如:Integer等···

  1. 引用Mybits依赖,配置Mybatis
    勾选SQL下:Mybatis Framework、MySQL Driver依赖

设置使用的数据库:在resource/application.properties

  • Driver驱动(固定)
    image
  • url
固定协议jdbc:mysql://
jdbc:mysql://localhost:3306/使用的数据库名 
  • application.properties下配置
    image
点击查看代码
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.username=用户名
spring.datasource.password=密码
  1. 编写SQL语句(注解/XML):将SQL结果封装到返回值
@Mapper
public interface UserMapper {
    @Select("select * from user")
    public List<User> list();
}

多用包装类型:好处是包装类没有默认值,不存在歧义

JDBC执行DML、DQL语句?

执行DML
int rowsAffected = statement.executeUpdate();//返回int即影响记录数

执行DQL
ResultSet rs = statement.executeQuery();//结果集对象,封装查询结果

DQL语句执行完毕ResultSet的解析?

resultSet.next():光标下移一行

resultSet.getXxx():获取字段数据

image

ResultSet(结果集):光标概念(默认在每行前一个)判断当前行是否有数据

while(resultSet.next()) {//遍历方法
    int id = resultSet.getInt("id");
    //···
}

提示词案例:使用AI

点击查看代码
你是一名java开发工程师,帮我基于JDBC程序来操作数据库,执行如下SQL语句:select id,username,password,name,age from user where username = 'daqiao' and password = '123456';

并将查询的每一行记录,都封装到实体类User中,然后将User对象的数据输出到控制台中。

User 实体类属性如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private Integer id; //ID
    private String username; //用户名
    private String password; //密码
    private String name; //姓名
    private Integer age; //年龄
}

提示词下的完整小案例:新知 & API

点击查看代码
package org.gchaoyang.testmybatis;

import org.gchaoyang.testmybatis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.sql.*;

@SpringBootTest  // Spring Boot 测试注解
public class JdbcTest {

    @Test  // JUnit 测试方法注解
    public void testUpdate() throws Exception {
        //1. 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

        //2. 获取数据库连接
        String url = "jdbc:mysql://localhost:3306/mybatis";//链接地址
        String username = "root";
        String password = "root";
        Connection connection = DriverManager.getConnection(url, username, password);

        //3. 获取SQL语句执行对象
        Statement statement = connection.createStatement();

        //4. 执行SQL (DML)
        int i = statement.executeUpdate("update user set age = 25 where id = 1");
        System.out.println("SQL执行完毕影响的记录数为: " + i);

        //5. 释放资源
        statement.close();
        connection.close();
    }

    @Test
    public void testSelect() {
        String URL = "jdbc:mysql://localhost:3306/mybatis";
        String USER = "root";
        String PASSWORD = "root";

        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;//封装查询结果,结果集对象

        try {
            // 1. 注册 JDBC 驱动
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2. 打开连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);

            // 3. 执行查询
            //这种sql用法为预编译语句:安全,性能更高
            String sql = "SELECT id, username, password, name, age FROM user WHERE username = ? AND password = ?";//?为占位符

            stmt = conn.prepareStatement(sql);//为Statement子接口,也可以执行SQL语句
            //但首先要给1,2占位符赋值
            stmt.setString(1, "daqiao");
            stmt.setString(2, "123456");

            rs = stmt.executeQuery();//将查询结果封装到ResultSet对象中

            // 4. 处理结果集:其中可能有多条数据
            while (rs.next()) {//通过光标辨析是否有值
                User user = new User(
                        rs.getInt("id"),
                        rs.getString("username"),
                        rs.getString("password"),
                        rs.getString("name"),
                        rs.getInt("age")
                );
                System.out.println(user); // 使用 Lombok 的 @Data 自动生成的 toString 方法
            }

        } catch (SQLException se) {
            // Handle errors for JDBC
            se.printStackTrace();
        } catch (Exception e) {
            // Handle errors for Class.forName
            e.printStackTrace();
        } finally {
            // 5. 关闭资源
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException se) {
                se.printStackTrace();
            }
        }
    }
}

其中要给与完整的字段信息,用以数据匹配

预编译SQL:使用PreparedStatement,安全高性能

非固定形式,而是用参数传递形式,即为预编译

预编译:使用PreparedStatement
PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");

pstmt.setString(1, "daqiao");
pstmt.setString(2, "123456");

ResultSet resultSet = pstmt.executeQuery();

与其相对的则是静态SQL(参数硬编码):直接使用Statement即可

静态SQL

点击查看代码
Statement statement = connection.createStatement();

int i = statement.executeUpdate("update user set age = 25 where id = 1");

System.out.println("SQL执行完毕,影响的记录数为:" + i);

优势:防止SQL注入、性能更高

运行jar包(jar包地址下)cmd, 启动后根据端口号浏览器打开
java -jar 名.jar

使用SQL注入:导致有select count(*) from emp where username = 'sjdkfjkdjfks' and password = '' or '1' = '1'; 1=1恒等

任意用户名xxxx
密码:写入带有攻击性字符串
'or'1'='1

SQL语句执行流程
image

预编译充分利用了缓存功能:实现了操作相同的优化

Mybatis(简化JDBC):持久(Dao)层框架,1配置ap,2定义接口

对比:左为JDBC,右为Mybatis Mybatis

image

Mybatis写法:定义接口,在其中声明接口方法 并 在其上添加注解(要执行的SQL语句)
image

最终调用接口内部方法时,会执行其SQL语句,并将其结果封装到集合中,最后将其内每一条记录封住到一个对象中

自动

@Mapper
public interface UserMapper {
    /**
    * 查询全部
    */
    @Select("select * from user")
    public List<User> findAll();
}

此时@SpringBootTest注解中,使用注入Bean即可

@SpringBootTest //SpringBoot单元测试的注解 - 当前测试类中的测试方法运行时,会启动springboot项目 - IOC容器
class SpringbootMybatisQuickstartApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testFindAll() {
        List<User> userList = userMapper.findAll();
        userList.forEach(user -> System.out.println(user));
    }
}

@SpringBootTset注解:测试类和启动类的包名要相同

image

image

辅助配置:SQL提示

对于@Mapper中SQL语句初始会被当做默认字符串(不提供提示)
image

以此标识此字符串为何种语言

但以此产生问题,(数据库配置信息只在运行时生效)此时不会识别
以此需要idea中连接数据库,配置信息后要test连通
image

辅助配置:Mybatis日志输出

image

关键字mybatislog.impl
image

JDBC vs Mybatis

JDBC存在参数硬编码问题(被固定),且结果集获取繁琐

而Mybatis中存储在配置文件(无需编译)无需修改对应java文件
且通过数据库连接池优化资源浪费问题

image

数据库连接池

image

若无数据库连接池,则对于SQL进程要创建connection(每次创建->用完关闭)
image

而启用连接池则会持久化一个连接池(使用与归还)

连接池遗漏问题(处理)
对于空调用或其他情况一直占用进程,不归还给线程池情况
数据库连接池会监控进程空闲时间:> \(MAX_time\),则会将连接归还给数据池

标准接口:DaTaSource

官方提供数据库连接池,由第三方组织实现
功能:获取连接

Connection getConnection() throws SQLException;

image

后2个较常用,默认Hikari

切换连接池:Druid
image

Mybatis增删改查:对于增删改无需返回void

删,使用@Delete()

image

使用预编译传参来使得内容不固定

此时调用即可

@Test
public void testDetleteById() {
    userMapper.deleteById(参数);//直接调用方法即可
}

采用Integer返回值:接取被影响的记录数
image

Integer i = userMapper.deleteById(5);
System.out.println(i);//影响记录数

注意:对于删除掉的ID,也会默认占位,此时自增会默认从删之前的ID+1

预编译写法 #{} 与 ${}

  • #{}:更多是参数值传递
  • ${}:更多是表名、字段名动态设置使用,会拼接到SQL语句中再编译,存在SQL注入

image

增:使用@Insert(),当参数过多封装对象传参

其中要和获取属性一一对应

image

@Test
public void testInsert(){
    User user = new User(null, "gaoyuanyuan", "666888", "高圆圆", 18);//id未使用,可任意传参
    userMapper.insert(user);
}

改:使用@Update(),多参数封装

image

使用方式同增

查:使用@Select(),返回值只有一个,所以封装到对象中

其中传递形参不会保留,即无法得知哪个是所需要的值,涉及多个形参要起名

image

若基于SpringBoot骨架项目则可省略

原因是SpringBoot其中存在副工程Maven下保留了接口形参名

对于框架错误查看:找到最后一个Caused by

image

XML映射

XML映射配置:resource目录用/

屏幕截图 2026-07-07 124514

在Mybatis网站中获取配置信息:Mybatis中文网
image

此即为基础结构
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xxx.xxx.xxx.xxx(与全限定名保持一致)">
内容
</mapper>

增删改查对应标签

e.g.全结构方式:
<select id = "findAll(方法名)" resultType = "xxx.xxx.User(返回类型的全类名)">
类型:
<update>
<delete>
<insert>

场景辨析

image

XML辅助配置:

错误:没找到对应SQL(未同包同名)

Invalid bound statement (not found): com.itheima.mapper.UserMapper.findAll

image

辅助配置1:配置XML指定映射文件位置

关键字mybatislocation···

指定XML映射配置文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml

java和resource下文件编译后都放在classpath类路径下

辅助配置2:使用MybatisX插件
可以点击小鸟:快速切换定位在接口/配置文件之间

SpringBoot配置文件:properties:key-value,yaml、yml

image

yaml、yml配置文件:通过缩进确定层级,且:后要有空格

image

在application.yml

# 定义对象/Map集合

user:
    name: Tom
    age: 18
    password: 123456

# 定义数组/List/Set集合

hobby:
    - Java
    - Game
    - Sport

其中若以0开头,则要加'',如'0123456',否则会认为其是8进制数据

将application.properties配置文件改为yml配置

image

输入类(原properties)关键字即可

e.g.
springapp···
springdat···
posted @ 2026-06-28 12:27  Gchaoyang9  阅读(4)  评论(0)    收藏  举报