Bootstrap

JavaWeb-后端实战

7.1 准备工作

在这里插入图片描述
在这里插入图片描述

7.1.1 开发规范

7.1.1.1 开发模式

(1)前后端混合开发,已淘汰
在这里插入图片描述
(2)前后端分离开发
在这里插入图片描述
在这里插入图片描述

7.1.1.2 Restful风格

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

7.1.2 Apifox

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

7.1.3 工程搭建

在这里插入图片描述
1、先创建空项目project:
在这里插入图片描述
2、确定JDK
在这里插入图片描述
在这里插入图片描述
3、确认maven
在这里插入图片描述
4、配置字符集-UTF-8
在这里插入图片描述
5、新建SpringBoot工程
在这里插入图片描述
依赖: lombok、SpringWeb、MyBatis Framework、MySQL Driver(MySQL驱动)
在这里插入图片描述
在这里插入图片描述
生成的工程只需要保留:src、xml、iml,其他的可以删掉;
前后端分离开发,static一般不存放静态页面,templates一般不存放模板文件,可以删掉;
使用yml格式的配置文件,properties改成yml
在这里插入图片描述
新建数据库tlias,在数据库中
在这里插入图片描述
新建Query Console(查询控制台),在里面使用SQL语句建表
在这里插入图片描述

CREATE TABLE dept (
  id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主键',
  name varchar(10) NOT NULL UNIQUE COMMENT '部门名称',
  create_time datetime DEFAULT NULL COMMENT '创建时间',
  update_time datetime DEFAULT NULL COMMENT '修改时间'
) COMMENT '部门表';

INSERT INTO dept VALUES (1,'学工部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
                      (2,'教研部','2024-09-25 09:47:40','2024-09-09 15:17:04'),
                      (3,'咨询部','2024-09-25 09:47:40','2024-09-30 21:26:24'),
                      (4,'就业部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
                      (5,'人事部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
                      (6,'行政部','2024-11-30 20:56:37','2024-09-30 20:56:37');


-- 查询全部的部门
select id, name, create_time, update_time from dept order by update_time desc;


-- 根据ID更新部门数据
update dept set name = '', update_time = '' where id = 1;

yml文件配置信息:

spring:
  application:
    name: tlias-web-management
    # 配置数据库的连接信息
    datasource:
      url: jdbc:mysql://localhost:3306/tlias
      driver-class-name: com.mysql.cj.jdbc.Driver
      username: root
      password: 1234

# MyBatis的相关配置
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mapper/*xml

7.2 部门管理

7.2.1 列表查询

7.2.1.1 列表查询–接口开发

(1)页面原型
在这里插入图片描述

(2)数据库建库建表

CREATE TABLE dept (
  id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主键',
  name varchar(10) NOT NULL UNIQUE COMMENT '部门名称',
  create_time datetime DEFAULT NULL COMMENT '创建时间',
  update_time datetime DEFAULT NULL COMMENT '修改时间'
) COMMENT '部门表';

INSERT INTO dept VALUES (1,'学工部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
                      (2,'教研部','2024-09-25 09:47:40','2024-09-09 15:17:04'),
                      (3,'咨询部','2024-09-25 09:47:40','2024-09-30 21:26:24'),
                      (4,'就业部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
                      (5,'人事部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
                      (6,'行政部','2024-11-30 20:56:37','2024-09-30 20:56:37');


-- 查询全部的部门
select id, name, create_time, update_time from dept order by update_time desc;


-- 根据ID更新部门数据
update dept set name = '', update_time = '' where id = 1;

(3)思路分析
在这里插入图片描述
(4)代码实现:
Controller层:

// @RestController等于@Controller+@RequestBody,
@RequestMapping("/depts")
@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;

    // @RequestMapping(value = "/depts", method = RequestMethod.GET) // method:指定请求方式
//    @GetMapping("/depts")
    @GetMapping
    public Result list() {
        System.out.println("查询全部的部门数据");
        List<Dept> deptList = deptService.findAll();
        return Result.success(deptList);
    }
}

Service层:

public interface DeptService {

    /**
     * 查询所有的部门数据
     * @return
     */
    List<Dept> findAll();
}

Service实现:

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> findAll() {
        return deptMapper.findAll();
    }
}

Mapper层:

@Mapper
public interface DeptMapper {

    /**
     * 查询所有的部门数据
     * @return
     */
    @Select("select id, name, create_time, update_time from dept order by update_time desc")
    // 方式一
//    @Results({
//            @Result(column = "create_time", property = "createTime"),
//            @Result(column = "update_time", property = "updateTime")
//    })

    // 方式二
//    @Select("select id, name, create_time createTime, update_time updateTime from dept order by update_time")
    List<Dept> findAll();
}

在这里插入图片描述

结果:
在这里插入图片描述
注意到,createTime和updateTime字段返回的数据为null,原因:
在这里插入图片描述
三种方式可以解决,推荐使用第三种
在这里插入图片描述
开启驼峰命名法,关键字 骆驼 camel

spring:
  application:
    name: tlias-web-management
  #数据库的连接信息
  datasource:
    url: jdbc:mysql://localhost:3306/tlias
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 1234

#Mybatis相关配置
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
    #开启驼峰命名映射开关
    map-underscore-to-camel-case: true

在这里插入图片描述

7.2.1.2 列表查询–前后端联调

在这里插入图片描述
conf文件下为nginx的配置文件:
在这里插入图片描述
html文件下为nginx所需要部署的前端项目:
在这里插入图片描述logs文件下为nginx运行的日志:
在这里插入图片描述
【nginx.exe】为nginx启动文件,双击一闪而过,在windows环境下则运行成功:
在这里插入图片描述
在这里插入图片描述
查看nginx配置,地址为localhost,监听90端口:
在这里插入图片描述
F12打开开发者工具,并刷新页面:
在这里插入图片描述
点击XHR:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2.2 删除部门

需求接口文档:
在这里插入图片描述
在这里插入图片描述
思路分析:
在这里插入图片描述
代码实现:
方式一:
在这里插入图片描述
方式二:
在这里插入图片描述

    /**
     * 删除部门
     * @param deptId
     * @return
     * 方式二:@RequestParam
     * 注意事项:一旦声明了@RequestParam,该参数在请求时必须传递,如果不传递将会报错,默认 required 为 true
     */
    @DeleteMapping
    public Result deleteById(@RequestParam("id") Integer deptId) {
        System.out.println("删除ID为:" + deptId + "部门");
        Integer count = deptService.deleteById(deptId);
        System.out.println("删除了" + count + "个部门");
        return Result.success();
    }

报错:
在这里插入图片描述
@RequestParam源码:
在这里插入图片描述在这里插入图片描述
方式三:

    /**
     * 删除部门
     * @param id
     * @return
     * 方式三:省略@RequestParam,前端传递的请求参数名与服务端方法形参名一直
     */
    @DeleteMapping
    public Result deleteById(Integer id) {
        System.out.println("删除ID为:" + id + "部门");
        Integer count = deptService.deleteById(id);
        System.out.println("删除了" + count + "个部门");
        return Result.success();
    }

Service:

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

    @Override
    public List<Dept> findAll() {
        return deptMapper.findAll();
    }

    @Override
    public Integer deleteById(Integer id) {
        return deptMapper.delete(id);
    }
}

Mapper:

    /**
     * 根据ID删除部门
     * @param id
     */
    @Delete("delete from dept where id = #{id}")
    Integer delete(Integer id);

在这里插入图片描述
在这里插入图片描述

7.2.3 新增部门

需求接口文档:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:@RequestBody注解使用在方法形参为数据类时,用于将传入的JSON字符转成数据类形式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2.4 查询和修改部门

修改部门的操作包括两个步骤:查询部门和修改部门

7.2.4.1 查询部门

需求接口文档:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

    /**
     * 查询部门(根据ID)
     * @param id
     */
    @Select("select id, name, create_time, update_time from dept where id = #{id}")
    Dept select(Integer id);

在这里插入图片描述

7.2.4.2 修改部门

需求接口文档:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.2.5 日志技术

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 控制台输出 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度  %logger{50}: 最长50个字符(超出.切割)  %msg:日志消息,%n是换行符 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <!-- 日志输出级别 -->
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
package com.itheima;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogTest {

    private static final Logger log = LoggerFactory.getLogger(LogTest.class);

    @Test
    public void testLog(){
//        System.out.println(LocalDateTime.now() + " : 开始计算...");
        log.debug("开始计算...");

        int sum = 0;
        int[] nums = {1, 5, 3, 2, 1, 4, 5, 4, 6, 7, 4, 34, 2, 23};
        for (int num : nums) {
            sum += num;
        }
        
//        System.out.println("计算结果为: "+sum);
//        System.out.println(LocalDateTime.now() + "结束计算...");
        log.info("计算结果为:" + sum);
        log.debug("结束计算...");
    }

}

Logger使用的是SLF4J这个接口(即面向接口编程)
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<!-- 控制台输出 -->
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%logger显示日志记录器的名称, %msg表示日志消息,%n表示换行符 -->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
		</encoder>
	</appender>

	<!-- 系统文件输出 -->
	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
			<!-- 日志文件输出的文件名, %i表示序号,从0开始 -->
			<FileNamePattern>D:/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
			<!-- 最多保留的历史日志文件数量 -->
			<MaxHistory>30</MaxHistory>
			<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
			<maxFileSize>10MB</maxFileSize>
		</rollingPolicy>

		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<!--格式化输出:%d 表示日期,%thread 表示线程名,%-5level表示级别从左显示5个字符宽度,%msg表示日志消息,%n表示换行符 -->
			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
		</encoder>
	</appender>

	<!-- 日志输出级别,此处all或OFF不区分大小写 -->
	<root level="ALL"> 
		<appender-ref ref="STDOUT" />
		<appender-ref ref="FILE" />
	</root>
</configuration>


在这里插入图片描述在这里插入图片描述
在这里插入图片描述

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;