Web day07 项目实战

目录

Restful风格:

代码结构:

 1). Controller层

2). Service层

3). Mapper(dao)层

4).yml文件:

数据封装:

1). 手动结果映射

2). 起别名

3). 开启驼峰命名(推荐)

删除部门:

新增部门:

修改数据:

日志技术(重要):

记录日志:

Logback配置文件:

1). 如果需要输出日志到控制台。添加如下配置:

2). 如果需要输出日志到文件。添加如下配置:

3). 日志开关配置 (开启日志(ALL),取消日志(OFF))

Logback日志级别:


Restful风格:

在前后端分离的开发模式中,前后端开发人员都需要根据提前定义好的接口文档,来进行前后端功能的开发。

传统URL风格如下:

http://localhost:8080/user/getById?id=1 GET:查询id为1的用户

  • http://localhost:8080/user/saveUser POST:新增用户

  • http://localhost:8080/user/updateUser POST:修改用户

  • http://localhost:8080/user/deleteUser?id=1 GET:删除id为1的用户

我们看到,原始的传统URL呢,定义比较复杂,而且将资源的访问行为对外暴露出来了。而且,对于开发人员来说,每一个开发人员都有自己的命名习惯,就拿根据id查询用户信息来说的,不同的开发人员定义的路径可能是这样的:getByIdselectByIdqueryByIdloadById... 。 每一个人都有自己的命名习惯,如果都按照各自的习惯来,一个项目组,几十号或上百号人,那最终开发出来的项目,将会变得难以维护,没有一个统一的标准。

基于REST风格URL如下:

  • http://localhost:8080/users/1 GET:查询id为1的用户

  • http://localhost:8080/users POST:新增用户

  • http://localhost:8080/users PUT:修改用户

  • http://localhost:8080/users/1 DELETE:删除id为1的用户

通过URL定位要操作的资源,通过HTTP动词(请求方式)来描述具体的操作。

  • GET : 查询

  • POST :新增

  • PUT : 修改

  • DELETE :删除

我们看到如果是基于REST风格,定义URL,URL将会更加简洁、更加规范、更加优雅

代码结构:

 1). Controller层

post添加 get查询 put修改 delete删除

get后无参数时 查询 全部 后有参数时用 @GetMapping("/{id}") 解析restful风格的参数

@RestController
@RequestMapping("/depts")
public class DeptController {

    @Autowired
    private DeptService deptService;

    @GetMapping
    public Result findAll(){
        List<Dept> all = deptService.findAll();
        return Result.Success(all);
    }

    /*@DeleteMapping
    public Result delete(Integer id){
        deptService.delete(id);
        return Result.Success("删除成功");
    }*/

    @DeleteMapping
    public Result delete(@RequestParam("id") Integer id){
        deptService.delete(id);
        return Result.Success("删除成功");
    }

    @PostMapping
    public Result addDept(@RequestBody Dept dept){
        deptService.addDept(dept);
        return Result.Success("添加成功");
    }

    @GetMapping("/{id}")
    public Result findById(@PathVariable Integer id){
        Dept dept = deptService.findById(id);
        return Result.Success(dept);
    }

    @PutMapping
    public Result update(@RequestBody Dept dept){
        deptService.updateDept(dept);
        return Result.Success("修改成功");
    }

}

2). Service层

接口:

public interface DeptService {
    List<Dept> findAll();

    Integer delete(Integer id);

    void addDept(Dept dept);

    Dept findById(Integer id);

    void updateDept(Dept dept);

}

实现类:

@Service
public class DeptServiceImpl implements DeptService {

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

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

    @Override
    public void addDept(Dept dept) {
        dept.setCreate_time(LocalDateTime.now());
        dept.setUpdate_time(LocalDateTime.now());
        deptMapper.insert(dept);
    }

    @Override
    public Dept findById(Integer id) {
        Dept dept = deptMapper.selectById(id);
        return dept;
    }

    @Override
    public void updateDept(Dept dept) {
        dept.setUpdate_time(LocalDateTime.now());
        deptMapper.update(dept);
    }
}

3). Mapper(dao)层

@Mapper
public interface DeptMapper {

    @Select("select * from dept")
    List<Dept> selectAll();

    @Delete("delete from dept where id=#{id}")
    int deleteById(Integer id);

    @Insert("insert into dept values (null,#{name},#{create_time},#{update_time})")
    void insert(Dept dept);


    @Select("select * from dept where id=#{id}")
    Dept selectById(Integer id);

    @Update("update dept set name=#{name},update_time=#{update_time} where id=#{id}")
    void update(Dept dept);
}

4).yml文件:

spring:
  application:
    name: tlias-manager-sys
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/test
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 1234
    type: com.alibaba.druid.pool.DruidDataSource
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

数据封装:

注意只有在查询时 数据库mybaits 框架自动返回对象时才会产生这个问题

当自定义实体类的 名字 和 数据库的字段名不完全一样时 在查询时:就会有不能自动封装的问题

解决方案:

  • 手动结果映射

  • 起别名

  • 开启驼峰命名

1). 手动结果映射

在DaoMapper接口方法上,通过 @Results及@Result 进行手动结果映射。

@Results({@Result(column = "create_time", property = "createTime"),
          @Result(column = "update_time", property = "updateTime")})
@Select("select id, name, create_time, update_time from dept")
public List<Dept> findAll();

2). 起别名

在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样。

@Select("select id, name, create_time createTime, update_time updateTime from dept")
public List<Dept> findAll();

3). 开启驼峰命名(推荐)

如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射。驼峰命名规则: abc_xyz => abcXyz

  • 表中字段名:abc_xyz

  • 类中属性名:abcXyz

在application.yml中做如下配置,开启开关。

mybatis:
  configuration:
    map-underscore-to-camel-case: true

 

删除部门:

  • 方案一:通过原始的 HttpServletRequest 对象获取请求参数

  • 方案二:通过Spring提供的 @RequestParam 注解,将请求参数绑定给方法形参

  • 方案三:如果请求参数名与形参变量名相同,直接定义方法形参即可接收。(省略@RequestParam)

新增部门:

/**
 * 根据ID查询 - GET http://localhost:8080/depts/1
 */
@GetMapping("/depts/{id}")
public Result getById(@PathVariable Integer id){
    System.out.println("根据ID查询, id=" + id);
    Dept dept = deptService.getById(id);
    return Result.success(dept);
}

 @RequestBody 注解 可以将post请求体中 传入的json 数据 自动封装为  Dept对象 

@RequsetParam 可以自动获取 URL风格的传参 (localhost:8080/depts?id=3)例如

@DeleteMapping()
    public Result delete(@RequestParam("id") Integer id){
        deptService.delete(id);
        return Result.Success("删除成功");
    }

如果使用 restful 风格 传参 需要使用 @PathVariable 修饰参数 

/**
 * 根据ID查询 - GET http://localhost:8080/depts/1
 */
@GetMapping("/depts/{id}")
public Result getById(@PathVariable Integer id){
    System.out.println("根据ID查询, id=" + id);
    Dept dept = deptService.getById(id);
    return Result.success(dept);
}

修改数据:

修改数据时用 PutMapping注解修饰方法 前端服务器 用put方法发送请求json数据 时 会根据键

配对 实体类中的 变量名  运用 @RequsetBody 注解自动封装到 实体类对象中 

日志技术(重要):

日志框架:

准备工作:引入logback的依赖(springboot中无需引入,在springboot中已经传递了此依赖)

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.4.11</version>
</dependency>

引入配置文件 logback.xml (资料中已经提供,拷贝进来,放在 src/main/resources 目录下; 或者直接AI生成)

<?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个字符宽度  %msg:日志消息,%n是换行符 -->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}-%msg%n</pattern>
        </encoder>
    </appender>

    <!-- 日志输出级别 -->
    <root level="ALL">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

记录日志:

使用@Slf4j   注解即可使用 会自动创建 Logger 对象

public class LogTest {
    
    //定义日志记录对象
    private static final Logger log = LoggerFactory.getLogger(LogTest.class);

    @Test
    public void testLog(){
        log.debug("开始计算...");
        int sum = 0;
        int[] nums = {1, 5, 3, 2, 1, 4, 5, 4, 6, 7, 4, 34, 2, 23};
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        log.info("计算结果为: "+sum);
        log.debug("结束计算...");
    }

}

Logback配置文件:

1). 如果需要输出日志到控制台。添加如下配置:

<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <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>

2). 如果需要输出日志到文件。添加如下配置:

<!-- 按照每天生成日志文件 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <!-- 日志文件输出的文件名, %i表示序号 -->
        <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>

3). 日志开关配置 (开启日志(ALL),取消日志(OFF))

<!-- 日志输出级别 -->
<root level="ALL">
    <!--输出到控制台-->
    <appender-ref ref="STDOUT" />
    <!--输出到文件-->
    <appender-ref ref="FILE" />
</root>

Logback日志级别:

trace 几乎不使用 会用 debug替代

lombok中提供的@Slf4j注解,可以简化定义日志记录器这步操作。添加了该注解,就相当于在类中定义了日志记录器,就下面这句代码:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值