1、思路分析

使用的数据库语句是:
select id,name,create_time,update_time from dept order by update_time desc;
实现按倒序的更新时间进行展示数据
首先在Controller中进行编写:
package com.itheima.controller;
import com.itheima.pojo.Dept;
import com.itheima.pojo.Result;
import com.itheima.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@RequestMapping("/depts")//请求路径
public Result list() {
System.out.println("查询全部部门数据");
List<Dept> deptList= deptService.findAll();
return Result.success(deptList);
}
}
之后在DeptService中编写:
package com.itheima.service;
import com.itheima.pojo.Dept;
import java.util.List;
public interface DeptService {
List<Dept> findAll();
}
继续在service的实现类中编写:
package com.itheima.service.impl;
import com.itheima.mapper.DeptMapper;
import com.itheima.pojo.Dept;
import com.itheima.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public List<Dept> findAll() {
return deptMapper.findAll();
}
}
最后在Mapper中编写:
package com.itheima.mapper;
import com.itheima.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface DeptMapper {
@Select("select id,name,create_time,update_time from dept order by update_time desc;")
List<Dept> findAll();
}
并在右侧的数据库中引入tlias数据,之后启动项目,在apifox中输入以下地址:http://localhost:8080/depts
结果为:


虽然上述的id和name都封装正确,但是createtime和updatetime并未正确封装!
主要原因是字段名不一致导致!
解决方法:
(1)手动封装

在Mapper中进行更改:
package com.itheima.mapper;
import com.itheima.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface DeptMapper {
@Results({
@Result(column = "create_time", property = "createTime"),
@Result(column = "update_time", property = "updateTime")
})
@Select("select id,name,create_time,update_time from dept order by update_time desc;")
List<Dept> findAll();
}
结果如下:成功封装!!!

(2)在数据库语言中起别名

将Mapper中的数据库语言进行更改:
@Select("select id,name,create_time createTime,update_time updateTime from dept order by update_time desc;")
结果如下:成功实现!

(3)驼峰命名(推荐!!!)

在application.yml文件中定义:
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
结果正常输出!!!
之后为了对请求方法get进行限制:
首先需要将控制类中的注解进行更改。方法为get :
@RequestMapping(value = "/depts",method= RequestMethod.GET)//请求路径
重新启动项目!
或者直接更改为:
@GetMapping("/depts")
即可实现以上功能!
2、查询部分前后端联调
首先下载nginx的内容并解压缩到之前存储各类软件的文件夹中(不包含中文以及空格),在下面的网页中可以下载!
下载成功之后,点击
,如果一闪而过代表启动成功,并可以在任务管理器中查看!
之后在网页中输入:http://localhost:90/index
运行之后展示如下页面:

之后启动idea项目,并点击系统信息管理的部门管理,结果如下所示:

前后端联调主要使用了Nginx进行反向代理
使用反向代理使得前端在分配任务时并不需要知道后端的具体地址交给代理即可,代理通过后端的请求压力等均衡的给后端服务器进行分配任务!


3、删除部门

三层架构:

由于这个功能需要根据id号进行删除数据,因此需要传递一个数,如下所示:

或者如果前端请求参数名与形参变量名一样,可直接省略注解!

首先对controller进行更改:
@DeleteMapping("/depts")
public Result delete(Integer id) {
System.out.println("删除部门数据");
deptService.delete(id);
return Result.success();//删除是不需要返回数据的
}
之后对service进行添加,因为不需要返回值,因此使用void:
void delete(Integer id);
对serviceimpl进行添加:
@Override
public void delete(Integer id) {
deptMapper.delete(id);
}
最后对mapper进行添加:这里使用的是动态更改id值
@Delete("delete from dept where id=#{id}")
void delete(Integer id);
最后运行程序,首先查看数据库,一共有6条数据

之后在apifox选择delete接口,输入:http://localhost:8080/depts?id=6
表明要删除id=6的数据,运行程序之后数据库数据删除:

java显示:

之后在http://localhost:90/dept 网页也可以进行删除!


4、新增部门



在controller中新增一个接口:
@PostMapping("/depts")
public Result add(@RequestBody Dept d) {
System.out.println("添加部门数据");
deptService.add(d);
return Result.success();
}
之后在service中新增:
void add(Dept d);
之后在serviceimpl中新增具体的实现类:
@Override
public void add(Dept d) {
//补全基础属性
d.setCreateTime(LocalDateTime.now());
d.setUpdateTime(LocalDateTime.now());
deptMapper.add(d);
}
最后在mapper中新增:
@Insert("insert into dept(name,create_time,update_time) values (#{name},#{createTime},#{updateTime})")
void add(Dept d);
先在apifox中测试:输入:http://localhost:8080/depts
之后在body的json中输入name属性,点击发送即可

结果如下所示:

之后刷新网页,可以实现新增功能:


5、修改功能




当请求的参数名和形参一致时,可以省略请求的参数名!
首先完成查询回显步骤:
controller:
@GetMapping("/depts/{id}")
public Result selectbyid(@PathVariable Integer id){
System.out.println("查询部门数据");
Dept de= deptService.selectbyid(id);//需要将查询到的数据返回给前端,返回的数据只有一行
return Result.success(de);
}
之后是service:
Dept selectbyid(Integer id);
之后是实现类:
@Override
public Dept selectbyid(Integer id) {
return deptMapper.selectid(id);
}
最后是mapper类:
@Select("select id,name,create_time,update_time from dept where id=#{id}")
Dept selectid(Integer id);
最后在前端服务器中刷新,启动后端项目,并随即点击一个修改:
回显成功!!!

之后进行修改数据!

首先是controller:
@PutMapping("/depts")
public Result update(@RequestBody Dept d) {
System.out.println("修改部门数据");
deptService.update(d);
return Result.success();
}
之后是service:
void update(Dept d);
接下来是实现类:
@Override
public void update(Dept d) {
d.setUpdateTime(LocalDateTime.now());
deptMapper.update(d);
}
最后是mapper:
@Update("update dept set name=#{name},update_time=#{updateTime} where id=#{id}")
void update(Dept d);
之后启动项目,重新刷新前端网页,对其中某一个进行修改,结果可得:先显示实际值,之后修改显示修改后的值!!!


在controller中,由于存在公共的路径,因此可以进行抽取,如右所示:

对controller进行修改,提取公共的路径:
package com.itheima.controller;
import com.itheima.pojo.Dept;
import com.itheima.pojo.Result;
import com.itheima.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequestMapping("/depts")
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
// @RequestMapping(value = "/depts",method= RequestMethod.GET)//请求路径
@GetMapping
public Result list() {
System.out.println("查询全部部门数据");
List<Dept> deptList= deptService.findAll();
return Result.success(deptList);
}
@DeleteMapping
public Result delete(Integer id) {
System.out.println("删除部门数据");
deptService.delete(id);
return Result.success();//删除是不需要返回数据的
}
@PostMapping
public Result add(@RequestBody Dept d) {
System.out.println("添加部门数据");
deptService.add(d);
return Result.success();
}
@GetMapping("/{id}")
public Result selectbyid(@PathVariable Integer id){
System.out.println("查询部门数据");
Dept de= deptService.selectbyid(id);//需要将查询到的数据返回给前端,返回的数据只有一行
return Result.success(de);
}
@PutMapping
public Result update(@RequestBody Dept d) {
System.out.println("修改部门数据");
deptService.update(d);
return Result.success();
}
}
功能正常实现!!!
6、日志功能


不需要引入依赖,在springboot中已经传递下来!

首先在resource中新建一个logback.xml


其中的代码为:
<?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 表示日期,SSS表示毫秒,%thread 表示线程名 -->
<!--%-5level表示级别从左显示5个字符宽度,因为debug是5个字符,而info是4个,为了统一,都显示5个字符-->
<!-- %logger 日志记录器的名字,{50} 最多展示50个字符,超出就自动简化,%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表示序号 以下表示文件的存储位置!!!-->
<FileNamePattern>D:/test/tlias-%d{yyyy-MM-dd}-%i.log</FileNamePattern>
<!-- 最多保留的历史日志文件数量 -->
<MaxHistory>30</MaxHistory>
<!-- 最大文件大小,超过这个大小会触发滚动到新文件,默认为 10MB -->
<maxFileSize>10MB</maxFileSize>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="ALL"><!--如果要整体统一管理,all表示打开日志开关,off表示关闭日志开关-->
<!--如果不想要以下某一个日志,直接注释即可-->
<appender-ref ref="STDOUT" /> <!--输出到控制台-->
<appender-ref ref="FILE" /><!--输出到文件,上面已经定义,这里属于引用-->
</root>
</configuration>
之后在test中新建一个类,并定义一个静态常量,导入的类是slf4j

对于LoggerFactory也是导入slf4j的类

之后补全测试:
package com.itheima;
import ch.qos.logback.classic.LoggerContext;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogTest {
private static final Logger logger = LoggerFactory.getLogger(LogTest.class);
@Test
public void testlog(){
logger.debug("开始计算---");
int sum=0;
int[] nums={1,3,5,7,9,11,13,15,17,19};
for(int num:nums){
sum+=num;
}
logger.info("计算结果为:"+sum);
logger.debug("结束计算---");
}
}
输出结果为:

此外对于log配置中的日志级别:
如果将这个级别配置为debug,则级别大于等于debug的日志都会输出!!!

如果将级别配置成info

那么结果就展示级别大于等于info的日志,如下所示:

如果在原来的测试类中添加以下代码:
logger.trace("trace...");
logger.warn("warn...");
logger.error("error...");
将配置文件xml的日志级别设置成debug,结果如下所示:

除了比debug低的trace之后,其余都按顺序输出!!!
之后改写tlias项目的controller中有关system的内容,之前是对Logger对象进行声明,现在可以直接在方法上面添加注解:

以下是这个注解的源代码,因此之后使用日志,其常量就是log即可!!!

在删除的日志中,不使用拼接,而是通过{}占位符的方式,几个占位符,后边就传递几个参数!
log.info("删除部门数据:{}",id);
将日志级别设置成info,输出结果如下:

总结:
