本文用于检验学习效果,忘记知识就去文末的链接复习
1. 网络基础
1.1 计网基础
区分设备:IP地址
区分网络:网络地址
网络互联:路由器
主机上进程间通信:端口
http是常用的协议,基于TCP协议
TCP VS UDP
- TCP
- 有连接(握手,建立连接)
- UDP
- 无连接(不建立连接),快(数据丢失不会重传)
1.2 Socket技术
Socket有什么用?
- 可实现 两台计算机上进程 之间的通信 (通过网络)
复习
- Java创建Socket对象和Server对象
- Socket通信过程(协议,域名,端口)
- 用Socket传输数据(字节,字符)
- Socket传输文件(字节)
- Socket访问浏览器(接收数据是一堆字符,有格式)
2. 数据库基础
什么是数据库?
- 数据的有序集合。数据放在数据表中,便于管理数据。
常见数据库
- MySQL
- Microsoft SQL Server
- Oracle
常见数据库管理软件
- Navicat
- DataGrip
常见配置
- 字符集(支持中文):utf8mb4(utf8只有3字节,有时会出问题)
- 排序规则:utf8mb4_general-ci
2.1 安装一个数据库
一般用MySQL学习
- 本地安装(下载安装包,在本地安装)
- 服务器安装(在服务器上安装MySQL,宝塔面板等,可通过公网IP访问)
- 在线购买(在阿里云,腾讯云上购买云数据库产品)
2.2 数据模型
- 实体-联系模型(Entity-Relationship Model)(E-R MODEL)
- ER图(E-R Diagram)
实体
- 属性
联系
- 1:1
- n:1
- n:m
2.3数据库的规范化
键
- 主键
- 外键
范式(具体定义看书)
(逐层递进,减少数据库间的冗余信息和依赖关系)
- 第一范式(1NF):每一列都不可拆分
- 如:"信息"这个列太模糊,可继续细分
- 第二范式(2NF):表中必须有主键,其他属性完全依赖主键
- 如:"学号"作为主键
- 第三范式(3NF):所有属性不传递依赖于主键
- 处理:分表,消除传递依赖
- BCNF: 每个表只存储一种信息,没有任何冗余信息
2.4 SQL语句
增查改删CRUD(Create/Retrive/Update/Delete)
SQL数据类型
char(n):可存储固定长度为n的字符串
varchar(n):可存储任意数量字符串
存储数字
- smallint
- int
- bigint
- float
- double
存储时间
- date:日期
- time:时间
- year:年份
- datetime:日期+时间
2.4.1 数据库定义语言(Data Definition Language,DDL)
sql
--创建数据库
CREATE DATABASE 数据库名
--删除数据库
DROP DATABASE 数据库名
--创建表
CREATE TABLE
--修改表
ALTER TABLE
--删除表
DROP TABLE
创建数据库study
sql
CREATE DATABASE study;
删除数据库study
sql
DROP DATABASE study;
创建一张表
sql
CREATE TABLE students (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age INT
);
查询数据
查看USER表中的tHost,tUSer列
sql
SELECT tHost,tUSer FROM USER;
修改数据
alter
如果你有一个名为 students 的表,并且你想在这个表中添加一个名为 age 的整数列,你可以使用以下命令:
sql
ALTER TABLE students
ADD age INT;
CONSTRAINT
列级约束条件
- 主键Primary Key
- 外键Foreign Key
- 唯一unique
- 检查check
- 默认default
- 非空/空not null/null
表级约束条件
- 主键Primary Key
- 外键Foreign Key
- 唯一unique
- 检查check
2.4.2 数据操纵语言(Data Manipulation Language,DML)
sql
--插入数据
INSERT INTO
--修改数据
UPDATE 表名 SET 列名=值,... WHERE 条件
--删除数据
DELETE FROM 表名
DELETE FROM 表名 WHERE 条件
2.4.3 数据库查询语言(Data Query Language,DQL)
sql
-- 指定查询某一列数据
SELECT 列名[,列名] FROM 表名
-- 会以别名显示此列
SELECT 列名 别名 FROM 表名
-- 查询所有的列数据
SELECT * FROM 表名
-- 只查询不重复的值
SELECT DISTINCT 列名 FROM 表名
--添加where字句来限定查询目标
SELECT * FROM 表名 WHERE 条件
--将查询结果排序
SELECT * FROM 表名 WHERE 条件 ORDER BY 列名 ASC|DESC
常用查询条件(WHERE中使用)
- =,>,<,>=,<=,!=
- 是否在集合中:
in
,not in
- 模糊匹配:
like
,not like
- 多重连接:
and
,or
,not
排序(默认升序)
- ASC:升序
- DESC:降序
聚集函数
count([distinct]*)
统计所有的行数(distinct表示去重)count([distinct]列名)
统计某列的值总和sum([distinct]列名)
求一列的和(注意必须是数字类型的)avg([distinct]列名)
求一列的平均值(注意必须是数字类型)max([distinct]列名)
求一列的最大值min([distinct]列名)
求一列的最小值
分组/分页查询
- 分组:
GROUP BY
- 分页:
HAVING
- 限制数量:
LIMIT
sql
--分组
SELECT sum(*) FROM 表名 WHERE 条件 GROUP BY 列名
--分页
SELECT sum(*) FROM 表名 WHERE 条件 GROUP BY 列名 HAVING 约束条件
--限制查询的数量,只取前n个结果
SELECT * FROM 表名 LIMIT 数量
多表查询
sql
--默认笛卡尔积
SELECT * FROM 表1, 表2
SELECT * FROM 表1, 表2 WHERE 条件
--自身连接,要起别名
SELECT * FROM 表名 别名1, 表名 别名2
连接
- 外连接
- 内连接
inner join
:交集 - 左连接
left join
:左边都要有,右边缺失值为空 - 右连接
right join
嵌套查询
将一个查询的结果作为另一个查询的条件
sql
SELECT * FROM 表名 WHERE 列名 = (SELECT 列名 FROM 表名 WHERE 条件)
2.4.4 数据库控制语言(Database Control Language,DCL)
sql
--创建用户
CREATE USER 用户名 identified by 密码;
--登录
login -u 用户名 -p
--授权(授权后才可看数据库)
grant all|权限1,权限2...(列1,...) on 数据库.表 to 用户 [with grant option]
--创建视图
CREATE VIEW 视图名称(列名) as 子查询语句 [WITH CHECK OPTION];
--删除视图
drop view apptest
-- 创建索引
CREATE INDEX 索引名称 ON 表名 (列名)
-- 查看表中的索引
show INDEX FROM student
--删除索引
drop index 索引名称 on 表名
--创建触发器
CREATE TRIGGER 触发器名称 [BEFORE|AFTER] [INSERT|UPDATE|DELETE] ON 表名/视图名 FOR EACH ROW DELETE FROM student WHERE student.sno = new.sno
--查看触发器
SHOW TRIGGERS
--删除触发器
DROP TRIGGER 触发器名称
--查看数据库引擎
SHOW ENGINES;
begin; #开始事务
...
rollback; #回滚事务
savepoint 回滚点; #添加回滚点
rollback to 回滚点; #回滚到指定回滚点
...
commit; #提交事务
-- 一旦提交,就无法再进行回滚了!
视图(本质就是一个查询结果)
- 打开视图时,可看到期待的查询结果。
- 是个虚表,不是真实存在的表
索引(快速查询)
- 类似Hash表,可快速定位元素的位置
触发器
- 在某种条件下会自动触发,在
select
/update
/delete
时,会自动执行我们预先设定的内容,触发器通常用于检查内容的安全性,相比直接添加约束,触发器显得更加灵活。 - 触发器所依附的表称为基本表
- new表/old表
事务
- 把一系列SQL操作整理起来,变成一个整体
- ACID特性
- 原子性
- 一致性
- 隔离性
- 持久性
函数&存储过程
- 它们能够捆绑一组SQL语句运行,并且可以反复使用,大大提高工作效率。
3. java与数据库
3.1 JDBC(Java Data Base Connectivity)
- 用java连接数据库,操作数据库
- 定义了接口(规范),接口由数据库实现
- 使用步骤
- 导入依赖(jar包)
- 用JDBC连接数据库
- 操作数据库
JDBC中一些类
- Driver Manager
- Connection
- Statement:用于执行SQL
操作
- DML操作
- DQL操作
批处理(statement.addBatch())
查询结果映射对象
- 把查询结果传进构造函数
- 反射
SQL注入攻击
- 用户在输入数据时,破坏原有的SQL语句,恶意操作数据库
- 可限制用户输入一些SQL语句关键字,但关键字太多,这方法不太好
- 用
PrepareStatement
执行SQL命令,可解决以上问题- 需要给出SQL语句格式
管理事务
sql
con.setAutoCommit(); //关闭自动提交后相当于开启事务。
// 这里是SQL语句
con.commit();或 con.rollback();
3.2 Lombok
- 自动生成set/get/构造函数
- 编译时处理代码(修改语法树),加上函数
使用方法
- 导入jar包(将jar文件拖入idea,右键-添加为项目)
- 在IDEA中下载插件
标签
- java中的goto
lombok注解
- 减少样板代码,使得 Java 类更加清晰和简洁。
- 在类 前加注解,在 方法/属性 前加注解
- 可定义访问权限
- AccessLevel.PUBLIC
- AccessLevel.PRIVATE
- @Setter
- @Getter
- @ToString
- exclude:省略一些内容
- of:留下一些内容(与exclude相反的)
- callsuper:toString中调用父类的toString方法
- 调用get方法,获取属性
- doNotUseGetters:不用get方法,直接用属性
- onlyExplicitlyIncluded:是否包含全部字段
- @ToString.Include:指定要包含的字段
- rank:越大,等级越高
- name:别名
- @EqualsAndHashCode
- @AllArgsConstructor:有所有参数的构造函数
- staticName:静态函数,返回一个对象
- force:给final类型变量一个默认值
- @NoArgsConstructor:无参数的构造函数
- @RequiredArgsConstructor:只构造需要构造 的属性
- final类型变量
- @Data
- 包含@Setter,@Getter,@RequiredArgsConstructor,@ToString,@EqualsAndHashCode
- 不建议有继承关系,因为equal方法结果可能与预期不符
- @Value
- 不会生成setter,成员属性都是final的
- @SneakyThrows:自动生成try-catch代码块
- Exception.class
- IOException.class
- @Cleanup:自动调用close(如IO流,用完要close)
- @Builder:快速生成建造者模式
-
@Builder.Default:指定默认值
-
@Builder.ObtainVia:指定默认值的获取方式
-
setterPrefix:方法名前加前缀
-
.Default:属性默认值
-
.ObtainVia:在Builder过程中通过指定方法,指定属性值
-
toBuilder:把对象变回Builder
getter中懒加载有什么用
在编程中,lazy 属性或特性通常用于实现懒加载(lazy loading)模式。
懒加载意味着对象的某些属性或资源的初始化会延迟到它们真正被需要时才进行,而不是在对象创建时立即进行。
这种策略对于优化性能非常有用,特别是在处理计算密集型操作或需要消耗大量资源的操作时。在 getter 上下文中,lazy 属性可以确保当你第一次访问某个属性时,其背后的计算或初始化操作才会执行,
并且其结果会被缓存起来,以便后续访问时直接返回,而不需要重新计算或初始化。
-
3.3 Mybatis
JDBC还是不够好用,用Mybatis可更方便地操作数据库
知道什么是XML
- XML语法跟HTML很像。里面写的是配置
配置
- mybatis-config.xml
- TestMapper.xml
- pojo文件/entity文件中创建java类
- 写selectList
- 不够方便,怎么办?
- 用接口
xxxMapper.java
,与TestMapper.xml相关联
修改xml,切换数据库环境
数据源
别名
增删改查
- 读取到数据后,可映射为实体类 或map
- 通过resultMap设定映射规则
- 通过constructor设定要调用的构造函数
自动映射:首字母小写,后面的驼峰
类中有多个构造方法【容易出问题】
- 只能有一个构造方法(有条件的,多了会出问题)
- 部分参数被构造方法使用,实体类没有被正确构建
按学号查找信息
- select * from student where sid = #{sid}
插入学生信息
- insert student(name,sex) values(#{name}, #{sex})
"一对多"
- resultMap
- collection
"多对一"
-resultMap
- association
事务
动态SQL
- if
- chooose(when, otherwise)
- trim(where, set)
- foreach
缓存机制
何时清空缓存?
- 插入操作后
- 会话结束后
缓存分级
- 优先级:二级----一级---数据库(cache---主存---硬盘)
- 一级缓存(对应session)
- 二级缓存(对应mapper)(需要启用)
解决缓存机制导致的不一致问题
- 关闭缓存(但存取数据时会有额外开销)
使用注解开发
- 在mybatis-config.xml中的< mappers >中注册
- 单独注册< mapper>
- 批量注册< packge >
- @select等
- @many/@one
- @ConstructorArgs
3.4 JUnit(单元测试)
测试某个小功能时,没必要重新启动整个项目
使用步骤
- 导入jar包
- 编写测试用例,加注解
- @Test
- 断言Assert.
- @Before:前置操作(@Test执行前,会执行这个)
- 有些前置操作只需要一次,怎么办?(juint5)
- @After
JUL日志系统(JDK提供的)
- 使用流程
- 获取日志打印器
- 调用info,输出信息
日志级别(高到低)
- SEVERE:严重错误
- WARNING:某些警告
- INFO:(默认)常规消息(该等级以下默认不会被打印)
- CONFIG
- FINE
- FINER
- FINEST
我们想:开发时输出所有日志,上线后正常输出日志
输出所有日志
- 修改日志级别
- 不使用默认日志处理器
- 使用自定义日志处理器
可以用文件处理器打印日志
可以添加过滤器,不让某些日志显示
了解Properties配置文件
- 常见操作
- Properties类
- properties.load
- properties.store
- hashtable VS hashmap
可用lombok快速开发日志
- @Log
Mybatis也有日志系统
- 启用
- 读取配置
4. Maven(管理项目)
Maven能管理jar包(手动导入太麻烦)
在IDEA中
- 创建maven项目
- 配置maven路径,
IDEA的设置中
- 设置默认maven配置,在
C:\Users\用户\AppData\Roaming\JetBrains\IntelliJIdea2023.3\options
如何导入jar包
- 在官网找到插入依赖的xml
- 插入到pom中
依赖属性
- type
- scope:依赖的作用域
- compile:编译,测试,运行时有效
- provided:编译,测试时有效(lombok)
- runtime:运行,测试时有效
- test:测试时有效(JUnit)
- optional
- exclusions
从本地找依赖
xml
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-local-lib</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/my-local-lib-1.0.jar</systemPath>
</dependency>
</dependencies>
可选依赖
xml
<optional>true</optional>
排除依赖
xml
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
</exclusion>
</exclusions>
依赖的继承关系
- 父项目中的
<dependencies>
,会被子项目直接继承 - 父项目中的
<dependencyManagement>
,在子项目中引入后,也可继承(不用写版本号) - 子项目间也可互相导入
maven常用命令
clean
:清除target中的文件validate
:验证项目的可用性compile
:编译项目install
:将当前项目安装到本地maven仓库(之后可被其他项目导入)verify
:按顺序执行默认生命周期阶段(validate,compile,package)test
:执行test目录下的所有测试用例package
:把项目打包为jar包(默认不含依赖)- pom中添加插件,可将依赖也一并打包
deploy
:发布命令到本地仓库和远程仓库site
:生成当前项目的发布站点