目录
自动装配的原理
Pom.xml文件
-
Spring-boot-dependencies:核心依赖在父工程中
-
我们在引入一些springboot依赖的时候不需要指定版本,就是因为有这些版本仓库
启动器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency>
-
就是springboot的启动场景
-
比如spring-boot-start-starter-web他会帮我们自动导入web的所有依赖
-
springboot会将所有的功能场景都变成一个个的启动器
-
我们需要使用什么功能,只需要找到对应的启动器start就行了
@SpringBootConfiguration //springboot的配置 @Configuration //Spring配置类 @Component //说明他也是个Spring的组建 @EnableAutoConfiguration //自动导入配置 @AutoConfigurationPackage //自动配置包 @Import({Registrar.class}) //导入选择器‘包注册’ @Import(AutoConfigurationImportSelector.class) // 自动导入选择
Thmeleaf的介绍
Thmeleaf是一款用于渲染XML/HTML/HTM5内容的模版引擎,类似于JSP,它可以轻易的与springMVC框架进行集成作为web应用的模版引擎,而与其他模版相比较,Thmeleaf最大的特点就是能够直接在浏览器中打开并正确显示模板页面,而不需要启动整个web应用。
THmeleaf使用了自然的模版技术,不会破坏文档的结构,模版依旧是有效的XML文档,模版还可以用作工作原型,Thmeleaf会在运行期替换掉静态值。
需要注意的是Thmeleaf对于URL的处理是通过语法@{...}来处理的,Thmeleaf支持绝对路径URL
<a th:href="@{http://www.thymeleaf.org}">Thymeleaf</a>
条件求值
<a th:href="@{/login}" th:unless=${session.user != null}>Login</a>
for循环
<tr th:each="prod : ${prods}"> <td th:text="${prod.name}">Onions</td> <td th:text="${prod.price}">2.41</td> <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> </tr>
WebJars
WebJars可以让我们使用jar包的形式来进行使用前端的各种框架和组件。
什么是WebJars
WebJars是将客户端资源打包成jar包,对资源进行统一的依赖管理,WebJars的jar包部署在maven中央仓库上。
为何使用WebJars
我们在进行开发javaWeb项目的时候会使用maven、Gradle等构建工具以实现对jar包版本的依赖管理,用来做到对项目的自动化管理,但是对于JavaScript、css等前段资源包,我们只能通过放在webapp下面进行操作,这样就无法对这些资源进行依赖管理,那么Webjars就提供给我们这写资源的jar包资源,对他们进行依赖管理。
<dependency> <groupId>org.webjars</groupId> <artifactId>vue</artifactId> <version>2.5.16</version> </dependency>
页面引入
<link th:href="@{/webjars/bootstrap/3.3.6/dist/css/bootstrap.css}" rel="stylesheet"></link>
使用springboot实现CRUD操作
项目结构
依赖引入
首先在父工程中给定版本
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.3</version> </parent>
子工程依赖引入
<dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.22</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>4.0.0</version> </dependency> </dependencies>
加入自定义过滤器类
可以改变默认的首页改成我们的登陆界面
@Configuration public class MyConfiguration implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/").setViewName("login"); registry.addViewController("/main.html").setViewName("dashboard"); } }
Controller
package com.offcn.springboot.controller; import com.offcn.springboot.pojo.Dept; import com.offcn.springboot.pojo.Employee; import com.offcn.springboot.service.EmployeeService; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; @Controller public class EmployeeController { @Resource private EmployeeService employeeService; @RequestMapping("/login") public String login(String username, String password, ModelMap modelMap){ if ("admin".equals(username)&&"admin".equals(password)){ return "redirect:/main.html"; }else { modelMap.addAttribute("msg","登陆失败请重新登录"); return "login"; } } @RequestMapping("emps") public String emps(ModelMap modelMap){ List<Employee> emps = employeeService.getAllEmp(); modelMap.addAttribute("emps",emps); return "emp/list"; } //添加员工,显示所有部门 @RequestMapping("showAllDept") public String showAllDept(ModelMap modelMap){ List<Dept> depts = employeeService.getAllDept(); modelMap.addAttribute("depts",depts); return "emp/add"; } //添加员工 @RequestMapping("updateEmp") public String updateEmp(Employee employee){ boolean flag = employeeService.updateEmp(employee); if (flag){ return "redirect:/emps"; }else { return "error"; } } //删除员工 @RequestMapping("deleteInfo") public String deleteInfo(Integer eid){ boolean flag = employeeService.deleteInfo(eid); if (flag){ return "redirect:emps"; }else { return "error"; } } //编辑员工之前的数据回显 @RequestMapping("getOneInfo") public String getOneInfo(ModelMap modelMap,Integer eid){ List<Dept> depts = employeeService.getAllDept(); modelMap.addAttribute("depts",depts); Employee one = employeeService.getOneInfo(eid); modelMap.addAttribute("emp",one); return "emp/add"; } }
使用lombok创建实体类
@Data @AllArgsConstructor @NoArgsConstructor public class Dept implements Serializable { private Integer did; private String dname; private String local; } @Data @AllArgsConstructor @NoArgsConstructor public class Employee { private Integer eid; private String ename; private String email; private Date bir; private Integer dfk; private Integer gender; private Dept dept; }
业务层的实现类
package com.offcn.springboot.service; import com.offcn.springboot.mapper.DeptMapper; import com.offcn.springboot.mapper.EmployeeMapper; import com.offcn.springboot.pojo.Dept; import com.offcn.springboot.pojo.Employee; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; @Service public class EmployeeServiceImpl implements EmployeeService{ @Resource private EmployeeMapper employeeMapper; @Resource private DeptMapper deptMapper; @Override public List<Employee> getAllEmp() { return employeeMapper.showAllInfo(); } @Override public List<Dept> getAllDept() { return deptMapper.getAllDept(); } @Override public boolean updateEmp(Employee employee) { boolean flag = false; if (employee.getEid()!=null){ flag= employeeMapper.updateEmp(employee)>0; }else { flag= employeeMapper.addInfo(employee)>0; } return flag; } @Override public boolean deleteInfo(Integer eid) { return employeeMapper.deleteInfo(eid)>0; } @Override public Employee getOneInfo(Integer eid) { return employeeMapper.getOneInfo(eid); } }
前端html使用了Thymeleaf模版引擎
登陆界面login.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Signin Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link href="asserts/css/signin.css" th:href="@{/asserts/css/signin.css}" rel="stylesheet"> </head> <body class="text-center"> <form class="form-signin" action="dashboard.html" th:action="@{/login}" method="post"> <img class="mb-4" th:src="@{/asserts/img/bootstrap-solid.svg}" src="asserts/img/bootstrap-solid.svg" alt="" width="72" height="72"> <h1 class="h3 mb-3 font-weight-normal" >Please sign in</h1> <!--判断--> <p style="color: #ff0000" th:text="${msg}" th:if="${not #strings.isEmpty(msg)}"></p> <label class="sr-only">Username</label> <input type="text" name="username" class="form-control" placeholder="Username" required="" autofocus=""> <label class="sr-only">Password</label> <input type="password" name="password" class="form-control" placeholder="Password" required=""> <div class="checkbox mb-3"> <label> <input type="checkbox" value="remember-me"/>remeber me </label> </div> <button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button> <p class="mt-5 mb-3 text-muted">© 2020-2021</p> <a class="btn btn-sm" >中文</a> <a class="btn btn-sm">English</a> </form> </body> </html>
添加界面add.html
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Dashboard Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link href="asserts/css/dashboard.css" th:href="@{/asserts/css/dashboard.css}" rel="stylesheet"> <style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; } </style> </head> <body> <!--引入抽取的topbar--> <!--模板名:会使用thymeleaf的前后缀配置规则进行解析--> <div th:replace="commons/bar::topbar"></div> <div class="container-fluid"> <div class="row"> <!--引入侧边栏--> <div th:replace="commons/bar::#sidebar(activeUri='emps')"></div> <main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4"> <!--需要区分是员工修改还是添加;--> <form th:action="@{/updateEmp}" method="post" > <!-- 隐藏域中隐藏更新用户的主键值 --> <input type="hidden" name="eid" th:value="${emp!=null}?${emp.eid}" > <div class="form-group"> <label>LastName</label> <input name="ename" type="text" th:value="${emp!=null}?${emp.ename}" class="form-control" placeholder="zhangsan" > </div> <div class="form-group"> <label>Email</label> <input name="email" type="text" th:value="${emp!=null}?${emp.email}" class="form-control" placeholder="zhangsan@offcn.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" th:checked="${emp!=null}?${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!=null}?${emp.gender==0}"> <label class="form-check-label">女</label> </div> </div> <div class="form-group"> <label>department</label> <!--提交的是部门的id--> <select class="form-control" name="dfk"> <option th:each="dept:${depts}" th:selected="${emp!=null}?${dept.did=emp.dfk}" th:text="${dept.dname}" th:value="${dept.did}">1</option> </select> </div> <div class="form-group"> <label>Birth</label> <input name="bir" type="text" th:value="${emp!=null}?${#dates.format(emp.bir,'yyyy-MM-dd')}" class="form-control" placeholder="zhangsan" > </div> <button type="submit" class="btn btn-primary" th:text="${emp==null}?'添加':'更新'">添加</button> </form> </main> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js" th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script> <script type="text/javascript" src="asserts/js/popper.min.js" th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script> <script type="text/javascript" src="asserts/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script> <!-- Icons --> <script type="text/javascript" src="asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script> <script> feather.replace() </script> </body> </html>
数据展示界面list.html
<!DOCTYPE html> <!-- saved from url=(0052)http://getbootstrap.com/docs/4.0/examples/dashboard/ --> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="description" content=""> <meta name="author" content=""> <title>Dashboard Template for Bootstrap</title> <!-- Bootstrap core CSS --> <link href="asserts/css/bootstrap.min.css" th:href="@{/webjars/bootstrap/4.0.0/css/bootstrap.css}" rel="stylesheet"> <!-- Custom styles for this template --> <link href="asserts/css/dashboard.css" th:href="@{/asserts/css/dashboard.css}" rel="stylesheet"> <style type="text/css"> /* Chart.js */ @-webkit-keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } @keyframes chartjs-render-animation { from { opacity: 0.99 } to { opacity: 1 } } .chartjs-render-monitor { -webkit-animation: chartjs-render-animation 0.001s; animation: chartjs-render-animation 0.001s; } </style> </head> <body> <!--引入抽取的topbar--> <!--模板名:会使用thymeleaf的前后缀配置规则进行解析--> <div th:replace="commons/bar::topbar"></div> <div class="container-fluid"> <div class="row"> <!--引入侧边栏--> <div th:replace="commons/bar::#sidebar(activeUri='emps')"></div> <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="@{/showAllDept}">员工添加</a></h2> <div class="table-responsive"> <table class="table table-striped table-sm"> <thead> <tr> <th>#</th> <th>Name</th> <th>email</th> <th>gender</th> <th>department</th> <th>birth</th> <th>操作</th> </tr> </thead> <tbody> <tr th:each="emp : ${emps}"> <td>[[${emp.eid}]]</td> <td th:text="${emp.ename}">12</td> <td th:text="${emp.email}">12</td> <td th:text="${emp.gender==0}?'女':'男'">12</td> <td th:text="${emp.dept.dname}">12</td> <td th:text="${#dates.format(emp.bir,'yyyy-MM-dd')}">12</td> <td> <a class="btn btn-sm btn-primary" th:href="@{/getOneInfo(eid=${emp.eid})}">更新</a> <a class="btn btn-sm btn-primary" th:href="@{/deleteInfo(eid=${emp.eid})}" >删除</a> </td> </tr> </tbody> </table> </div> </main> <form id="deleteEmpForm" method="post"> <input type="hidden" name="_method" value="delete"/> </form> </div> </div> <!-- Bootstrap core JavaScript ================================================== --> <!-- Placed at the end of the document so the pages load faster --> <script type="text/javascript" src="asserts/js/jquery-3.2.1.slim.min.js" th:src="@{/webjars/jquery/3.3.1/jquery.js}"></script> <script type="text/javascript" src="asserts/js/popper.min.js" th:src="@{/webjars/popper.js/1.11.1/dist/popper.js}"></script> <script type="text/javascript" src="asserts/js/bootstrap.min.js" th:src="@{/webjars/bootstrap/4.0.0/js/bootstrap.js}"></script> <!-- Icons --> <script type="text/javascript" src="asserts/js/feather.min.js" th:src="@{/asserts/js/feather.min.js}"></script> <script> feather.replace() </script> <!-- <script>--> <!-- $(".deleteBtn").click(function(){--> <!-- //删除当前员工的--> <!-- $("#deleteEmpForm").attr("action",$(this).attr("del_uri")).submit();--> <!-- return false;--> <!-- });--> <!-- </script>--> </body> </html>