当前位置: 首页 > news >正文

JavaWeb(后端)

数据库:

基础概念:

概念说明
数据库(DB)存储和管理数据的仓库(英文:DataBase)
数据库管理系统(DBMS)操作和管理数据库的大型软件(英文:DataBase Management System)
SQL(结构化查询语言)操作关系型数据库的编程语言,定义了统一操作标准(英文:Structured Query Language)

目前主流的数据库:Oracle,MySQL,SQL Server,PostgreSQL,DB2,SQLLite,MariaDB

数据模型:

关系型数据库(RDBMS):

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

二维表:由行(记录)和列(字段)组成的表格(例:员工表、部门表)

MySQL 的操作逻辑:

通过 MySQL 客户端连接 DBMS;向 DBMS 发送 SQL 语句,由 DBMS 操作数据库的表结构与数据;层级关系:数据库服务器 → 多个数据库 → 单个数据库包含多张表 → 单张表包含多行记录

SQL 语句:

SQL:结构化查询语言,是一门操作关系型数据库的编程语言,定义操作所有关系型数据库的统一标准

按功能被分为四大类:

分类英文全称作用
DDLData Definition Language(数据定义语言)定义数据库对象(库、表)
DMLData Manipulation Language(数据操作语言)操作表中数据(增、删、改)
DQLData Query Language(数据查询语言)查询表中数据
DCLData Control Language(数据控制语言)管理数据库权限

DDL 语句:

用于操作数据库、表的结构

数据库操作:
查询数据库:

查询所有数据库:

show databases;

查询当前数据库:

select database();

注意:要操作某一个数据库,必须要切换到对应的数据库中

创建数据库:
create database [ if not exists ] 数据库名 [default charset 字符集];

创建数据库时,可以不指定字符集(默认)

注意:在同一个数据库服务器中,不能创建两个名称相同的数据库,否则将会报错

if not exists:如果数据库不存在,则创建该数据库;存在则不创建

使用数据库:
use 数据库名;

操作表前需切换到对应数据库

删除数据库:
drop database [ if exists ] 数据库名;

注意:如果删除一个不存在的数据库,将会报错

if exists:如果数据库存在,再执行删除,否则不执行删除

表操作:
创建表:
create table 表名( 字段1 字段1类型 [约束] [comment 字段1注释 ], 字段2 字段2类型 [约束] [comment 字段2注释 ], ...... 字段n 字段n类型 [约束] [comment 字段n注释 ] ) [ comment 表注释 ] ;
约束:

作用于字段的规则,限制存储数据

约束描述关键字
非空约束限制该字段取值不能为 nullnot null
唯一约束保证字段的所有数据都是唯一、不重复的unique
主键约束主键是一行数据的唯一标识,要求非空且唯一primary key
默认约束保存数据时,如果未指定该字段值,则采用默认值default
外键约束让两张表的数据建立连接,保证数据的一致性和完整性foreign key
create table user( id int primary key auto_increment comment 'ID,唯一标识', #主键自动增长 username varchar(20) not null unique comment '用户名', name varchar(10) not null comment '姓名', age int comment '年龄', gender char(1) default '男' comment '性别' ) comment '用户表';

主键自增(auto_increment):

作用:插入新数据行时,数据库会自动为主键字段生成递增的数值

规则:自增序列从正整数 1 开始,每次插入新记录时自动加一

数据类型:

在 MySQL 中主要分为三类:

数值类型:tinyint、smallint、int、bigint、float、double、decimal(精确小数)

字符串类型:char(定长)、varchar(变长)、text(长文本)、blob(二进制数据);

日期时间类型:date(日期)、time(时间)、datetime(日期时间)、timestamp(带时区的日期时间)

查询表:
-- 查询当前数据库的所有表 show tables; -- 查看指定的表结构 desc 表名; -- 可以查看指定表的字段、字段的类型、是否可以为NULL、是否存在默认值等信息 -- 查询指定表的建表语句 show create table 表名;
修改表:

添加字段:

alter table 表名 add 字段名 类型(长度) [comment 注释] [约束];

修改字段:

-- 修改字段类型 alter table 表名 modify 字段名 新数据类型(长度); -- 修改字段名 alter table 表名 change 旧字段名 新字段名

删除字段:

alter table 表名 drop 字段名;

修改表名:

rename table 表名 to 新表名;

删除表:

drop table [ if exists ] 表名;

注意:关于表结构的查看、修改、删除操作,一般都是直接基于图形化界面操作

DML 语句:

用于操作表中数据

插入数据:

向指定字段添加数据:

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 表名 set 字段名1 = 值1 , 字段名2 = 值2 , .... [where 条件] ;

注意:无 where 条件会修改表中所有数据;建议添加 update_time 字段记录修改时间

删除数据:
delete from 表名 [where 条件] ;

注意:无 where 条件会修改表中所有数据;不能删除单个字段(可用 update 设为 NULL)

DQL 语句:

用于查询表中数据

select 字段列表 from 表名列表 where 条件列表 group by 分组字段列表 having 分组后条件列表 order by 排序字段列表 limit 分页参数
基本查询:

查询多个字段:

select 字段1, 字段2, 字段3 from 表名;

查询所有字段(通配符):

select * from 表名;

设置别名:

select 字段1 [ as 别名1 ] , 字段2 [ as 别名2 ] from 表名;-- 别名中有特殊字符时,使用''或""包含

去除重复记录:

select distinct 字段列表 from 表名;
条件查询:
select 字段列表 from 表名 where 条件列表 ; -- 条件列表:意味着可以有多个条件

在 SQL 语句当中,构造条件的运算符分为比较运算符和逻辑运算符

常用的比较运算符:

常用的逻辑运算符:

聚合函数:

对一列数据计算后返回一个结果:

常用的聚合函数:

函数作用
count()计数
max()最大值
min()最小值
avg()平均值
sum()求和

注意 : 聚合函数会忽略空值,对 NULL 值不作为统计

分组查询:

按照某一列或者某几列,把相同的数据进行合并输出(通常会使用聚合函数进行计算)

select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];

注意:分组后只能查询分组字段和聚合函数;having 用于过滤分组结果

排查查询:
select 字段列表 from 表名 [where 条件列表] [group by 分组字段 ] order by 字段1 排序方式1 , 字段2 排序方式2 … ;

排序方式:asc:升序(默认);desc:降序

注意:多字段排序:前一个字段相同时,按后一个字段排序

分页查询:
select 字段列表 from 表名 limit 起始索引, 查询记录数 ;

注意:起始索引 = (查询页码 - 1)* 每页显示记录数

JDBC:

全称:Java DataBase Connectivity(Java 数据库连接)

本质

Sun 公司定义的操作关系型数据库的接口规范;各数据库厂商实现该接口,提供数据库驱动包;

开发者通过 JDBC 接口编程,实际执行的是驱动包中的实现代码

操作数据库:

准备工作:

创建 Maven 项目,引入 MySQL 驱动依赖:

<dependencies> <!-- MySQL JDBC driver --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> </dependencies>

创建数据库 web 及 user 表:

create table user( id int unsigned primary key auto_increment comment 'ID,主键', username varchar(20) comment '用户名', password varchar(32) comment '密码', name varchar(10) comment '姓名', age tinyint unsigned comment '年龄' ) comment '用户表'; insert into user(id, username, password, name, age) values (1, 'wangbian', '123456', '王扁', 22), (2, 'wujing', '123456', '吴京', 28), (3, 'danshen', '123456', '蛋神', 24), (4, 'mowan', '123456', '魔丸', 28), (5, 'lingzhu', '123456', '灵珠', 27);

代码实现:

public class JDBCTest{ //编写JDBC程序, 查询数据 @Test public void testJdbc() throws Exception{ //获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234"); //创建预编译的PreparedStatement对象 PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?"); //设置参数 pstmt.setString(1, "wangbian");//第一个问号对应的参数 pstmt.setString(2, "123456");//第二个问号对应的参数 //执行查询 ResultSet rs = pstmt.executeQuery(); //处理结果集 while(rs.next()){ int id = rs.getInt("id"); String uName = rs.getString("username"); String pwd = rs.getString("password"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("ID: " + id + ", Username: " + uName + ", Password: " + pwd + ", Name: " + name + ", Age: " + age); } //关闭资源 rs.close(); pstmt.close(); conn.close(); } }

参数化测试(动态传参):

public class JDBCTest{ //编写JDBC程序, 查询数据 @ParameterizedTest @CsvSource({"wangbian,123456"}) public void testJdbc(String _username, String _password) throws Exception { //获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234"); //创建预编译的PreparedStatement对象 PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?"); //设置参数 pstmt.setString(1, _username);//第一个问号对应的参数 pstmt.setString(2, _password);//第二个问号对应的参数 //执行查询 ResultSet rs = pstmt.executeQuery();//返回值是查询结果集 //处理结果集 while(rs.next()){ int id = rs.getInt("id"); String uName = rs.getString("username"); String pwd = rs.getString("password"); String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println("ID: " + id + ", Username: " + uName + ", Password: " + pwd + ", Name: " + name + ", Age: " + age); } //关闭资源 rs.close(); pstmt.close(); conn.close(); } }

代码剖析:

ResultSet(结果集):封装查询结果

next():游标移动到下一行,返回 true(有数据)/ false(无数据);

getXxx(字段名/索引):获取对应字段的数据

PreparedStatement(预编译 Statement):

作用:防止 SQL 注入、提高性能;

原理:先将带占位符(?)的 SQL 发送给数据库编译,再传递参数执行

SQL 执行方式:

方式特点缺点
静态 SQL(Statement)参数直接拼接在 SQL 中存在 SQL 注入风险
预编译 SQL(PreparedStatement)?占位,参数动态传递

修改数据:

@ParameterizedTest @CsvSource({"1,123456,25"}) public void testUpdate(int userId, String newPassword, int newAge) throws Exception{ //建立数据库连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234"); //SQL 更新语句 String sql = "UPDATE user SET password = ?, age = ? WHERE id = ?"; //创建预编译的PreparedStatement对象 PreparedStatement pstmt = conn.prepareStatement(sql); //设置参数 pstmt.setString(1, newPassword);//第一个问号对应的参数 pstmt.setInt(2, newAge);//第二个问号对应的参数 pstmt.setInt(3, userId);//第三个问号对应的参数 //执行更新 int rowsUpdated = pstmt.executeUpdate();//返回值是影响的记录数 //输出结果 System.out.println(rowsUpdated + " row(s) updated."); //关闭资源 pstmt.close(); conn.close(); }

MyBatis:

一款持久层框架,用于简化 JDBC 开发

持久层:即数据访问层(DAO),负责操作数据库

框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型

在框架的基础上进行软件开发更加高效、规范、通用、可拓展

入门程序:

需求:查询所有用户

环境准备:

创建 SpringBoot 工程:引入依赖(MyBatis Starter、MySQL 驱动、Lombok)

创建数据库表:

create table user( id int unsigned primary key auto_increment comment 'ID,主键', username varchar(20) comment '用户名', password varchar(32) comment '密码', name varchar(10) comment '姓名', age tinyint unsigned comment '年龄' ) comment '用户表'; insert into user(id, username, password, name, age) values (1, 'wangbian', '123456', '王扁', 22), (2, 'wujing', '123456', '吴京', 28), (3, 'zhangbing', '123456', '张兵', 24), (4, 'mowan', '123456', '魔丸', 28), (5, 'lingzhu', '123456', '灵珠', 27);

代码实现:

编写实体类 (User):

@Data//自动生成get/set/toString等方法 @NoArgsConstructor @AllArgsConstructor public class User { private Integer id; //ID private String username; //用户名 private String password; //密码 private String name; //姓名 private Integer age; //年龄 }

配置数据库连接(application.properties):

#数据库访问的url地址 spring.datasource.url=jdbc:mysql://localhost:3306/web #数据库驱动类类名 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #访问数据库-用户名 spring.datasource.username=root #访问数据库-密码 spring.datasource.password=root@1234

编写 Mapper 接口(数据访问接口):

@Mapper//标识为MyBatis Mapper接口,框架自动生成代理对象并交给Spring管理 public interface UserMapper{ //查询全部 @Select("select * from user")//编写查询SQL public List<User> findAll(); }

单元测试:

@SpringBootTest class SpringbootMybatisApplicationTests { @Autowired//自动注入UserMapper代理对象 private UserMapper userMapper; @Test public void testFindAll(){ List<User> userList = userMapper.findAll(); for (User user : userList) { System.out.println(user); } } }

运行结果:

注意:测试类所在包需要与引导类所在包相同

辅助配置:

IDEA SQL 提示配置:

在 IDEA 中关联 MySQL 数据库,可实现 Mapper 接口中 SQL 语句的语法提示:

配置完成后还存在不识别表名(列名)的情况,需要配置 MySQL 数据库连接:

MyBatis 日志配置:

在 application.properties 中添加配置,可查看 SQL 执行日志:

#mybatis的配置 mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

再次运行单元测试:

数据库连接池:

避免频繁的创建连接、销毁连接而带来的资源浪费

工作原理:

没有数据库连接池的情况:

客户端执行 SQL 语句:要先创建一个新的连接对象,然后执行 SQL 语句,SQL 语句执行后又需要关闭连接对象从而释放资源,每次执行 SQL 时都需要创建连接、销毁链接,这种频繁的重复创建销毁的过程是比较耗费计算机的性能

有数据库连接池的情况:

数据库连接池是个容器,负责分配、管理数据库连接(Connection)

  • 程序在启动时,会在数据库连接池(容器)中,创建一定数量的 Connection 对象

允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

  • 客户端在执行 SQL 时,先从连接池中获取一个 Connection 对象,然后在执行 SQL 语句,SQL 语句执行完之后,释放 Connection 时就会把 Connection 对象归还给连接池(可复用)

释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏

  • 客户端获取到 Connection 对象了,但是 Connection 对象并没有去访问数据库(处于空闲),数据库连接池发现 Connection 对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象

优势:资源重用,提升系统响应速度,避免数据库连接遗漏

常见连接池:

官方定义了 javax.sql.DataSource 接口,第三方实现包括:C3P0、DBCP、Druid、Hikari(SpringBoot 默认)

功能:获取连接

public Connection getConnection() throws SQLException;

切换连接池(以 Druid 为例):

引入依赖:

<dependency> <!-- Druid连接池依赖 --> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.19</version> </dependency>

配置连接池(application.properties):

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.druid.url=jdbc:mysql://localhost:3306/web spring.datasource.druid.username=root spring.datasource.druid.password=1234

增删改查操作:

MyBatis 提供两种参数占位方式:

符号说明场景优缺点
#{…}占位符,执行时,会将 #{…} 替换为?,生成预编译SQL参数值传递安全、性能高(推荐)
${…}拼接符,直接将参数拼接在 SQL 语句中,存在 SQL 注入问题表名、字段名动态设置时使用不安全、性能低
删除:
@Delete("delete from user where id = #{id}") //返回值为受影响行数 Integer deleteById(Integer id);

新增:

@Insert("insert into user(username,password,name,age) values(#{username},#{password},#{name},#{age})") void insert(User user);
修改:
@Update("update user set username = #{username},password = #{password},name = #{name},age = #{age} where id = #{id}") public void update(User user);
查询:
@Select("select * from user where username = #{username} and password = #{password}") public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

@Param 作用:为接口方法的参数指定名称,确保 SQL 中能正确匹配参数(由于用户名是唯一的,所以查询返回的结果最多只有一个,可以直接封装到一个对象中)

在 SpringBoot 官方脚手架创建的项目中,接口编译时会保留方法参数名,此时 @Parram 注解可省略

XML 映射配置:

MyBatis 有两种开发方式:注解方式(适合简单 SQL)、XML 方式(适合复杂 SQL 功能)

XML 配置文件规范:

文件位置:XML 文件名与 Mapper 接口名一致,且放置在同包下(同包名);

namespace 属性:XML 的 namespace 需与 Mapper 接口的全限定名一致;

SQL 语句对应:XML 中 SQL 语句的 ID 与 Mapper 接口的方法名一致,且返回类型一致

XML 配置文件实现:

创建 XML 映射文件:

编写 XML 映射文件:

<?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"> <!-- namespace填写Mapper接口全限定名 --> <mapper namespace="org.example.mapper.UserMapper"> <!-- 编写SQL语句 --> </mapper>

编写 SQL 语句:

<?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="org.example.mapper.UserMapper"> <!--查询操作--> <!-- <select>标签:用于编写select查询语句 --> <!-- resultType属性:指的是查询返回的单条记录所封装的类型 --> <select id="findAll" resultType="org.example.pojo.User"> select * from user </select> </mapper>

辅助配置:

在 application.properties 中配置 XML 映射文件的位置:

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

MybatisX:

MybatisX 是 IDEA 的 MyBatis 快速开发插件

支持:Mapper 接口与 XML 文件之间的快速跳转;XML 中 SQL 语句的自动提示(如实体类属性、表字段)

YAML:

对比:

SpringBoot 支持 properties 和 yaml 两种配置格式,两者核心差异:

语法:

大小写敏感;数值与符号间需空格;层级用缩进表示

常见数据格式:

对象 / Map 集合

user: name: hei age: 18 password: 123456

数组 / List / Set集合

hobby: - sing - dance - rap - basketball

注意:若配置项的值以 0 开头,需用引号包裹(避免被解析为八进制数)

示例:

# 应用配置 spring: application: name: springboot-mybatis # 数据库配置 datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/web username: root password: 1234 # MyBatis配置 mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
http://www.jsqmd.com/news/496987/

相关文章:

  • 海外社媒营销服务商合集,Facebook、LinkedIn、TikTok代运营,适配多品类B2B外贸需求 - 品牌2026
  • 2026年河南单反相机回收公司推荐:数码相机/CCD/镜头/无人机/鼠标回收服务商 - 品牌推荐官
  • Z-Image-Turbo_Sugar脸部Lora效果展示:同一人物多角度(正脸/侧脸/45°)生成一致性
  • Janus-Pro-7B训练数据揭秘:9000万条多模态样本如何提升稳定性与泛化性
  • Audio Pixel Studio人声分离原理浅析:基于频谱分析的轻量化UVR实现路径
  • C++成员模板类
  • 2026年 换位绕组线厂家推荐排行榜:高效节能、精准导电的工业级线材优选 - 品牌企业推荐师(官方)
  • Gemma-3-270m从零开始教程:Ollama安装→模型拉取→交互提问→结果保存
  • Java 解析 CDR 文件并计算图形面积的完整方案(支持 MultipartFile / 网络文件)@杨宁山
  • Qwen-Image-2512-SDNQ Web服务部署教程:OpenEuler 22.03 LTS系统适配记录
  • Alpamayo-R1-10B快速部署:scripts/start_webui.sh脚本执行逻辑深度解析
  • Qwen-Image-2512-SDNQ Web服务API详解:curl调用/generate接口参数实战
  • FLUX.小红书极致真实V2企业案例:连锁茶饮品牌月产2000+新品宣传图
  • 查重过了但AIGC爆红?手把手教你降ai:从59%降到6.3%,附免费降ai率工具测评 - 殷念写论文
  • 幻境·流金代码实例:Python调用本地镜像批量生成指定规格图像脚本
  • RexUniNLU惊艳案例:中文财经新闻公司-事件-影响三元组实时抽取
  • Phi-3 Forest Lab参数详解:Temperature=0.1时Phi-3在算法题解中的确定性表现
  • 2026年上海海外推广获客服务商优选,外贸B2B营销+社媒代运营,助力企业出海破局 - 品牌2026
  • .Net基于AgentFramework中智能体Agent Skill集成Shell命令实现小龙虾mini版
  • Qwen3-ASR-0.6B语音识别效果展示:高语速新闻播报实时转写能力
  • 面向复杂工业环境:2026年高可靠边缘计算盒子公司推荐 - 品牌2026
  • 3D Face HRN高性能部署:FP16量化后显存降低42%,精度损失<0.8%实测
  • 通义千问3-VL-Reranker-8B部署指南:防火墙配置与远程访问安全设置
  • 乙巳马年春联生成终端作品分享:企业定制红金配色春联设计集
  • Qwen3-TTS-Tokenizer-12Hz一文详解:从WAV/MP3到离散tokens全流程
  • DeepSeek-R1-Distill-Qwen-1.5B从零开始:本地/root/ds_1.5b路径模型加载全流程
  • [特殊字符] Meixiong Niannian画图引擎参数调优指南:步数/CFG/种子三者协同关系图解
  • Stable-Diffusion-v1-5-archiveGPU算力成本分析:A10单小时生成量与单位图片成本测算
  • 【Triton 教程】triton_language.div_rn
  • Qwen3-Embedding-4B惊艳案例:‘会议改期’匹配‘原定周三的项目评审调整至周五’时间语义推断