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,同包同名 返回类型也相同

image-20250805160219863

<?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>

迷茫java练习生