【Java MVC】制作简单的手机管理系统

目录

1.功能要求:

 2.背景要求:

3.技术要求:

4.添加数据库MySQL

5.文件准备:

6.控制层(PhoneConntroller):

6.1.分页、添加、添加并保持、修改、删除、排序、搜索名字

7.业务类(Phone):

7.1.在此定义了5个业务类的属性:

7.1.1电话的编号、保存的名字、对方的年龄、电话号码、电话的IP

8.数据访问层(PhoneRepository)接口:

8.1.负责与数据的查询的方法

8.1.1在网页中可以查询数据库中对应电话的编号、保存的名字、对方的年龄、电话号码、电话的IP

9.在service层创建一个接口PhoneService这个类服务与9.1.PhoneServiceImpl并进行测试:

9.1.1里面定义了方法,例如:将用户的手机信息存进一个列表里、新增手机信息或者更新手机信息、通过查询用户的手机信息存进一个新的列表里,将它们进行分页展示

9.1.2:测试类BankServiceimpl用来继承BankService,实现获取所有用户的手机信息、根据姓名查找用户的、保存用户信息到列表、根据id删除用户的信息、根据姓名查找列表是否存在此用户、设置排序参数:

10.HTML部分:主页面以及新增和更新部分页面设置

10.1主页面(index):

10.手机通讯录管理系统的界面(new_phone,html)

10.1它使用了Bootstrap框架来实现样式和布局的设置。

10.1.1在页面上,你可以看到一个包含标题和表单的容器。表单中包括了几个输入字段,用于保存手机通讯录中的联系人信息。每个输入字段都有一个占位符和相应的输入类型。

11.更新手机通讯录联系人信息的界面:

11.1在更新操作时,通常需要知道要更新的联系人的ID。

12.运行结果:

12.1.1主页面:

12.1.2 新增页面: 

 12.1.3 查询页面:

​编辑

12.1.4 更新、删除:

13. 总结:


1.功能要求:

包括但不限于功能要求增删改查和分页。以设备管理管理系统App为例:

1.设备:属性至少3个以上,包括并不限于设备类型、设备名称、初始状态……

2.添加设备

3.删除设备

4.更新设备

5.查找设备(自定义查询依据),显示查询结果。

6.分页

7.排序

扩展(加分):例如部门设备(1:n)管理部门,根据部门查询设备等等。

 2.背景要求:

设计一个手机通讯管理系统,提供用户方便查找并修改。

3.技术要求:

创建项目,并添加依赖项。

4.添加数据库MySQL

       MySQL是一个开源的关系型数据库管理系统,被广泛用于Web应用程序开发。它具有卓越的性能、可靠性和可扩展性,提供了丰富的查询语言和存储过程支持。通过与Spring Boot和JPA的结合,我们可以轻松地进行数据库操作,实现数据的持久化和查询。

我定义的数据名,以及密码,各位可以尝试着修改。数据库名称:testdb

spring.datasource.url=jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username= root
spring.datasource.password= 123456

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.open-in-view=false
# 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

5.文件准备:

5.1.创建软件包与实现类 

6.控制层(PhoneConntroller):

6.1.分页、添加、添加并保持、修改、删除、排序、搜索名字

package com.example.phone.Controller;

import com.example.phone.model.Phone;
import com.example.phone.repository.PhoneRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

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



/ 控制层
@Controller
public class PhoneController {
    @Autowired
    private PhoneRepository phoneRepository;

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

    /// 添加
    @GetMapping("/showNewPoneForm")
    public String showNewPhoneForm(Model model) {
        Phone phone = new Phone();
        model.addAttribute("phone", phone);
        return "new_phone";
    }


    /// 添加的保存
    @PostMapping("/savePone")
    public String savePhone(@ModelAttribute("phone") Phone phone) {
        phoneRepository.save(phone);
        return "redirect:/";
    }

    /// 修改

    @GetMapping("/showFormForUpdate/{id}")
    public String showFormForUpdate(@PathVariable("id") long id, Model model) {
        Optional<Phone> optional = phoneRepository.findById(id);
        if (optional.isPresent()) {
            Phone phone = optional.get();
            model.addAttribute("phone", phone);
        } else {
            throw new RuntimeException("Cannot find phone with ID: " + id);
        }
        return "update_phone";
    }

    /// 删除
    @GetMapping("/deletePhone/{id}")
    public String deletePhone(@PathVariable("id") long id) {
        phoneRepository.deleteById(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;
        Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())
                ? Sort.by(sortField).ascending()
                : Sort.by(sortField).descending();

        Pageable pageable = PageRequest.of(pageNo - 1, pageSize, sort);
        Page<Phone> page = phoneRepository.findAll(pageable);
        List<Phone> listPhones = 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("listPhones", listPhones);
        return "index";
    }

    //搜索名字
    @GetMapping("/query{inpname}")
    public String query(@PathVariable(value = "inpname") String inpame,Model model){
        List<Phone> listPhones = phoneRepository.findByName(inpame);
        model.addAttribute("listPhones",listPhones);
        return "index";
    }


}

7.业务类(Phone):

7.1.在此定义了5个业务类的属性:

7.1.1电话的编号、保存的名字、对方的年龄、电话号码、电话的IP

package com.example.phone.model;

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

@Data
@Entity
@Table(name = "phones")
public class Phone {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(name = "numbering")         /// 电话的编号
    private String numbering;

    @Column(name = "name")               保存的名字
    private String name;

    @Column(name = "age")                对方的年龄
    private String age;

    @Column(name = "phone")              电话号码
    private String phone;
    @Column(name = "address")          / 电话的IP
    private String address;
}

8.数据访问层(PhoneRepository)接口

8.1.负责与数据的查询的方法

8.1.1在网页中可以查询数据库中对应电话的编号、保存的名字、对方的年龄、电话号码、电话的IP

package com.example.phone.repository;

import com.example.phone.model.Phone;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

 接口
@Repository
public interface PhoneRepository extends JpaRepository<Phone, Long> {

    /// 添加查询名字
    @Query("select p from Phone p where p.name like %:name%")
    List<Phone> findByName(@Param("name") String name);

}

9.在service层创建一个接口PhoneService这个类服务与9.1.PhoneServiceImpl并进行测试:

9.1.1里面定义了方法,例如:将用户的手机信息存进一个列表里、新增手机信息或者更新手机信息、通过查询用户的手机信息存进一个新的列表里,将它们进行分页展示

package com.example.phone.service;

import com.example.phone.model.Phone;
import org.springframework.data.domain.Page;

import java.util.List;

public interface PhoneService {
        //获取所有的手机通讯信息
        List<Phone> getAllPhones();

        //新增/更新一个手机通讯信息
        void savePhone(Phone phone);

        //获取指定ID的手机通讯信息
        Phone getPhoneById(long id);

        //删除指定ID的手机通讯信息
        void deletePhoneById(long id);

        /// 查询指定名字
        List<Phone> findByNameContaining(String name);


        //分页查询手机通讯信息
        Page<Phone> findPaginated(int pageNo, int pageSize, String sortField, String sortDirection);
}


9.1.2:测试类BankServiceimpl用来继承BankService,实现获取所有用户的手机信息、根据姓名查找用户的、保存用户信息到列表、根据id删除用户的信息、根据姓名查找列表是否存在此用户、设置排序参数:

package com.example.phone.service;

import com.example.phone.model.Phone;
import com.example.phone.repository.PhoneRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

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


@Service
public class PhoneServiceImpl implements PhoneService {

    private PhoneRepository phoneRepository;

    @Autowired
    public PhoneServiceImpl(PhoneRepository phoneRepository){
        this.phoneRepository = phoneRepository;
    }

    @Override
    public List<Phone> getAllPhones() {
        return phoneRepository.findAll();
    }

    @Override
    public void savePhone(Phone phone) {
        phoneRepository.save(phone);
    }

    @Override
    public Phone getPhoneById(long id) {
        Optional<Phone> optional = phoneRepository.findById(id);
        Phone phone = null;
        if (optional.isPresent()) {
           phone = optional.get();
        } else {
            throw new RuntimeException("找不到手机ID:" + id);
        }
        return phone;
    }

    @Override
    public void deletePhoneById(long id) {
        phoneRepository.deleteById(id);
    }

    @Override
    public List<Phone> findByNameContaining(String name) {
        List<Phone> optional = phoneRepository.findByName(name);

        return optional;
    }

    @Override
    public Page<Phone> 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.phoneRepository.findAll(pageable);
    }
}

10.HTML部分:主页面以及新增和更新部分页面设置

10.1主页面(index)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>手机通讯录管理系统</title>

    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">

</head>
<body>

<div class="container my-2">
    <h1>电 话 列 表</h1>

    <a th:href = "@{/showNewPoneForm}" class="btn btn-primary btn-sm mb-3"> 添加手机通讯录数据 </a>

    <h3>查找名字</h3>
    <form id="query-form" action="/query" method="get">
        <input type="text" id="name-input" name="inpname" placeholder="输入需要查询的名字">
        <button type="button" onclick="queryStudent()">查找</button>
    </form>
    <!--    将输入框输入的内容传到url上面去-->
    <script>
        function queryStudent() {
            var name = document.getElementById("name-input").value;
            var url = "/query" + encodeURIComponent(name);
            window.location.href = url;
        }
    </script>


    <table border="1" class = "table table-striped table-responsive-md">
        <thead>
        <tr>
            <th>
                <a th:href="@{'/page/' + ${currentPage} + '?sortField=numbering&sortDir=' + ${reverseSortDir}}">
                    编 号</a>
            </th>
            <th>
                <a th:href="@{'/page/' + ${currentPage} + '?sortField=name&sortDir=' + ${reverseSortDir}}">
                    姓 名</a>
            </th>
            <th>
                <a th:href="@{'/page/' + ${currentPage} + '?sortField=age&sortDir=' + ${reverseSortDir}}">
                    年 龄</a>
            </th>
            <th>
                <a th:href="@{'/page/' + ${currentPage} + '?sortField=phone&sortDir=' + ${reverseSortDir}}">
                    电 话</a>
            </th>
            <th>
                <a th:href="@{'/page/' + ${currentPage} + '?sortField=address&sortDir=' + ${reverseSortDir}}">
                    地 址</a>
            </th>
            <th> 操 作 </th>
        </tr>
        </thead>
        <tbody>
        <tr th:each="phone : ${listPhones}">
            <td th:text="${phone.numbering}"></td>
            <td th:text="${phone.name}"></td>
            <td th:text="${phone.age}"></td>
            <td th:text="${phone.phone}"></td>
            <td th:text="${phone.address}"></td>
            <td> <a th:href="@{/showFormForUpdate/{id}(id=${phone.id})}" class="btn btn-primary">更新</a>
                <a th:href="@{/deletePhone/{id}(id=${phone.id})}" class="btn btn-danger">删除</a>
            </td>
        </tr>
        </tbody>
    </table>

    <div th:if = "${totalPages > 1}">
        <div class = "row col-sm-10">
            <div class = "col-sm-3">
                Total Rows: [[${totalItems}]]
            </div>
            <div class = "col-sm-5">
					<span th:each="i: ${#numbers.sequence(1, totalPages)}">
						<a th:if="${currentPage != i}" th:href="@{'/page/' + ${i}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">[[${i}]]</a>
						<span th:unless="${currentPage != i}">[[${i}]]</span>  &nbsp; &nbsp;
					</span>
            </div>
            <div class = "col-sm-1">
                <a th:if="${currentPage < totalPages}" th:href="@{'/page/' + ${currentPage + 1}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">Next</a>
                <span th:unless="${currentPage < totalPages}">Next</span>
            </div>

            <div class="col-sm-1">
                <a th:if="${currentPage < totalPages}" th:href="@{'/page/' + ${totalPages}+ '?sortField=' + ${sortField} + '&sortDir=' + ${sortDir}}">Last</a>
                <span th:unless="${currentPage < totalPages}">Last</span>
            </div>
        </div>
    </div>
</div>
</body>
</html>

10.手机通讯录管理系统的界面(new_phone,html)

10.1它使用了Bootstrap框架来实现样式和布局的设置。

10.1.1在页面上,你可以看到一个包含标题和表单的容器。表单中包括了几个输入字段,用于保存手机通讯录中的联系人信息。每个输入字段都有一个占位符和相应的输入类型。

在输入字段下方,有一个提交按钮,用于保存输入的联系人信息。

在表单下方,还有一个返回按钮,用于返回到通讯录列表页面。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>手机通讯录管理系统</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
</head>

<body>
<div class="container">
    <h1>手机通讯录管理系统</h1>
    <hr>
    <h2>Save Phone</h2>

    <form action="#" th:action="@{/savePone}" th:object="${phone}" method="POST">
        <input type="text" th:field="*{numbering}" placeholder="编号" class="form-control mb-4 col-4">

        <input type="text" th:field="*{name}" placeholder="姓名" class="form-control mb-4 col-4">

        <input type="text" th:field="*{age}" placeholder="年龄" class="form-control mb-4 col-4">

        <input type="text" th:field="*{phone}" placeholder="电话" class="form-control mb-4 col-4">

        <input type="text" th:field="*{address}" placeholder="地址" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2"> Save Phone</button>
    </form>

    <hr>

    <a th:href="@{/}"> Back to Phone List</a>
</div>
</body>

</html>

11.更新手机通讯录联系人信息的界面:

11.1在更新操作时,通常需要知道要更新的联系人的ID。

这个隐藏字段被用来保存联系人的ID 。通过这个隐藏字段,系统可以识别出要更新的联系人。

除此之外,其他的代码和之前的代码保持一致。用户可以在输入字段中修改联系人的信息,然后点击"Update Phone"按钮来更新联系人信息。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>手机通讯录管理系统</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">

   </head>

<body>
<div class="container">
    <h1>手机通讯录管理系统</h1>
    <hr>
    <h2>Update Phone</h2>

    <form action="#" th:action="@{/savePone}" th:object="${phone}" method="POST">

        <!-- Add hidden form field to handle update -->
        <input type="hidden" th:field="*{id}" />

        <input type="text" th:field="*{numbering}"  placeholder="编号" class="form-control mb-4 col-4">

        <input type="text" th:field="*{name}"  placeholder="姓名" class="form-control mb-4 col-4">

        <input type="text" th:field="*{age}" placeholder="年龄" class="form-control mb-4 col-4">

        <input type="text" th:field="*{phone}" placeholder="电话" class="form-control mb-4 col-4">

        <input type="text" th:field="*{address}" placeholder="地址" class="form-control mb-4 col-4">

        <button type="submit" class="btn btn-info col-2"> Update Phone</button>
    </form>

    <hr>

    <a th:href="@{/}"> Back to Phone List</a>
</div>
</body>

</html>

12.运行结果:

12.1.1主页面:

12.1.2 新增页面: 

 12.1.3 查询页面:

12.1.4 更新、删除:

13. 总结:

        该学期JAVA的学习可以说让我们正式认识了JAVA这门语言的魅力,通过结合Spring Boot、JPA、Thymeleaf、MySQL和Bootstrap,从最初几行代码变为现如今的几十行到几百行,一点点的学习一点点的进步,漫长的过程也让我们对知识更深刻的记忆。如老师所言,“代码是需要练的”,光看是无法真正的学会。学习Java高级程序设计课程是一次充实且有收获的经历,通过不懈的努力和持续的学习,我对Java编程语言有了更深入的理解。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值