SpringBoot小项目
开发中使用的Pom依赖
<dependencies>
<!--thymeleaf 引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--springboot web的开发支持-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok 插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 数据层 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
可能出现的关于Maven的资源过滤问题
<!--Maven 资源文件过滤-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
整合Mybatis
-
在resources目录下新建 application.yaml
spring: datasource: url: jdbc:mysql://localhost:3306/springboot?useSSL=false&useUnicode=true&serverTimezone=UTC&characterEncoding=UTF-8 username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver #关闭模板引擎的缓存 thymeleaf: cache: false messages: basename: i18n.login mvc: format: date: yyyy-MM-dd # 配置mybatis规则、使用MyBatisPlus则此项配置无效 mybatis: # 注意:对应实体类的路径 type-aliases-package: com.yp.webtest.pojo #指定myBatis的核心配置文件与Mapper映射文件 mapper-locations: classpath:com/yp/webtest/mapper/xml/*.xml configuration: map-underscore-to-camel-case: true-
编写测试类查看数据是否连接成功
@Slf4j @SpringBootTest class SpringbootWebTestApplicationTests { // DI注入 数据源 @Autowired JdbcTemplate jdbcTemplate; @Test void contextLoads() { List<Map<String, Object>> list = jdbcTemplate.queryForList("select * from employee"); log.info("数据库信息:"+list.toString()); } }-
导入实体类 pojo
package com.yp.webtest.pojo; import lombok.Data; /** * @author edz */ @Data public class Department { private Integer id; private String departmentName; }package com.yp.webtest.pojo; import lombok.Data; import java.util.Date; @Data public class Employee { private Integer id; private String lastName; private String email; //1 male, 0 female private Integer gender; private Integer department; private Date birth; // 多个员工可以是同一个部门 表结构的关系是多对一 private Department eDepartment; }- 编写接口类 和 接口的Mapper.xml
package com.yp.webtest.mapper; import com.yp.webtest.pojo.Employee; import org.apache.ibatis.annotations.Mapper; import java.util.List; /** * @Description: * @Mapper : 表示本类是一个 MyBatis 的 Mapper * @Author: YP * @Version: 1.0 * @Date: 2021/1/18$ 7:15 下午$ */ @Mapper public interface EmployeeMapper { // 获取所有员工信息 List<Employee> getEmployees(); // 新增一个员工 int save(Employee employee); // 修改员工信息 int update(Employee employee); // 通过id获得员工信息 Employee get(Integer id); // 通过id删除员工 int delete(Integer id); }package com.yp.webtest.mapper; import com.yp.webtest.pojo.Department; import org.apache.ibatis.annotations.Mapper; import java.util.List; /** * @Description: * @Author: YP * @Version: 1.0 * @Date: 2021/1/18$ 7:15 下午$ */ @Mapper public interface DepartmentMapper { // 获取所有部门信息 List<Department> getDepartments(); // 通过id获得部门 Department getDepartment(Integer id); }<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.yp.webtest.mapper.EmployeeMapper"> <!-- 按查询结果嵌套处理 思路: 1. 直接查询出结果,进行结果集的映射 --> <select id="getEmployees" resultMap="EmployeeMap"> select e.id as eid,last_name,email,gender,birth,d.id as did,d.department_name as dname from department d,employee e where d.id = e.department </select> <resultMap id="EmployeeMap" type="Employee"> <id property="id" column="eid"/> <result property="lastName" column="last_name"/> <result property="email" column="email"/> <result property="gender" column="gender"/> <result property="birth" column="birth"/> <!--association关联属性 property属性名 javaType属性类型 column在多 的一方的表中的列名--> <association property="eDepartment" javaType="Department"> <id property="id" column="did"/> <result property="departmentName" column="dname"/> </association> </resultMap> <insert id="save" parameterType="Employee"> insert into employee (last_name,email,gender,department,birth) values (#{lastName},#{email},#{gender},#{department},#{birth}); </insert> <update id="update" parameterType="Employee"> update employee set last_name = #{lastName},email=#{email},gender=#{gender},department=#{department},birth=#{birth} where id = #{id} ; </update> <select id="get" resultType="Employee"> select * from employee where id = #{id} </select> <delete id="delete" parameterType="int"> delete from employee where id = #{id} </delete> </mapper><?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.yp.webtest.mapper.DepartmentMapper"> <select id="getDepartments" resultType="Department"> select * from department; </select> <select id="getDepartment" resultType="Department" parameterType="int"> select * from department where id = #{id}; </select> </mapper> -
-
导入静态资源文件
- css、js、img放在resources下的static文件夹下
- html放在resources下的templates文件夹下
最终的文件结构:

项目的整体文件结构:

访问资源的首页
-
在config文件夹下编写一个MyConfig类
package com.yp.webtest.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* @Description:
* 编写MVC的扩展配置, 重写WebMvcConfigurer的方法,完成业务请求的跳转
* 添加视图控制,完成页面的扩展
* @Author: YP
* @Version: 1.0
* @Date: 2021/1/19$ 9:09 上午$
*/
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("dashboard");
registry.addViewController("/main.html").setViewName("dashboard");
}
}
此时已经可以完成页面的正常跳转,仍需要解决资源导入的问题,因为使用的thymeleaf模板引擎,需要给所有的html问加上文件的约束,并使用th:href="@{/**}"的格式替换本地资源文件的引入
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<link th:href="@{/asserts/css/bootstrap.min.css}" rel="stylesheet">
登录和拦截器功能的书写
-
编写index.html文件下的属性
<form class="form-signin" th:action="@{/user/login}" method="post"> <img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" th:text="#{login.tip}" >Please sign in</h1> <!--判断是登录成功,使用if, ${}可以使用工具类--> <p style="color: red" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p> <label class="sr-only" th:text="#{login.username}" >Username</label> <input type="text" class="form-control" name="username" th:placeholder="#{login.username}" required="" autofocus=""> <label class="sr-only" th:text="#{login.password}" >Password</label> <input type="password" name="password" class="form-control" th:placeholder="#{login.password}" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"> [[#{login.remember}]] </label> </div> </form> -
在controller文件夹下编写用于登录的LoginController
package com.yp.webtest.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import javax.servlet.http.HttpSession;
/**
* @Description:
* @Author: YP
* @Version: 1.0
* @Date: 2021/1/18$ 8:04 下午$
*/
@Controller
public class LoginController {
@PostMapping("/user/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
Model model, HttpSession session){
if (!StringUtils.isEmpty(username) && "123".equals(password)){
//登录成功!将用户信息放入session
session.setAttribute("loginUser",username);
//登录成功!防止表单重复提交,我们重定向,在myconfing中有对main.html请求的处理,自动转发到dashboard
return "redirect:/main.html";
}else {
//登录失败!存放错误信息
model.addAttribute("msg","用户名密码错误");
return "index";
}
}
}
-
登录拦截器
在config文件下编写LoginHandlerInterceptor类
package com.yp.webtest.config; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * @Description: 登录拦截器 * @Author: YP * @Version: 1.0 * @Date: 2021/1/19$ 11:02 上午$ */ public class LoginHandlerInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 登录成功之后,获取用户的session Object loginUser = request.getSession().getAttribute("loginUser"); if (loginUser!=null){ // 放行 return true; }else { // 进行拦截, 未登录,跳转到登录页 request.setAttribute("msg","请先登录!"); request.getRequestDispatcher("/").forward(request,response); return false; } } }然后将自定义的拦截器注册到项目的SpringMVC配置类中! MyConfig类
package com.yp.webtest.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @Description: * 重写WebMvcConfigurer的方法,完成业务请求的跳转 * 添加视图控制,完成页面的扩展 * @Author: YP * @Version: 1.0 * @Date: 2021/1/19$ 9:09 上午$ */ @Configuration public class MyConfig implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("index"); registry.addViewController("/index.html").setViewName("dashboard"); registry.addViewController("/main.html").setViewName("dashboard"); } /** * Desc: 将自定义的组件注册到容器中 * @param * @return: org.springframework.web.servlet.LocaleResolver */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**") .excludePathPatterns("/","/user/login","/asserts/**"); } }数据库中员工列表的显示
修改页面员工管理的列表请求:
<a th:class="${active=='list.html'?'nav-link active':'nav-link'}" th:href="@{/emps}">员工管理</a>编写controller处理请求: EmployeeController.java
// controller层调用service层,这里是直接调用的dao层 @Autowired EmployeeMapper employeeMapper; //查询所有员工,返回列表页面 @GetMapping("/emps") public String list(Model model){ List<Employee> employees = employeeMapper.getEmployees(); //将结果放在请求中 model.addAttribute("emps",employees); return "emp/list"; }跳转到list.html页面
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <!--添加员工按钮--> <h2> <a class="btn btn-sm btn-success" href="emp" th:href="@{/emp}">添加员工</a> </h2> <div class="table-responsive"> <table class="table table-striped table-sm"> <thead> <tr> <th>id</th> <th>lastName</th> <th>email</th> <th>gender</th> <th>department</th> <th>birth</th> <!--我们还可以在显示的时候带一些操作按钮--> <th>操作</th> </tr> </thead> <tbody> <!--从数据库中获取数据--> <tr th:each="emp:${emps}"> <td th:text="${emp.id}"></td> <td>[[${emp.lastName}]]</td> <td th:text="${emp.email}"></td> <td th:text="${emp.gender==0?'女':'男'}"></td> <td th:text="${emp.EDepartment.departmentName}"></td> <!--<td th:text="${emp.birth}"></td>--> <!--使用时间格式化工具--> <td th:text="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm')}"></td> <!--操作--> <td> <a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.id}">编辑</a> <a class="btn btn-sm btn-danger" th:href="@{/delEmp/}+${emp.id}">删除</a> </td> </tr> </tbody> </table> </div> </main>添加员工
编写controller
@Autowired DepartmentMapper departmentMapper; //去员工添加页面 @GetMapping("/emp") public String toAddPage(Model model){ //查出所有的部门,提供选择 List<Department> departments = departmentMapper.getDepartments(); model.addAttribute("departments",departments); return "emp/add"; } //员工添加功能 //接收前端传递的参数,自动封装成为对象[要求前端传递的参数名,和属性名一致] @PostMapping("/emp") public String addEmp(Employee employee){ System.out.println(employee); //保存员工信息 employeeMapper.save(employee); //回到员工列表页面,可以使用redirect或者forward return "redirect:/emps"; }<!--添加员工的表单--> <form th:action="@{/emp}" method="post"> <div class="form-group"> <label>LastName</label> <input type="text" class="form-control" name="lastName" placeholder="ypp"> </div> <div class="form-group"> <label>Email</label> <input type="email" class="form-control" name="email" placeholder="123456@qq.com"> </div> <div class="form-group"> <label>Gender</label><br/> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" value="1"> <label class="form-check-label">男</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" value="0"> <label class="form-check-label">女</label> </div> </div> <div class="form-group"> <label>department</label> <!--提交的是部门的ID--> <select class="form-control" name="department"> <option th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}">1</option> </select> </div> <div class="form-group"> <label>Birth</label> <input type="text" class="form-control" name="birth" placeholder="birthday"> </div> <button type="submit" class="btn btn-primary">添加</button> </form>员工信息的修改
//去员工修改页面 @GetMapping("/emp/{id}") public String toUpdateEmp(@PathVariable("id") Integer id, Model model){ //根据id查出来员工 Employee employee = employeeMapper.get(id); System.out.println(employee); //将员工信息返回页面 model.addAttribute("emp",employee); //查出所有的部门,提供修改选择 List<Department> departments = departmentMapper.getDepartments(); model.addAttribute("departments",departments); return "emp/update"; } // 完成修改操作 @PostMapping("/updateEmp") public String updateEmp(Employee employee){ employeeMapper.update(employee); //回到员工列表页面 return "redirect:/emps"; }<form th:action="@{/updateEmp}" method="post"> <input name="id" type="hidden" class="form-control" th:value="${emp.id}"> <div class="form-group"> <label>LastName</label> <input name="lastName" type="text" class="form-control" th:value="${emp.lastName}"> </div> <div class="form-group"> <label>Email</label> <input name="email" type="email" class="form-control" th:value="${emp.email}"> </div> <div class="form-group"> <label>Gender</label><br/> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" value="1" th:checked="${emp.gender==1}"> <label class="form-check-label">男</label> </div> <div class="form-check form-check-inline"> <input class="form-check-input" type="radio" name="gender" value="0" th:checked="${emp.gender==0}"> <label class="form-check-label">女</label> </div> </div> <div class="form-group"> <label>department</label> <!--提交的是部门的ID--> <select class="form-control" name="department"> <option th:selected="${dept.id == emp.department}" th:each="dept:${departments}" th:text="${dept.departmentName}" th:value="${dept.id}">1 </option> </select> </div> <div class="form-group"> <label>Birth</label> <input name="birth" type="text" class="form-control" th:value="${#dates.format(emp.birth,'yyyy-MM-dd HH:mm')}"> </div> <button type="submit" class="btn btn-primary">修改</button> </form>删除员工
编写对应的controller
// 删除员工 @GetMapping("/delEmp/{id}") public String delEmp(@PathVariable("id") Integer id){ employeeMapper.delete(id); return "redirect:/emps"; }在list.html页面添加删除的标签
<a class="btn btn-sm btn-danger" th:href="@{/delEmp/}+${emp.id}">删除</a>
浙公网安备 33010602011771号