网站搭建好有什么内容可以修改/广告竞价推广
伟人毛主席倡导我们“活到老学到老”,老人家更是生命不息读书不止的光辉榜样。已到不惑之年的我,一直想抽点时间研学Springboot。最近闲暇之余亲自动手操刀springboot,浅尝辄止般体验了一把微服务架构之美!博文详细记录了我的体验过程之旅,希望对有需求的童鞋有帮助。(想快速上手的童鞋建议先拜读并实验CSDN博主「sunnyzyq」的原创文章《Springboot项目搭建(前端到数据库,超详细)》(原文链接:https://blog.csdn.net/sunnyzyq/java/article/details/86711708,本文便是在博主「sunnyzyq」博文的基础上展开的研学之旅。)
体验装备:
平台:macOS Catalina version 10.15.4
环境:Eclipse IDE for Enterprise Java Developers 4.14.0
框架:Springboot
工具:Maven
数据库:Mysql8.0.20
前端:html/Thymeleaf
后台:JPA
IDE可根据自己装备选择,我的环境搭建准备工作涉及Eclipse、Mysql及Maven安装配置,细节就不在此啰嗦,不明白的童鞋可自行百度了解。下面开始我的体验之旅。
知识储备:容器、控制反转IoC、注入依赖DI、MVC 、Spring Bean
容器:可以认为是一个黑盒,只要按其提供的标准接口就可以拿到需要的东西,不需要关心其内部实现细节,充分体现了面向对象编程中封装与多态特点。
控制反转IoC:是一种思想,好莱坞原则,“不要给我们打电话,我们会打给你”,由主动变被动,再也不用瞎操心了,只需要告诉容器你要什么,剩下的事容器都帮你搞定。
注入依赖DI:实现控制反转IoC思想的技术手段,一般采用构造函数,getter和setter方法实现。
MVC:代码上实现业务逻辑分离,一般分展示层、服务层、数据操作层、控制层,各自分工明确,只做自己份内的事,决不抢人家的饭碗。
Bean:实体类,Springboot容器管理的对象。
1 实验内容及要求
1.1 实验内容:开发一个员工信息管理系统,需求非常简单,只有一张信息表user,字段只有工号、姓名、年龄、简介。要求实现最基本的CRUD功能即可,即增加(Create)、读取(Retrieve)、更新(Update)和删除(Delete)。此外还需要实现模糊查询功能,根据模糊用户名快速查找定位员工信息。
1.2 实验要求:技术选型要求采用SpringBoot框架、MVC架构编程实现。
1.3 效果展示:分用户列表页(含分页、搜索、删除功能)、增加页、编辑页。系统登陆主界面如下图
增加页展示如下
编辑页展示如下
搜索展示如下(支持模糊查寻)
麻雀虽小,五脏俱全。。本实验内容涵盖了道友们必须掌握的入门大法CRUD,对SpringBoot框架的理解有很好的帮助作用。其实,学习掌握任何一门语言亲自动手操刀撸码是必须的,能让我们快、准、狠的理解相应技术理念并运用到实战开发环境中去。
下面开始项目开发之旅......
2 创建项目
2.1 运行Eclipse,选择File >New >New Project >Maven Project,点击Next。
2.2 直接默认,点击Next。
2.3 Select an Archetype默认选中"All Catalogs",这里点击选择"Internal",找到maven-archetype-quickstart,点出Next。
2.4 填写 GroupId、ArtifactId,可根据自己单位域名拆分填写。Package会自动生成,点击Finish,项目创建完成。
2.5 项目目录结构如下图。
2.6 可以看到项目根文件夹为感叹号,这是由于JRE System Library默认选择为J2SE-1.5,这里我们右键JRE System Library>Properties>Execution environment>下拉菜单>选择1.8版本>Apply and Close,感叹号去除。
2.7 修正后的项目目录结构如下图
至此,项目基本目录搭建完成,我们需要重点关注src/main/java文件夹及pom.xml项目对象模型文件,这是我们要撸码配置的主战场。pom.xml文件是用来配置项目运行所需的依赖包,可根据项目实际需要添加导入需要的jar包。src/main/java文件夹下目录只有一个包src/main/java/com.myspringboot及一个类文件App.java。
根据MVC架构理念,我们的项目需要在src/main/java/com.myspringboot目录下创建实体类com.myspringboot.bean包、控制层com.myspringboot.controller包、服务层com.myspringboot.service包、数据接入层com.myspringboot.dao包四个包。接下来在每一层包中均创建父类或接口和子类实现类,便于系统功能扩展,把每层公有的属性方法放在父类或接口中,子类通过继承或接口父类公有属性方法并根据需要实现具体功能。基于上述理念,我们在bean包创建了BaseBean.java父类和User.java子类两个bean,在service包创建了UserService.java接口及实现子类UserServiceImpl.java(建立位于父类下的单独包com.myspringboot.service.impl),在dao包创建了CommonDao.java父类和UserDao.java子类实现类,在controller包创建UsreCtorller.java控制类。
我们还在src/main/java文件夹下单独建立了资源文件夹resoures,创建application.yml来配置项目环境属性,并在其上创建static和templates文件夹。static文件夹用于存放css、js文件,templates文件夹用于存放前端html模板。项目最终完整目录结构组成见下图。
3 项目配置及搬砖撸码
3.1 配置pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0modelVersion> <groupId>comgroupId> <artifactId>myspringbootartifactId> <version>0.0.1-SNAPSHOTversion> <packaging>jarpackaging> <parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-parentartifactId> <version>2.0.5.RELEASEversion> parent> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starterartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-webartifactId> dependency> <dependency> <groupId>junitgroupId> <artifactId>junitartifactId> <scope>testscope> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-devtoolsartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-thymeleafartifactId> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> <version>8.0.20version> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-data-jpaartifactId> dependency> dependencies>project>
3.2 配置application.yml
server: port: 80 servlet: session: timeout: 30 tomcat: max-threads: 0 uri-encoding: UTF-8 spring: thymeleaf: prefix: classpath:/templates/ suffix: .html mode: HTML5 encoding: UTF-8 servlet: content-type: text/html cache: false datasource: url: jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai driver-class-name: com.mysql.cj.jdbc.Driver username: ****** password: ****** dbcp2: initial-size: 10 max-total: 20 max-idle: 8 min-idle: 8 jpa: database: mysql show-sql: true hibernate: ddl-auto: update naming: physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
3.3 com.myspringboot包主程序App.java
package com.myspringboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * Hello world! * */@SpringBootApplicationpublic class App { public static void main( String[] args ){ SpringApplication.run(App.class,args); }}
3.4 实体类Bean
3.4.1 BaseBean.java
package com.myspringboot.bean;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.MappedSuperclass;@MappedSuperclasspublic class BaseBean{ /* * AutoID */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id=id; }}
3.4.2 User.java子类bean
package com.myspringboot.bean;import javax.persistence.Entity;import javax.persistence.Table;import javax.persistence.Column;@Entity@Table(name = "user") public class User extends BaseBean{ @Column(nullable=false) private Integer uid; @Column(nullable=false) private String name; @Column(nullable=false) private int age; @Column(nullable=false) private String info; public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid=uid; } public String getName() { return name; } public void setName(String name) { this.name=name; } public int getAge() { return age; } public void setAge(int age) { this.age=age; } public String getInfo() { return info; } public void setInfo(String info) { this.info=info; }}
3.5 Svervice类
3.5.1 UserSverive父类接口
package com.myspringboot.service;import java.util.List;import org.springframework.data.domain.Page;import com.myspringboot.bean.User;public interface UserService { void save(User user); void deleteById(Integer id); User findById(Integer id); User edit(Integer id); User update(User user); ListfindByNameLike(String name); ListgetUserList(); PageuserList(Integer start,Integer limit);}
3.5.1 UserSveriveImpl子类实现类
package com.myspringboot.service.impl;import java.util.List;import javax.transaction.Transactional;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.myspringboot.bean.User;import com.myspringboot.dao.UserDao;import com.myspringboot.service.UserService;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Pageable;import org.springframework.data.domain.Sort;@Service@Transactionalpublic class UserServiceImpl implements UserService{ @Autowired private UserDao userDao; @Override public void save(User user) { userDao.save(user); } @Override public void deleteById(Integer id) { userDao.deleteById(id); } @Override public User edit(Integer id) { return userDao.findById(id).get(); } @Override public User update(User user) { return userDao.save(user); } @Override public ListgetUserList(){ return userDao.findAll(); } @Override public ListfindByNameLike(String name){ return userDao.findByNameLike("%"+name+"%"); } @Override public PageuserList(Integer start,Integer limit) { start=start<0 ? 0 : start; Sort sort=new Sort(Sort.DEFAULT_DIRECTION,"uid"); Pageable pageable=PageRequest.of(start, limit, sort); Page page=userDao.findAll(pageable); return page; } @Override public User findById(Integer id) { // TODO Auto-generated method stub return null; }}
3.6 数据访问层
3.6.1 CommonDao
package com.myspringboot.dao;import org.springframework.data.jpa.repository.JpaRepository;import org.springframework.stereotype.Repository;import com.myspringboot.bean.BaseBean;@Repositorypublic interface CommonDao extends JpaRepository { }
3.6.2 UserDao类
package com.myspringboot.dao;import java.util.List;import org.springframework.stereotype.Repository;import com.myspringboot.bean.User;@Repositorypublic interface UserDao extends CommonDao{ //Name fuzzy search ... List<User> findByNameLike(String name); }
3.7控制层类UserController
package com.myspringboot.controller;import java.util.List;import javax.servlet.http.HttpServletRequest;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.ui.Model;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.stereotype.Controller;import com.myspringboot.bean.User;import com.myspringboot.service.UserService;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.data.domain.Page;@Controllerpublic class UserController { @Autowired private UserService userService; @RequestMapping("/hello") @ResponseBody public String hello() { return "Hello World !!!"; } @RequestMapping("/index") public String index(Model model) { model.addAttribute("uid", 2001); model.addAttribute("name","jack"); model.addAttribute("age",20); model.addAttribute("info","我是一个爱学习的好青年。"); return "index"; } //Save @RequestMapping("/save") public String save(User user) { userService.save(user); System.out.println("save success !"); return "redirect:users"; } //Delete @RequestMapping("/delete") public String delete(Integer id) { userService.deleteById(id); return "redirect:users"; } //Edit the displayed page @RequestMapping("/edit") @ResponseBody public ModelAndView edit(Integer id) { User user=userService.edit(id); ModelAndView mav=new ModelAndView("edit"); mav.addObject("user", user); return mav; } //Update @RequestMapping("/update") public String update(User user) { userService.update(user); return "redirect:users"; } //Pageless display @RequestMapping("/userlist") public String userList(Model model) { List userList=userService.getUserList(); model.addAttribute("userList",userList); return "list"; } //Paginated display @RequestMapping("/users") public ModelAndView users(@RequestParam(value="start", defaultValue = "0") Integer start,@RequestParam(value = "limit", defaultValue = "5") Integer limit) { Page page=userService.userList(start,limit); ModelAndView mav=new ModelAndView("users"); mav.addObject("page", page); return mav; } //Name fuzzy query display @RequestMapping("/search") public ModelAndView search(HttpServletRequest request) { ModelAndView modelAndView=new ModelAndView(); String query=request.getParameter("query"); List userSearch=userService.findByNameLike(query);// List userSearch=userService.getUserList(); modelAndView.addObject("userSearch",userSearch); modelAndView.addObject("query", query); modelAndView.setViewName("/list"); return modelAndView; }}
3.8资源类文件
3.8.1 templates文件夹前端展示页
(1). users.html
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head > <meta charset="UTF-8"> <title>User Listtitle> <link th:href="@{common.css}" rel="stylesheet" type="text/css" />head><body > <a th:href="@{/}">Add New Usera><form action="/search" method="post"><div align="center"> <div> Enter name for quick search:<input type="text" th:value="${query}" name="query" placeholder="Support fuzzy search ..."> <button>searchbutton> div> <table > <tr> <th>CardNumberth> <th>Nameth> <th>Aageth> <th>Profileth> <th>Operateth> tr> <tr th:each="item:${page.content}"> <td th:text="${item.uid}">CardNumbertd> <td th:text="${item.name}">Nametd> <td th:text="${item.age}">Agetd> <td th:text="${item.info}">Profiletd> <td> <a th:href="@{/edit(id=${item.id})}">Edita> <a th:href="@{/delete(id=${item.id})}">Deletea> td> tr> table>div><div align="center"> <a th:href="@{/users(start=0)}">[Start]a> <a th:if="${not page.isFirst()}" th:href="@{/users(start=${page.number-1})}">[Previous]a> <a th:if="${not page.isLast()}" th:href="@{/users(start=${page.number+1})}">[Next]a> <a th:href="@{/users(start=${page.totalPages-1})}">[End]a>div>form>body>html>
(2). edit.html
<html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link th:href="@{common.css}" rel="stylesheet" type="text/css" /> <title>Edittitle> head> <body > <div align="center"> <form action="/update" method="post"> <table> <tr><td>td><td><input type="hidden" name="id" th:field="${user.id}"/>td>tr> <tr><td><label for="txtname">CardNumber:label>td> <td><input type="text" name="uid" th:field="${user.uid}"/>td>tr> <tr><td><label for="txtname">Name:label>td> <td><input type="text" name="name" th:field="${user.name}"/>td>tr> <tr><td><label for="txtage">Age:label>td> <td><input type="text" name="age" th:field="${user.age}"/>td>tr> <tr><td><label for="txtname">Profile:label>td> <td><input type="text" name="info" th:field="${user.info}"/>td>tr> table> <input type="submit" value="Submit"> form> div> body>html>
(3) list.html
<html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link th:href="@{common.css}" rel="stylesheet" type="text/css" /> <title>userSearchtitle> head> <body > <a href="/users"><button>Return to User Listbutton>a> <div align="center"> <table border="1"> <tr> <th>CardNumberth> <th>Nameth> <th>Ageth> <th>Profileth> tr> <tr th:each="user:${userSearch}"> <td th:text="${user.uid}">td> <td th:text="${user.name}">td> <td th:text="${user.age}">td> <td th:text="${user.info}">td> tr> table> div> body>html>
(4) index.html
<html xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link th:href="@{common.css}" rel="stylesheet" type="text/css" /> <title>Createtitle> head> <body > <form action="/save" method="post"> <div align="center"> <br/> Add New User<br/> <table> <tr><td>CardNumber:td><td><input type="text" th:value="${uid}" name="uid">td>tr> <tr><td>Name:td><td><input type="text" th:value="${name}" name="name">td>tr> <tr><td>Age:td><td><input type="text" th:value="${age}" name="age">td>tr> <tr><td>Profile:td><td><input type="text" th:value="${info}" name="info">td>tr> table> <button>Savebutton> div> form> body>html>
3.8.2 static文件
实验只用到了common.css
/* body{ background-color: #0ACFF0} */table,th,td { border: 1px solid green; border-collapse: collapse; }
4. 实验总结及展望
第3节内容是我撸码体验SpringBoot的全部过程,已无私贡献给道友们!我的整体感觉是SpringBoot框架简单、快捷、高效,很值得道友们研学!下一步有时间,我准备对其增加文件上传(图片显示)、多表关联CRUD、权限认证审核等功能,根据需求不断丰富完善。有需要打包源码的道友可微信或公众号内留言。