javaweb
1HTML
2 CSS
3 JavaScript
HTTP协议
一、 请求协议
不需要自己解析
1请求行
2请求头
3请求体
package com.ithema;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RequestController {
// 请求处理方法
// 不需要自己解析
@RequestMapping("/request")
public String request(HttpServletRequest request) {
//获取请求方式
String method = request.getMethod(); // GET POST
System.out.println("请求方式:" + method);
//获取请求的URL地址
StringBuffer requestURL = request.getRequestURL();
System.out.println("请求URL:" + requestURL); // http://localhost:8080/request
System.out.println("----------------------");
//获取请求的URI 资源访问路径
String requestURI = request.getRequestURI(); // /request
System.out.println("请求URI:" + requestURI);
//获取请求的协议
String protocol = request.getProtocol(); // HTTP/1.1
System.out.println("请求协议:" + protocol);
//请求参数 -name , age;
String name = request.getParameter("name");
String age = request.getParameter("age");
System.out.println("name:" + name);
System.out.println("age:" + age);
// 获取请求头 -Accept
String accept = request.getHeader("Accept");
System.out.println("Accept:" + accept);
System.out.println("----------------------");
return "OK";
}
}
二、响应协议
1响应行 1xx响应中 200成功 3xx重定向 4xx:404 资源不存在 500服务器错误
2响应头
3响应体
package com.ithema;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
@RestController
public class ReceptorController {
@RequestMapping("/response")
public void response(HttpServletResponse response) throws Exception {
//设置响应状态码
response.setStatus(401);
//设置响应头
response.setHeader("name","zhangsan");
//设置响应体
response.getWriter().write("<h1> hello response <h1>");
}
@RequestMapping("/response2")
public ResponseEntity<String> response2(){
return ResponseEntity.status(401).header("name","zhangsan")
.body("<h1> hello response <h1>");
}
}
MySQL
默认端口3306;
二维表 存储数据 格式统一
不区分大小写!
一、SQL语句
1.DDL 定义语言 定义库对象
show databases; 查询所有库
select database(); 查询当前数据库
use + 名字 ;切换数据库
create database “【】” + name ; 添加数据库 【 if not exists 】 如果不存在就创建
drop database “【】” + name; 删除数据库 【if exists】 如果;;
# 创建一张表
create table user(
id int comment 'ID,唯一标识' ,
username varchar(50) comment 'yonghuming' ,
name varchar(10) comment '姓名' ,
age int comment '年龄' ,
gender char(1) comment '性别'
) comment '用户信息表' ;
# 创建一张表
create table user(
id int primary key auto_increment comment 'ID,唯一标识' , #主键约束 auto_increment
username varchar(50) not null unique comment 'yonghuming' , #非空唯一
name varchar(10) not null comment '姓名' ,
age int comment '年龄' ,
gender char(1) default '男' comment '性别'
) comment '用户信息表' ;
show tables ;
desc emp ;
show create table emp;
# 添加字段
alter table emp add qq varchar(13) comment 'QQ' ;
# 修改字段类型
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 ;
2.DML 操作语言 增删改
insert
update
delete
-- DML : 数据操作语言
-- DML : 插入数据 - insert
-- 1. 为 emp 表的 username, password, name, gender, phone 字段插入值
insert into emp(username, password, name, gender, phone) values ('zhaomin','123456','赵敏' , 2 , '19833135744') ;
-- 2. 为 emp 表的 所有字段插入值
# insert into emp(id, username, password, name, gender, phone, job, salary, entry_date, image, create_time, update_time)
# values(null,'zhangsan',null, 'lin',1,'1300030001','1','6000','2020-1-1','1.jpg',now(),now());
insert into emp values(null,'zhangsan',null, 'lin',1,'1300030001','1','6000','2020-1-1','1.jpg',now(),now());
-- 3. 批量为 emp 表的 username, password, name, gender, phone 字段插入数据
-- DML : 更新数据 - update
-- 1. 将 emp 表的ID为1员工 用户名更新为 'zhangsan', 姓名name字段更新为 '张三'
-- 2. 将 emp 表的所有员工的入职日期更新为 '2010-01-01'
delete from emp;
3.DQL 查询语言 查
!!!!!!!
-- =================== DQL: 基本查询 ======================
-- 1. 查询指定字段 name,entry_date 并返回
select name , entry_date from emp;
-- 2. 查询返回所有字段
# 推荐
select id, username, password, name, gender, phone, job, salary, entry_date, image, create_time, update_time from emp;
# 不推荐
select * from emp;
-- 3. 查询所有员工的 name,entry_date, 并起别名(姓名、入职日期)
# as可以省略 有空格加''
select name as 姓名, entry_date as 入职日期 from emp;
-- 4. 查询已有的员工关联了哪几种职位(不要重复)
# distinct 去除重复
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'(包含) 之间的员工信息
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' && gender = 2;
-- 8. 查询 职位是 2 (讲师), 3 (学工主管), 4 (教研主管) 的员工信息
select * from emp where job = 2 || job = 3 || 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 '%二%' ;
-- =================== DQL: 分组查询 ======================
-- 聚合函数
-- 聚合函数不参与null的统计 !!
-- 1. 统计该企业员工数量
select count(job) from emp;
select count(id) from emp;
-- 推荐 * 1
select count(*) from emp;
select count(1) from emp;
-- 2. 统计该企业员工的平均薪资
select avg(salary) from emp;
-- 3. 统计该企业员工的最低薪资
select min(salary) from emp;
-- 4. 统计该企业员工的最高薪资
select max(emp.salary) from emp;
-- 5. 统计该企业每月要给员工发放的薪资总额(薪资之和)
select sum(emp.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;
-- =================== 排序查询 ======================
-- 1. 根据入职时间, 对员工进行升序排序 ASC
select * from emp order by entry_date asc;
# 默认升序排序
select * from emp order by entry_date ;
-- 2. 根据入职时间, 对员工进行降序排序 desc
select * from emp order by entry_date desc ;
-- 3. 根据 入职时间 对公司的员工进行 升序排序 , 入职时间相同 , 再按照 更新时间 进行降序排序
select * from emp order by entry_date ,update_time desc;
-- mysql的分页查询
-- =================== 分页查询 ======================
-- 1. 从起始索引0开始查询员工数据, 每页展示5条记录
select * from emp limit 0,5;
select * from emp limit 5;
-- 2. 查询 第1页 员工数据, 每页展示5条记录
select * from emp limit 0,5;
-- 3. 查询 第2页 员工数据, 每页展示5条记录
select * from emp limit 5,5;
-- 4. 查询 第3页 员工数据, 每页展示5条记录
select * from emp limit 10,5;
# 起始索引 = (页码 - 1) * 每页展示记录数 ;
4.DCL 控制语言 用户权限
sql练习
-- 部门管理
create table tb_dept(
id int unsigned primary key auto_increment comment '主键ID',
name varchar(10) not null unique comment '部门名称',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '修改时间'
) comment '部门表';
insert into tb_dept (id, name, create_time, update_time)
values(1,'学工部',now(),now()),
(2,'教研部',now(),now()),
(3,'咨询部',now(),now()),
(4,'就业部',now(),now()),
(5,'人事部',now(),now());
-- 员工管理
create table tb_emp (
id int unsigned primary key auto_increment comment 'ID',
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 女',
image varchar(300) comment '图像',
job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
entrydate date comment '入职时间',
dept_id int unsigned comment '部门ID',
salary int unsigned comment '工资',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '修改时间'
) comment '员工表';
INSERT INTO tb_emp
(id, username, password, name, gender, image, job, entrydate,dept_id,salary, create_time, update_time) VALUES
(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,20000,now(),now()),
(2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,18000,now(),now()),
(3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,16800,now(),now()),
(4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,12000,now(),now()),
(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,9000,now(),now()),
(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,6000,now(),now()),
(7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,6500,now(),now()),
(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,7200,now(),now()),
(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,5300,now(),now()),
(10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,12000,now(),now()),
(11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,8900,now(),now()),
(12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,7800,now(),now()),
(13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,6800,now(),now()),
(14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,15800,now(),now()),
(15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,11500,now(),now()),
(16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2007-01-01',2,8300,now(),now()),
(17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,4500,now(),now());
-- 薪资等级表
create table tb_salgrade(
grade int comment '等级',
losal int comment '该等级最低薪资',
hisal int comment '该等级最高薪资'
) comment '薪资等级表';
insert into tb_salgrade values (1,0,3000);
insert into tb_salgrade values (2,3001,5000);
insert into tb_salgrade values (3,5001,8000);
insert into tb_salgrade values (4,8001,10000);
insert into tb_salgrade values (5,10001,15000);
insert into tb_salgrade values (6,15001,20000);
insert into tb_salgrade values (7,20001,25000);
insert into tb_salgrade values (8,25001,30000);
-- 1. 查询员工的姓名 , 及所属的部门名称 (隐式内连接实现)
select e.name,d.name from tb_emp e, tb_dept d where e.dept_id = d.id;
-- 2. 查询员工的姓名 , 及所属的部门名称 (显式内连接实现)
select e.name,d.name from tb_emp e join tb_dept d on e.dept_id = d.id;
-- 3. 查询员工的 姓名、性别、职位、部门名称 (隐式内连接)
select e.name,e.gender,e.job,d.name from tb_emp e,tb_dept d where e.dept_id = d.id;
-- 4. 查询 薪资 高于 10000 的员工的姓名、性别、职位、部门名称(显式内连接)
select e.name,e.gender,e.job,d.name from tb_emp e join tb_dept d on e.dept_id = d.id where e.salary > 10000;
-- 5. 查询员工表 所有 员工的姓名, 和对应的部门名称 (左外连接)
select e.name,d.name from tb_emp e left join tb_dept d on e.dept_id = d.id;
-- 6. 查询员工表 所有 员工的姓名, 和对应的部门名称 (右外连接)
select e.name,d.name from tb_dept d right join tb_emp e on e.dept_id = d.id ;
-- 7. 查询部门表 所有 部门的名称, 和对应的员工名称 (右外连接)
select d.name,e.name from tb_emp e right join tb_dept d on e.dept_id = d.id;
-- 8. 查询 "教研部" 的所有员工信息 (标量子查询)
select d.id from tb_dept d where name='教研部';
select * from tb_emp where dept_id = (select d.id from tb_dept d where name='教研部') ;
-- 9. 查询在 "方东白" 入职之后的员工信息 (标量子查询)
select entrydate from tb_emp where name = '方东白';
select * from tb_emp where entrydate > (select entrydate from tb_emp where name = '方东白');
-- 10. 查询 "教研部" 和 "咨询部" 的所有员工信息 (列子查询)
select id from tb_dept where name = '教研部' || name = '咨询部';
select * from tb_emp where dept_id = (select id from tb_dept where name = '教研部')
|| tb_emp.dept_id = (select id from tb_dept where name = '咨询部');
-- 11. 查询与 "韦一笑" 的入职日期 及 职位都相同的员工信息 (行子查询)
select entrydate,job from tb_emp where name = '韦一笑';
select e.* from tb_emp e,(select entrydate an,job j from tb_emp where name = '韦一笑')
en where e.entrydate = en.an && e.job = en.j;
-- 12. 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门信息 (表子查询)
select * from tb_emp e join tb_dept d on e.dept_id = d.id where entrydate > '2006-01-01';
-- 13. 查询 拥有员工的 部门ID、部门名称 (没有员工的部门无需展示)
select e.name,d.id,d.name from tb_emp e join tb_dept d on e.dept_id = d.id;
-- 14. 查询所有 在 2010-01-01 之后入职的员工, 及其归属的部门名称; 如果员工没有分配部门, 也需要展示出来
select e.name,d.name,e.entrydate from tb_emp e left join tb_dept d on e.dept_id=d.id where e.entrydate > '2010-01-01';
-- 15. 查询 "教研部" 员工的平均工资
select avg(e.salary) from tb_emp e join tb_dept d on e.dept_id = d.id where d.name = '教研部';
-- 16. 查询工资比 "俞莲舟" 高的员工信息。
select salary from tb_emp where name = '俞莲舟';
select * from tb_emp where salary > (select salary from tb_emp where name = '俞莲舟') ;
-- 17. 查询 工资 比该企业员工的平均薪资 还要高的员工信息
select avg(salary) from tb_emp;
select * from tb_emp where salary > (select avg(salary) from tb_emp);
-- 18. 查询所有的部门信息, 并统计部门的员工人数
select d.name,count(d.id) from tb_emp e join tb_dept d on e.dept_id = d.id group by d.id;
-- 19. 查询所有员工的 姓名, 工资 , 及 工资等级 (有难度的哦)
select e.name,e.salary,s.grade from tb_emp e join tb_salgrade s on e.salary >= s.losal && e.salary <= s.hisal ;
-- 20. 查询 "教研部" 所有员工的信息 及 工资等级 (有难度的哦)
-- select e.* from tb_emp e join tb_dept d on e.dept_id = d.id where d.name = '教研部';
select e.*,s.grade from (select e.* from tb_emp e join tb_dept d on e.dept_id = d.id where d.name = '教研部') e join tb_salgrade s
on e.salary >= s.losal && e.salary <= s.hisal;
-- 21. 查询 工资 低于 本部门平均工资的员工信息 (有难度的哦)
-- 22. 列出所有部门的详细信息(包括部门ID, 部门名称)和人数
-- 23、取得每个薪资等级有多少员工 (有难度的哦)
-- 24. 取得每个部门最高薪水的人员名称
二、JDBC Java API
Mybatis
spring.application.name=springboot-mybatis
# 配置数据库的链接信息
# 四要素
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=1234
#配置mybatis日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
配置数据库信息
package com.ithema.mapper;
import com.ithema.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper // 自动创建代理对象 ,不需要实现类对象, 自动存入Ioc容器中
public interface UserMapper {
/**
* 查询所有用户
*/
@Select("select * from user")
public List<User> findAll();
}
mapper接口实现
package com.ithema;
import com.ithema.mapper.UserMapper;
import com.ithema.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest // Springboot 测试类的注解,测试方法运行时会启动Springboot项目 -IOC 容器
class SpringbootMybatisApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testFindAll() {
List<User> all = userMapper.findAll();
for (User user : all) {
System.out.println(user);
}
}
}
单元测试 @SpringbootTest 注释 加载 springboot 环境
XML 映射
1,同包同名 返回类型也相同

<?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="com.ithema.mapper.UserMapper">
<!-- resultType 查询返回的单条记录的数据类型-->
<select id="findAll" resultType="com.ithema.pojo.User">
select * from user
</select>
</mapper>
package com.ithema.mapper;
import com.ithema.pojo.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper // 自动创建代理对象 ,不需要实现类对象, 自动存入Ioc容器中
public interface UserMapper {
/**
* 查询所有用户
*/
//@Select("select * from user")
public List<User> findAll();
}
要实现复杂SQL功能需要xml 映射
简单的增删改查用注解
spring.application.name=springboot-mybatis
# 配置数据库的链接信息
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=1234
#配置mybatis日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
==
spring:
application:
name: springboot-mybatis
#数据库连接信息
datasource:
url: jdbc:mysql://localhost:3306/web01
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 1234
#mybatis的配置信息
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
yml格式数字以0开头需要加''否则认为是八进制
手动封装属性名对不上时需要手动封装
<resultMap id="empResultMap" type="com.ithema.pojo.Emp">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="name" property="name"/>
<result column="gender" property="gender"/>
<result column="phone" property="phone"/>
<result column="job" property="job"/>
<result column="salary" property="salary"/>
<result column="image" property="image"/>
<result column="entry_date" property="entryDate"/>
<result column="dept_id" property="deptId"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<collection property="exprList" ofType="com.ithema.pojo.EmpExpr">
<id column="ee_id" property="id"/>
<result column="ee_emp_id" property="empId"/>
<result column="ee_begin" property="begin"/>
<result column="ee_end" property="end"/>
<result column="ee_company" property="company"/>
<result column="ee_job" property="job"/>
</collection>
</resultMap>
<select id="getById" resultMap="empResultMap">
select e.*,ee.id ee_id,ee.emp_id ee_emp_id, ee.begin ee_begin,ee.end ee_end,ee.company ee_company,ee.job ee_job
from emp e left join emp_expr ee on e.id = ee.emp_id
where e.id = #{id}
</select>
logback
Mapper
@Options(useGeneratedKeys = true, keyProperty = "id") // 获取生成的主键值 赋值给emp.id
xml映射 动态sql
<insert id="insertBatch">
insert into emp_expr(emp_id, begin, end, company, job) values
<!-- foreach
collection: 集合
item: 集合中的元素
index: 索引
open: 循环开始
close: 循环结束
separator: 集合元素之间的分隔符
-->
<foreach collection="exprList" item="expr" separator=",">
(#{expr.empId},#{expr.begin},#{expr.end},#{expr.company},#{expr.job})
</foreach>
</insert>
<select id="list" resultType="com.ithema.pojo.Emp">
select e.*,d.name deptName from emp e left join dept d on e.dept_id = d.id
<where>
<if test="name != null and name != ''">
e.name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and e.gender = #{gender}
</if>
<if test="begin != null and end != null">
and e.entry_date between #{begin} and #{end}
</if>
</where>
order by e.update_time desc
</select>