【MVC】快递信息管理系统

本文介绍了一个基于MVC架构的快递信息管理系统,使用SpringBoot、Mysql和Thymeleaf等技术实现。详细阐述了开发环境、技术栈、项目搭建、各层功能以及难点解决,展示了增删改查、分页和模糊查询等功能效果。


项目介绍

该项目主要介绍基于快递信息的增删改查。

什么是MVC?
MVC是三个单词的首字母缩写,它们是Model(模型)、View(视图)和Controller(控制)。


开发环境

  1. 运行环境:最好是java jdk 17,我们在这个平台上运行的。其他版本理论上也可以。

  2. IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;

  3. 硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;

  4. 数据库:MySql 5.7版本;

  5. 是否Maven项目:是


技术栈

  1. 后端:SpringBoot+Mysql+Thymeleaf模板引擎

  2. 前端:HTML+JavaScript+BootStrap


使用说明

  1. 使用idea的数据库,在mysql中创建对应名称的数据库,并导入项目的sql文件;

  2. 使用IDEA导入项目时,若为maven项目请选择maven;进去依赖添加完毕之后出现pom.xml的,即视为成功使用maven;

  3. 将项目中application.properties配置文件中的数据库配置改为自己的配置;

  4. 运行项目,输入localhost:8080/ 进入网页界面


技术要求

使用IDEA新建项目时,要选择Spring Initializr
选择Maven
建议JDK 17
添加以下五个依赖

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


思路过程

1. 搭建框架
在这里插入图片描述


2. model层
存放实体类;有收件人,电话号码,快递状态,一张表对应一个实体类,类属性同表字段相对应。

注:添加@Data用法,可帮我们省去实体类的get()和set()方法,节省时间。
在这里插入图片描述

代码展示:

package com.example.express.model;

import jakarta.persistence.*;
import lombok.Data;

@Data
@Entity
@Table(name = "express")
public class Express {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "person_name")
    private String personName;

    @Column(name = "person_number")
    private String personNumber;

    @Column(name = "state")
    private String state;
}


3. Service层
业务层,service层的作用为完成功能设计。存放业务逻辑处理,不直接对数据库进行操作,有接口和接口实现类,提供controller层调用的方法。设计的功能主要有新增、更新、获取指定id的快递信息、删除指定ID的快递信息、分页、模糊查询快递信息。
在这里插入图片描述

代码展示:

package com.example.express.service;

import com.example.express.model.Express;
import org.springframework.data.domain.Page;

import java.util.List;

public interface ExpressService {

    //获取所有快递
    List<Express> getAllExpress();

    //新增
    void saveExpress(Express express);

    //获取指定单号
    Express getExpressByTd(long id);

    //删除指定单号
    void deleteExpressById(long id);

    //分页
    Page<Express> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);

    //根据收件人查询
    List<Express> findByPersonName(String personName);
}


4. ExpressServiceImpl.java用来存放接口的实现类对接口函数进行实现。

在这里插入图片描述

代码展示:

package com.example.express.service;

import com.example.express.model.Express;
import com.example.express.repository.ExpressRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class ExpressServiceImpl implements ExpressService {

    @Autowired
    private ExpressRepository expressRepository;

    @Override
    public List<Express> getAllExpress(){
        return expressRepository.findAll();
    }
    @Override
    public void saveExpress(Express express){
        this.expressRepository.save(express);
    }

    @Override
    public Express getExpressByTd(long id) {
        //调用数据访问层查找指定ID的员工,返回Optional对象
        Optional<Express> optional = expressRepository.findById(id);
        Express express = null;
        //如果存在指定id的快递
        if (optional.isPresent()){
            //从Optional对象中获取快递对象
            express = optional.get();
        }else {
            //否则抛出运行时异常
            throw new RuntimeException("找不到快递单号:"+id);

        }
        return express;
    }
    @Override
    public void deleteExpressById(long id){
        this.expressRepository.deleteById(id);
    }

    @Override
    public Page<Express> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection) {
        //设置排序参数,升序ASC/降序DESC?
        Sort sort = sortDirection.equalsIgnoreCase(Sort.Direction.ASC.name())
                ? Sort.by(sortField).ascending()
                : Sort.by(sortField).descending();

        //根据页号/每页记录数/排序依据返回某指定页面数据。
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);

       return this.expressRepository.findAll(pageable);
    }

    @Override
    public List<Express> findByPersonName(String personName) {
        List<Express> name = expressRepository.findAllByPersonName(personName);

        return name;
    }
}


5. Controller层

控制器层,controller层的功能为请求和响应控制。
controller层负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。

在这里插入图片描述

代码展示:

package com.example.express.controller;

import com.example.express.model.Express;
import com.example.express.service.ExpressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
public class ExpressController {
    @Autowired
    private ExpressService expressService;

    @GetMapping("/")
    public String viewHomePage(Model model) {
        return findPaginated(1, "personName", "asc", model);
    }


    /**
     * 跳转
     */
    @GetMapping("/showNewExpressForm")
    public String showNewExpressForm(Model model){
        Express express = new Express();
        model.addAttribute("express", express);
        return "new_express";
    }
    @GetMapping("/query{inpname}")
    public String query(@PathVariable(value = "inpname") String inpame,Model model){
        List<Express> listpersonnumber = expressService.findByPersonName(inpame);
        model.addAttribute("listExpress",listpersonnumber);
        return "index";
    }

    /**
     * 添加
     */
    @PostMapping("/saveExpress")
    public String saveExpress(@ModelAttribute("express") Express express){
        expressService.saveExpress(express);
        return "redirect:/";
    }

    /**
     * 更新跳转
     */
    @GetMapping("/showFormForUpdate/{id}")
    public String showFormForUpdate(@PathVariable(value = "id") long id,Model model){
        Express express = expressService.getExpressByTd(id);
        model.addAttribute("express", express);
        return "update_express";
    }

    /**
     * 删除
     */
    @GetMapping("/deleteExpress/{id}")
    public String deleteExpress(@PathVariable(value = "id") long id){
        this.expressService.deleteExpressById(id);
        return "redirect:/";
    }

    //获取分页数据
    @GetMapping("/page/{pageNo}")
    public String findPaginated(@PathVariable (value = "pageNo") int pageNo,
                                @RequestParam("sortField") String sortField,
                                @RequestParam("sortDir") String sortDir,
                                Model model) {
        int pageSize = 5;
        //分页查询
        Page<Express> page = expressService.findPaginated(pageNo, pageSize, sortField, sortDir);
        List<Express> listExpress = page.getContent();
        model.addAttribute("currentPage", pageNo);
        model.addAttribute("totalPages", page.getTotalPages());
        model.addAttribute("totalItems", page.getTotalElements());
        model.addAttribute("sortField", sortField);
        model.addAttribute("sortDir", sortDir);
        model.addAttribute("reverseSortDir", sortDir.equals("asc") ? "desc" : "asc");
        model.addAttribute("listExpress", listExpress);
        return "index";
    }
}


6. repository层

  • 调用ExpressRepository进行数据库操作。查询Express里面的personName对象;

  • select * from xxx中xxx也不是数据库里面真正的表名,而是对应的实体名;

  • 补充:sql中的字段名也不是数据库中真正的字段名,而是实体的字段名。
    在这里插入图片描述

代码展示:

package com.example.express.repository;

import com.example.express.model.Express;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface ExpressRepository extends JpaRepository<Express,Long> {
    @Query("select g from Express g where g.personName like %:personName%")
    List<Express> findAllByPersonName(@Param("personName") String personName);
}

7. 配置application.properties

本人使用的是远程数据库

  • 如使用本地数据库,localhost即可

在这里插入图片描述

代码展示:

# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.url=jdbc:mysql://(数据库ip):3306/express?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
spring.datasource.username=root
spring.datasource.password=自定义

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# for Spring Boot 2
# spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQL5InnoDBDialect

# for Spring Boot 3
spring.jpa.properties.hibernate.dialect= org.hibernate.dialect.MySQLDialect

# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto= update

#?????hibernate-sql
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

8. index.html部分页面展示

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

ps:html 的源码这里就不往上放了,大家感兴趣可自行摸索或私信我。


9. 使用BootStrap
进入到BootStrap官网中,选择符合主题或自己喜欢的样式,将他添加进html页面中的head标签中。
官网:BootStrap官网
在这里插入图片描述

难点及解决方法

难点

  • 图片导入到 html 时,却在网页界面上不显示;使用其相对路径和绝对路径也都不显示;

在这里插入图片描述

解决方法

  1. 先使用 “…/static/img/p1.jpg” 方法法插入;点击浏览器预览

在这里插入图片描述

  1. 此时是正常显示的;
    但注意看,这里有一个链接,可以看到是先项目名称才到后面的templates/index.html,之后我们的图片就应该
    “http://localhost:63342/Express/src/main/resources/static/img/p1.jpg”
    这样我们使用项目的时候localhost:8080才可以正常访问!

在这里插入图片描述

在这里插入图片描述
至此,问题就解决了。


效果展示

(1) 网页界面首页
p1


(2) 增加快递信息
在这里插入图片描述

在这里插入图片描述


(3)更新
将张三更改为张四
在这里插入图片描述

在这里插入图片描述


(4)删除
将张四删除
在这里插入图片描述

在这里插入图片描述


(5) 查找——根据收件人的名字模糊查询
查询包含 “谢” 的收件人信息
在这里插入图片描述


(6) 分页(大于5行数据可显示页面)
在这里插入图片描述


总结

SpringBoot是一款非常优秀的框架,不仅提供了简化开发的工具和功能,还能帮助我们更好地理解和应用Spring框架。并且它还提供了一种快速、简单的方式来构建独立的、可执行的Spring应用程序。

通过学习我对Java应用程序的开发有了更深入的认识,也提升了自己的技能水平。我相信在未来的工作中,SpringBoot将会成为我们不可或缺的利器。

小伙伴们可以添加其他功能哦!
不合适的地方,望大牛指正。欢迎交流学习!

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值