⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/weixin_44671737/article/details/112341805 「兴趣使然的程序猿」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

摘要

对企业来说,人、物资、能源、资金、信息是5大重要资源。人、物资、能源、资金这些都是可见的有形资源,而信息是一种无形的资源。以前人们比较看重有形的资源,进入信息社会和知识经济时代以后,信息资源就显得日益重要。

因为信息资源决定了如何更有效地利用物资资源。信息资源是人类与自然的斗争中得出的知识结晶,掌握了信息资源,就可以更好地利用有形资源,使有形资源发挥更好的效益。

由此可见,诸如各类管理系统还是很有价值的,笔者经历的公司内部都有自己实现的管理系统,可能有些非互联网的公司是依靠其他公司提供的信息管理服务,ERP系统至今还发挥着重要作用,笔者下班后连忙带赶,经历数个小时的鏖战,终于做完了此xx管理系统,在此与诸位分享。

1 技术选型

1.1 Mysql8

为什么是mysql8,不是5版本的。没错就是喜新厌旧啦!!!

mysql8有何特别之处呢!

1.性能就是好,没错它就是强,所以当然上Mysql8,快点上8。

2.Mysql8还支持各种牛逼的功能:SQL窗口函数,GIS,JSON扩展语法等等。总之这些功能听着就挺牛,由于笔者自己还没弄明白,就不赘述了。

1.2 springboot2

当前主流的web开发框架,不二之选,没有比这更方便的了,为什么选这个,它就是无敌,没有竞争对手啊。自动装配,父级依赖,嵌入tomcat等等,就是无敌呀。

1.3 模板引擎thymeleaf

用模板引擎也实属无奈,笔者不会前端呀,毕竟人的精力是有限的。不过这个东西还是挺好用的,赶脚用着和几年前学写jsp也差不多。

2 项目构建

2.1 创建项目

spring initializer

取个心爱的项目名字

勾选需要的依赖,mysql,thymeleaf,jpa

2.2 建表

好吧,笔者为了偷懒,没有建表ddl,直接上jpa,先建一个需要的库,create database。做完这些,项目开始的准备工作就已经完了,马上又带了激动人心的撸代码环节了。

3 项目实现

3.1 项目效果

主页面

就是这样滴,如此就已然发挥了笔者百分之两百的前端功力了,各种查阅资料,复制copy加代码修改,修修改改终于有了上边的模样,应该不算太丑吧!好吧,我承认了。

3.2 项目结构

和主流web开发项目的结构基本大同小异:

对应数据库实体的entity包,对应数据库操作的repo目录,对应业务代码的service目录,对应restful api的controller目录。

4 代码实现

4.1 前台页面

首页面,就是上边看到的那个帅气的首页!

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<meta charset="UTF-8">
<title>xx-manager</title>
</head>
<body>
<header th:replace="xx-header.html"></header>
<div class="container my-2">
<a th:href="@{/newEmployee}" class="btn btn-primary btn-sm mb-3"> 新增 </a>
<table border="1" class = "table table-striped table-responsive-md">
<thead>
<tr>
<th>姓名</th>
<th>邮箱</th>
<th>电话</th>
<th>地址</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="employee : ${employees}">
<td th:text="${employee.name}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.mobile}"></td>
<td th:text="${employee.location}"></td>
<td><a th:href="@{/updateEmployee/{id}(id=${employee.id})}" class="btn btn-primary">修改</a>
<a th:href="@{/deleteEmployee/{id}(id=${employee.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-2">
总人数: [[${items}]]
</div>
<div class="col-sm-1">
<span th:each="i: ${#numbers.sequence(1, totalPages)}">
<a th:if="${currentPage != i}" th:href="@{'/page/' + ${i}}">[[${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}}">下一页</a>
<span th:unless="${currentPage < totalPages}">下一页</span>
</div>

<div class="col-sm-1">
<a th:if="${currentPage < totalPages}" th:href="@{'/page/' + ${totalPages}}">尾页</a>
<span th:unless="${currentPage < totalPages}">尾页</span>
</div>
</div>
</div>
</div>
<footer th:replace="footer.html"></footer>
</body>
</html>

新增功能页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<meta charset="UTF-8">
<title>xx-manager</title>
</head>
<body>
<header th:replace="xx-header.html"></header>
<div class="container">
<h1>xx-manager</h1>
<hr>
<h2>保存</h2>

<form action="#" th:action="@{/saveEmployee}" th:object="${employee}" method="POST">
<input type="text" th:field="*{name}" placeholder="姓名" class="form-control mb-4 col-4">

<input type="text" th:field="*{email}" placeholder="邮箱" class="form-control mb-4 col-4">

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

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

<button type="submit" class="btn btn-info col-2">保存</button>
</form>

<hr>

<a th:href="@{/}">回退</a>
</div>
<footer th:replace="footer.html"></footer>
</body>
</html>

修改功能页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css">
<meta charset="UTF-8">
<title>xx-manager</title>
</head>
<body>
<header th:replace="xx-header.html"></header>
<div class="container">
<h1>xx-manager</h1>
<hr>
<h2>更新</h2>

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

<input type="hidden" th:field="*{id}" />

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

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

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

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

<button type="submit" class="btn btn-info col-2">修改</button>

</form>

<hr>

<a th:href="@{/}">回退</a>
</div>
<footer th:replace="footer.html"></footer>
</body>
</html>

4.2 后台业务实现

4.2.1 实体类Employee

对应数据库中的表

package com.lbh.xxmanager.entity;

import javax.persistence.*;

/**
* Copyright(c)lbhbinhao@163.com
* @author liubinhao
* @date 2021/1/7
* ++++ ______ ______ ______
* +++/ /| / /| / /|
* +/_____/ | /_____/ | /_____/ |
* | | | | | | | | |
* | | | | | |________| | |
* | | | | | / | | |
* | | | | |/___________| | |
* | | |___________________ | |____________| | |
* | | / / | | | | | | |
* | |/ _________________/ / | | / | | /
* |_________________________|/b |_____|/ |_____|/
*/
@Entity
@Table(name = "xx_employee")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "name")
private String name;
@Column(name = "email")
private String email;
@Column(name = "mobile")
private String mobile;
@Column(name = "location")
private String location;
@Column(name="status")
private int status;

public long getId() {
return id;
}

public void setId(long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getMobile() {
return mobile;
}

public void setMobile(String mobile) {
this.mobile = mobile;
}

public String getLocation() {
return location;
}

public void setLocation(String location) {
this.location = location;
}

public int getStatus() {
return status;
}

public void setStatus(int status) {
this.status = status;
}
}

4.2.2 数据库操作层repo

package com.lbh.xxmanager.repo;

import com.lbh.xxmanager.entity.Employee;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
* Copyright(c)lbhbinhao@163.com
* @author liubinhao
* @date 2021/1/7
* ++++ ______ ______ ______
* +++/ /| / /| / /|
* +/_____/ | /_____/ | /_____/ |
* | | | | | | | | |
* | | | | | |________| | |
* | | | | | / | | |
* | | | | |/___________| | |
* | | |___________________ | |____________| | |
* | | / / | | | | | | |
* | |/ _________________/ / | | / | | /
* |_________________________|/b |_____|/ |_____|/
*/
@Repository
public interface EmployeeRepository extends JpaRepository<Employee,Long> {

List<Employee> findAllByStatus(int status);

Page<Employee> findAllByStatus(int status, Pageable pageable);

Page<Employee> findAllByStatusAndLocationLikeOrNameLikeOrEmailLike(int status,String locaion,String name,String email, Pageable pageable);

}

4.2.3 业务代码service

接口:

package com.lbh.xxmanager.service;

import com.lbh.xxmanager.entity.Employee;
import org.springframework.data.domain.Page;

import java.util.List;

/**
* Copyright(c)lbhbinhao@163.com
* @author liubinhao
* @date 2021/1/7
* ++++ ______ ______ ______
* +++/ /| / /| / /|
* +/_____/ | /_____/ | /_____/ |
* | | | | | | | | |
* | | | | | |________| | |
* | | | | | / | | |
* | | | | |/___________| | |
* | | |___________________ | |____________| | |
* | | / / | | | | | | |
* | |/ _________________/ / | | / | | /
* |_________________________|/b |_____|/ |_____|/
*/
public interface EmployeeService {

List<Employee> findAllEmployees();

void saveEmployee(Employee employee);

Employee getEmployeeById(long id);

void deleteEmployeeById(long id);

Page<Employee> findPaging(int no,int size);

Page<Employee> findPaging(int no,int size,String searchKey);
}

业务实现类:

package com.lbh.xxmanager.service;

import com.lbh.xxmanager.entity.Employee;
import com.lbh.xxmanager.repo.EmployeeRepository;
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.stereotype.Service;

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

/**
* Copyright(c)lbhbinhao@163.com
*
* @author liubinhao
* @date 2021/1/7
* ++++ ______ ______ ______
* +++/ /| / /| / /|
* +/_____/ | /_____/ | /_____/ |
* | | | | | | | | |
* | | | | | |________| | |
* | | | | | / | | |
* | | | | |/___________| | |
* | | |___________________ | |____________| | |
* | | / / | | | | | | |
* | |/ _________________/ / | | / | | /
* |_________________________|/b |_____|/ |_____|/
*/
@Service
public class EmployeeServiceImpl implements EmployeeService {

@Autowired
private EmployeeRepository employeeRepository;

@Override
public List<Employee> findAllEmployees() {
return employeeRepository.findAllByStatus(0);
}

@Override
public void saveEmployee(Employee employee) {
employee.setStatus(0);
employeeRepository.save(employee);
}

@Override
public Employee getEmployeeById(long id) {
Optional<Employee> byId = employeeRepository.findById(id);
Employee employee = null;
if (byId.isPresent()){
employee = byId.get();
}else {
throw new RuntimeException("该id员工不存在!");
}
return employee;
}

@Override
public void deleteEmployeeById(long id) {
Employee employeeById = getEmployeeById(id);
employeeById.setStatus(1);
employeeRepository.save(employeeById);
}

@Override
public Page<Employee> findPaging(int no, int size) {
Pageable pageable = PageRequest.of(no - 1,size);
return employeeRepository.findAllByStatus(0,pageable);
}

@Override
public Page<Employee> findPaging(int no, int size, String searchKey) {
String key = "%"+searchKey+"%";
Pageable pageable = PageRequest.of(no - 1,size);
return employeeRepository.findAllByStatusAndLocationLikeOrNameLikeOrEmailLike(0,key,key,key,pageable);
}
}

4.2.4 Web接口

package com.lbh.xxmanager.controller;

import com.lbh.xxmanager.entity.Employee;
import com.lbh.xxmanager.service.EmployeeService;
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 org.thymeleaf.util.StringUtils;

import java.util.List;

/**
* Copyright(c)lbhbinhao@163.com
* @author liubinhao
* @date 2021/1/7
* ++++ ______ ______ ______
* +++/ /| / /| / /|
* +/_____/ | /_____/ | /_____/ |
* | | | | | | | | |
* | | | | | |________| | |
* | | | | | / | | |
* | | | | |/___________| | |
* | | |___________________ | |____________| | |
* | | / / | | | | | | |
* | |/ _________________/ / | | / | | /
* |_________________________|/b |_____|/ |_____|/
*/
@Controller
public class EmployeeController {

@Autowired
private EmployeeService employeeService;

@GetMapping("/")
public String index(Model model){
model.addAttribute("employees",employeeService.findAllEmployees());
return "redirect:/page/1";
}

@GetMapping("/newEmployee")
public String newEmployee(Model model){
Employee employee = new Employee();
model.addAttribute("employee",employee);
return "new_employee";
}

@PostMapping("/saveEmployee")
public String saveEmployee(@ModelAttribute Employee employee){
employeeService.saveEmployee(employee);
return "redirect:/";
}

@GetMapping("/updateEmployee/{id}")
public String updateEmployee(@PathVariable Long id,Model model){
Employee employeeById = employeeService.getEmployeeById(id);
model.addAttribute("employee",employeeById);
return "update_employee";
}

@GetMapping("/deleteEmployee/{id}")
public String deleteEmployee(@PathVariable Long id){
employeeService.deleteEmployeeById(id);
return "redirect:/";
}

@GetMapping("/page/{pageNo}")
public String findPaging(@PathVariable int pageNo, @RequestParam(required = false) String key, Model model){
Page<Employee> paging = null;
if (StringUtils.isEmpty(key)) {
paging = employeeService.findPaging(pageNo, 5);
}
else{
paging = employeeService.findPaging(pageNo, 5,key);
}
List<Employee> content = paging.getContent();
model.addAttribute("currentPage",pageNo);
model.addAttribute("totalPages",paging.getTotalPages());
model.addAttribute("items",paging.getTotalElements());
model.addAttribute("employees",content);
return "index";
}
}

4.3 配置文件

springboot的配置文件

server.port=9001
spring.datasource.username=root
spring.datasource.password=你的数据库密码
spring.datasource.url=jdbc:mysql://localhost:3303/xx-manager?serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=CONVERT_TO_NULL&autoReconnect=true&useSSL=false&failOverReadOnly=false

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
# update 这样写可以自动建表,更新表
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto=update

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type=TRACE

5 总结

写一个这样简单的后台信息管理还是不难,看来笔者还是宝刀未老。下班回家开始做,不过写博客是真滴难,都过了12点还没有写完,写博客和我写代码的时间也相差无几了。哎,我这可怜的头发啊。

文章目录
  1. 1. 摘要
  2. 2. 1 技术选型
    1. 2.1. 1.1 Mysql8
    2. 2.2. 1.2 springboot2
    3. 2.3. 1.3 模板引擎thymeleaf
  3. 3. 2 项目构建
    1. 3.1. 2.1 创建项目
    2. 3.2. 2.2 建表
  4. 4. 3 项目实现
    1. 4.1. 3.1 项目效果
    2. 4.2. 3.2 项目结构
  5. 5. 4 代码实现
    1. 5.1. 4.1 前台页面
    2. 5.2. 4.2 后台业务实现
      1. 5.2.1. 4.2.1 实体类Employee
      2. 5.2.2. 4.2.2 数据库操作层repo
      3. 5.2.3. 4.2.3 业务代码service
      4. 5.2.4. 4.2.4 Web接口
    3. 5.3. 4.3 配置文件
  6. 6. 5 总结