JavaWeb——学习辅助系统项目案例

目录

1.准备工作

2.部门管理

2.1查询

2.2前后端连调

2.3删除

2.4新增

3.员工管理

3.1分页查询

3.2分页条件查询

3.3删除员工

3.4新增员工

4.文件上传

4.1简介

4.2本地存储

4.3阿里云OOS

4.4查询回显

4.5修改员工

4.6参数配置化

4.7配置文件--yml配置文件

4.8配置文件--@ConfigurationProperties


1.准备工作

  

 

注意事项
REST是风格,是约定方式,约定不是规定,可以打破。
描述模块的功能通常使用复数,也就是加s的格式来描述,表示此类资源,而非单个资源。如: users、emps、book..

开发规范-统一响应结果
前后端交互统一响应结果Result放在pojo包下

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
    private Integer code;//响应码,1 代表成功; 0 代表失败
    private String msg;  //响应信息 描述字符串
    private Object data; //返回的数据

    //增删改 成功响应
    public static Result success(){
        return new Result(1,"success",null);
    }
    //查询 成功响应
    public static Result success(Object data){
        return new Result(1,"success",data);
    }
    //失败响应
    public static Result error(String msg){
        return new Result(0,msg,null);
    }
}

开发流程

  • 查看页面原型明确需求
  • 阅读接口文档
  • 思路分析
  • 接口开发
  • 接口测试
  • 前后端联调

2.部门管理

2.1查询

在DeptController里面接收请求,调用DeptService查询部门,响应数据。

使用日志记录框架记录日志,要定义一个日志记录对象private static Logger log= LoggerFactory.getLogger(DeptController.class);在其他类中如果也需要定义日志记录对象这句代码就比较麻烦,我们可以使用注解@Sjf4j,就可以直接使用log对象的info方法来记录日志。

要限定开发接口的请求方式是GET,可以在@RequestMapping(value = "/depts",method = RequestMethod.GET)指定请求方式为GET。为简化这个注解可以直接用@GetMapping("/depts")限定请求方式为GET,之后也可以使用@PostMapping("/depts")之类的。

        开发流程:前端发送请求之后会请求到DeptController的list()方法,在DeptController的list()方法当中会调用DeptService中的list()方法获取数据,在DeptServicer的list()方法中会调用DeptMapper中的list()方法来查询全部的部门信息,DeptMapper接口就会向数据库中发送sql语句查询员工信息,并且将查询的信息封装到List集合当中,返回给Service,Service返回给Controller,Controller拿到数据再返回给前端。

import com.study.pojo.Dept;
import com.study.pojo.Result;
import com.study.service.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Slf4j
@RestController
public class DeptController {
//    private static Logger log= LoggerFactory.getLogger(DeptController.class);//记录日志

    @Autowired
    private DeptService deptService;
    
    //@RequestMapping(value = "/depts",method = RequestMethod.GET)指定请求方式为GET
    @GetMapping("/depts")
    public Result list() {
        log.info("查询全部部门信息");

        //调用Service查询部门数据
        List<Dept> deptList = deptService.list();
        return Result.success(deptList);
    }
}

 在DeptService中:

import com.study.pojo.Dept;

import java.util.List;

public interface DeptService {
    /**
     * 查询全部部门信息
     * @return
     */
    List<Dept> list();
}

DeptServiceImpl中:

import com.study.mapper.DeptMapper;
import com.study.pojo.Dept;
import com.study.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> list() {
        return deptMapper.list();
    }
}

DeptMapper中:

import com.study.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface DeptMapper {
    /**
     * 查询全部部门数据
     * @return
     */
    @Select("select * from dept")
    List<Dept> list();
}
2.2前后端连调

将前端与后端工程都启动起来,然后访问前端工程,通过前端工程来访问后端程序进而对其调试。

2.3删除

2.4新增

 修改部门需要先实现根据ID查询部门,在实现修改部门功能。

代码如下:

DeptController:

@Slf4j
@RestController
public class DeptController {
//    private static Logger log= LoggerFactory.getLogger(DeptController.class);//记录日志

    @Autowired
    private DeptService deptService;

    /**
     * 查询部门数据
     * @return
     */
    //@RequestMapping(value = "/depts",method = RequestMethod.GET)指定请求方式为GET
    @GetMapping("/depts")
    public Result list() {
        log.info("查询全部部门信息");

        //调用Service查询部门数据
        List<Dept> deptList = deptService.list();
        return Result.success(deptList);
    }

    /**
     * 删除部门
     * @param id
     * @return
     */
    @DeleteMapping("/depts/{id}")
    public Result deleteById(@PathVariable Integer id) {
        log.info("根据id删除部门{"+id+"}");
        deptService.deleteById(id);
        return Result.success();
    }

    /**
     * 新增部门
     */
    @PostMapping("/depts")
    public Result add(@RequestBody Dept dept) {
        log.info("新增部门:"+dept);
        deptService.add(dept);
        return Result.success();
    }

    /**
     * 根据id查询部门
     */
    @GetMapping("/depts/{id}")
    public Result selectById(@PathVariable Integer id) {
        log.info("根据id查询部门"+id);
        Dept dept=deptService.selectById(id);
        return Result.success(dept);
    }

    /**
     * 修改部门
     */
    @PutMapping("/depts")
    public Result update(@RequestBody Dept dept) {
        log.info("更新部门信息"+dept);
        deptService.update(dept);
        return Result.success();
    }
}

DeptService:

public interface DeptService {
    /**
     * 查询全部部门信息
     * @return
     */
    List<Dept> list();

    /**
     * 删除部门
     * @param id
     */
    void deleteById(Integer id);

    /**
     * 新增部门
     * @param dept
     */
    void add(Dept dept);

    /**
     * 根据id查询部门
     * @param id
     * @return
     */
    Dept selectById(Integer id);

    /**
     * 修改部门
     * @param dept
     */
    void update(Dept dept);
}

DeptServiceImpl:

@Service
public class DeptServiceImpl implements DeptService {

    @Autowired
    private DeptMapper deptMapper;

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

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

    @Override
    public void add(Dept dept) {
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());

        deptMapper.add(dept);
    }

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

    @Override
    public void update(Dept dept) {
        dept.setUpdateTime(LocalDateTime.now());

        deptMapper.update(dept);
    }
}

DeptMapper:

@Mapper
public interface DeptMapper {
    /**
     * 查询全部部门数据
     * @return
     */
    @Select("select * from dept")
    List<Dept> list();

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

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

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

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

3.员工管理

3.1分页查询

①分析

 创建一个响应数据的实体类PageBean

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 分页查询结果分装类
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageBean {
    private Long total;//总记录数
    private List rows;//数据列表
}

②实现

③PageHelper插件

3.2分页条件查询

在实现查询功能时,不仅仅要实现将数据列表查询显示出来分页展示,还需要根据条件进行查询。

 

  

3.3删除员工

实现了批量删除功能也就是实现了删除功能 

3.4新增员工

到此为止的员工管理功能代码如下:

EmpController:

@Slf4j
@RestController
@RequestMapping("/emps")
public class EmpController {

    @Autowired
    private EmpService empService;

    @GetMapping
    public Result page(@RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer pageSize,
                       String name, Short gender,
                       @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
                       @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
      log.info("分页查询,参数:{},{},{},{},{},{}",page,pageSize,name,gender,begin,end);
      PageBean pageBean = empService.page(page,pageSize,name,gender,begin,end);
      return Result.success(pageBean);
    }

    @DeleteMapping("/{ids}")
    public Result delete(@PathVariable List<Integer> ids) {
        log.info("删除员工,参数:{}",ids);
        empService.delete(ids);
        return Result.success();
    }

    @PostMapping
    public Result insert(@RequestBody Emp emp) {
        log.info("新增员工,参数:{}",emp);
        empService.insert(emp);
        return Result.success();
    }
}

EmpService:

public interface EmpService {
    /**
     *分页查询以及条件分页查询
     * @return
     */
    PageBean page(Integer page, Integer pageSize,String name, Short gender, LocalDate begin,
                  LocalDate end);

    /**
     * 删除员工
     * @param ids
     */
    void delete(List<Integer> ids);

    /**
     * 新增员工
     * @param emp
     */
    void insert(Emp emp);
}

EmpServiceImpl:

@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

//    @Override
//    public PageBean page(Integer page, Integer pageSize) {
//        //1.获取总记录数
//        Long total = empMapper.count();
//        //2.获取分页查询结果列表
//        Integer start = (page-1)*pageSize;
//        List<Emp> empList=empMapper.page(start,pageSize);
//        //3.封装PageBean对象并返回
//        PageBean pageBean=new PageBean(total,empList);
//        return pageBean;
//    }

    @Override
    public PageBean page(Integer page, Integer pageSize,String name, Short gender, LocalDate begin, LocalDate end) {
        //1.设置分页参数
        PageHelper.startPage(page,pageSize);
        //2.执行查询
        List<Emp> empList=empMapper.list(name,gender,begin,end);
        Page<Emp> p=(Page<Emp>) empList;
        //3.封装PageBean对象并返回
        PageBean pageBean=new PageBean(p.getTotal(),p.getResult());
        return pageBean;
    }

    @Override
    public void delete(List<Integer> ids) {
        empMapper.delete(ids);
    }

    @Override
    public void insert(Emp emp) {
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());

        empMapper.insert(emp);
    }
}

EmpMapper:

@Mapper
public interface EmpMapper {

    /**
     * 获取总记录数
     * @return
     */
//    @Select("select count(*) from emp")
//    Long count();

    /**
     * 分页查询,获取列表数据
     * @param start 起始索引
     * @param pageSize 展现列表数
     * @return
     */
//    @Select("select * from emp limit #{start},#{pageSize}")
//    List<Emp> page(Integer start,Integer pageSize);

    /**
     * 员工信息的查询
     * @return
     */
    //@Select("select * from emp")
    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);

    /**
     * 删除员工
     * @param ids
     */
    void delete(List<Integer> ids);

    /**
     * 新增员工
     * @param emp
     */
    //@Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values " +
     //       "(#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})")
    void insert(Emp emp);
}

写SQL的EmpMapper.xml:

<?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.study.mapper.EmpMapper">
<!--    新增员工-->
    <insert id="insert">
        insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values
        (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime})
    </insert>

    <!--    删除员工-->
    <delete id="delete">
        delete from emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

<!--    条件查询-->
    <select id="list" resultType="com.study.pojo.Emp">
        select * from emp
        <where>
        <if test="name != null and name != ''">
            name like concat('%',#{name},'%')
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
        </where>
        order by update_time desc
    </select>
</mapper>

4.文件上传

4.1简介
  • 文件上传,是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程。
  • 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。

文件上传前端页面的三要素:

  1. 必须要定义一个表单,并且在表单里面要要定义一个类型为file的表单项,体现为一个上传文件的按钮
  2. 表单的提交方式必须是post,因为进行文件上传,文件一般比较大。
  3. form表单当中,通过enctype属性指定表单的编码格式为multipart/form-data。因为普通默认的编码格式不适合传输大型的二进制文件

如果表单的编码格式选择的是默认的application/x-www-form-urlencoded: The default value.,提交的文件仅仅是文件的文件名,文件的内容没有提交到服务端。

当编码方式为 multipart/form-data时,上传的文件形式,文件内容与文件名均会上传。

实例:

小结:

4.2本地存储

我们提交的文件临时自动存放在临时文件存放目录下,当这次请求响应完成之后临时文件会被自动删除,所以在文件上传时,除了要接收上传的文件,有时还需要将文件保存起来。

代码实例:

@Slf4j
@RestController
public class UploadController {
    @RequestMapping("/upload")
    public Result upload(String username, Integer age, MultipartFile image) throws IOException {
        log.info("文件上传:{},{},{}",username,age,image);
        //获取原始文件名
        String originalFilename = image.getOriginalFilename();
        //构造唯一文件名(不重复)
        int index=originalFilename.lastIndexOf(".");
        String substring = originalFilename.substring(index);
        UUID uuid = UUID.randomUUID();
        String newFileName = uuid + substring;
        //将文件存储在服务器的磁盘目录中
        image.transferTo(new File("E:\\JAVA\\测试\\springboot-案例-本地存储\\"+newFileName));

        return Result.success();
    }
}

 这种上传保存方法对文件的大小有限制,必须小于1M,所以需要加上配置信息。

#配置单个文件最大上传大小
spring.servlet.multipart.max-file-size=10MB
#配置单个请求最大上传大小(一次请求可以上传多个文件)
spring.servlet.multipart.max-request-size=100MB

针对本地存储出现的问题,项目组可以自己搭建一套用于存储的服务器,还可以使用云存储。


4.3阿里云OOS

①准备

云也就是云端,可以理解为互联网 。云服务就是通过互联网对外提供的各种各样服务


第三方服务-通用思路

  1. 准备工作
  2. 参照官方SDK编写入门程序
  3. 集成使用

Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间。
SDK: Software Development Kit的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK。
 


1. 阿里云 OSS 简介
阿里云对象存储服务( Object Storage Service ,简称 OSS )为您提供基于网络的数据
存取服务。使用 OSS ,您可以通过网络随时存储和调用包括文本、图片、音频和视频
等在内的各种非结构化数据文件。
阿里云 OSS 将数据文件以对象( object )的形式上传到存储空间( bucket )中。
您可以进行以下操作:
创建一个或者多个存储空间,向每个存储空间中添加一个或多个文件。
通过获取已上传文件的地址进行文件的分享和下载。
通过修改存储空间或文件的属性或元信息来设置相应的访问权限。
在阿里云管理控制台执行基本和高级 OSS 任务。
使用阿里云开发工具包或直接在应用程序中进行 RESTful API 调用执行基本和高级
OSS 任务
2. OSS 开通
1 )打开 https://www.aliyun.com/ ,申请阿里云账号并完成实名认证。
2 )充值 ( 可以不用做 )
3 )开通 OSS
登录阿里云官网。 点击右上角的控制台。
将鼠标移至产品,找到并单击对象存储 OSS ,打开 OSS 产品详情页面。在 OSS 产品详情
页中的单击立即开通。

 

开通服务后,在 OSS 产品详情页面单击管理控制台直接进入 OSS 管理控制台界面。您也
可以单击位于官网首页右上方菜单栏的控制台,进入阿里云管理控制台首页,然后单
击左侧的对象存储 OSS 菜单进入 OSS 管理控制台界面

 

4 )创建存储空间
新建 Bucket ,命名为 hmleadnews ,读写权限为 公共读

②入门

参照SDK文档进行文件上传。

在Java中,首先需要安装 SDK,在pom.xml增加配置信息。

对于文件的上传,可以直接复制实例代码到项目当中,然后根据需求修改代码的变量部分。运行之后可以看到文件已经上传到阿里云OSS当中。

package com.study;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import java.io.FileInputStream;
import java.io.InputStream;

public class Demo {

    public static void main(String[] args) throws Exception {
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-beijing.aliyuncs.com";
        // RAM用户的访问密钥(AccessKey ID和AccessKey Secret)。
        String accessKeyId = "LTAI5tGxfdS59C6Lz3t82S3N";
        String accessKeySecret = "epmq1T4mM66q5jGIT0IVwKvMxE400w";
        // 使用代码嵌入的RAM用户的访问密钥配置访问凭证。
        CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "myweb-frame01";
        // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
        String objectName = "1.jpg";
        // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
        String filePath= "C:\\Users\\ye\\Pictures\\喜欢的图\\壁纸(1).jpg";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 创建PutObjectRequest对象。
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream);
            // 创建PutObject请求。
            PutObjectResult result = ossClient.putObject(putObjectRequest);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
} 

③集成

4.4查询回显

4.5修改员工

4.6参数配置化

问题分析:在做项目时,会涉及多个第三方服务等,代码中的参数过多。当参数发生变化时,需要改动参数并重新进行代码的编,将java代码编译成字节码文件再重新运行,比较繁琐。项目中的类很多时,参数比较分散,修改不方便,难以定位。

  

4.7配置文件--yml配置文件

 

4.8配置文件--@ConfigurationProperties

当需要注入的value值过多时,操作比较繁琐。可以使用 @ConfigurationProperties注解。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ustinian.488

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值