springboot的crud案例
在学习了一段springboot后,跟着网上的老师做了一遍springboot+thymeleaf的crud案例,没有连接数据库。
以下是项目的目录结构:
引入静态资源.PNG静态资源引入+模拟数据库
首先引入项目的静态资源,我们可以在bootstrap模板的网站下载好一个静态模板,然后将该模板的HTML页面放入templates,将静态资源js、css、img这些文件存放在static的文件夹下。
我们以企业管理系统来实现crud,创建基本的两个实体类,分别是职员employee和部门department。
//部门表(省略无参有参构造,setter,getter方法)
public class Department {
private Integer id; //部门id
private String departmentName; //部门名称
//员工表
public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;
private Date birthday;
private Department department;
dao层
由于我们并没有链接数据库,所以我们在dao层中要模拟数据库,实现增删改查。
package com.szw.springboot05.dao;
import com.szw.springboot05.been.Department;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
//部门dao
@Repository("departmentDao")
public class DepartmentDao {
//模拟数据库中的数据
private static Map<Integer, Department> departments = null;
static {
departments = new HashMap<Integer, Department>();//创建一个部门表
departments.put(101,new Department(101,"教学部"));
departments.put(102,new Department(102,"市场部"));
departments.put(103,new Department(103,"教研部"));
departments.put(104,new Department(104,"运营部"));
departments.put(105,new Department(105,"后勤部"));
}
//获得所有部门的信息
public Collection<Department> getDepartments(){
return departments.values();
}
//通过id得到部门
public Department getDepartmentById(Integer id){
return departments.get(id);
}
}
package com.szw.springboot05.dao;
import com.szw.springboot05.been.Department;
import com.szw.springboot05.been.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
//员工Dao
@Repository
public class EmployeeDao {
//模拟数据库中的数据
private static Map<Integer, Employee> employess = null;
//员工所属的部门
@Autowired
private DepartmentDao departmentDao;
static {
employess = new HashMap<Integer,Employee>(); //创建一个部门表
employess.put(1001,new Employee(1001,"AA","1111@qq.com",0,new Department(101,"教学部")));
employess.put(1002,new Employee(1002,"BB","2222@qq.com",1,new Department(102,"市场部")));
employess.put(1003,new Employee(1003,"CC","3333@qq.com",1,new Department(103,"教研部")));
employess.put(1004,new Employee(1004,"DD","4444@qq.com",0,new Department(104,"运营部")));
employess.put(1005,new Employee(1005,"EE","5555@qq.com",1,new Department(105,"后勤部")));
}
//主键递增
private static Integer initId = 1006;
//增加一个员工
public void save(Employee employee){
if(employee.getId() == null){
employee.setId(initId++);
System.out.println("递增");
}
employee.setDepartment(departmentDao.getDepartmentById(employee.getDepartment().getId()));
employess.put(employee.getId(),employee);
}
//查询全部员工信息
public Collection<Employee> getAll(){
return employess.values();
}
//通过id查询员工
public Employee getEmployeeById(Integer id){
return employess.get(id);
}
//删除员工
public void delete(Integer id){
employess.remove(id);
}
}
完成对数据库的模拟后,我们要先进行首页的功能。
这里我们要使用配置类对首页实现访问:
package com.szw.springboot05.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.*;
import java.util.Locale;
//配置,帮助我们扩展配置
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
//视图跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
registry.addViewController("/index.html").setViewName("index");
}
}
配置好后我们可以启动项目,发现项目首页并没有样式。
我们打开html页面的代码,在头部中引入thymeleaf的头部。
<html lang="en" xmlns:th="http://www.thymeleaf.org"></pre>
引入该头部后,我们将每个页面的需要引入静态资源的链接改成thymeleaf的格式。
<link th:href="@{/css/bootstrap.min.css}">
注意原先的assert是不用再加的,如果需要jquery文件,可以在webjars网站复制maven的坐标,粘贴到pom文件中就可以了。
我们重启项目,打开首页,会发现样式加载ok了。
国际化
国际化:就是对一个页面语言的切换。
步骤:
1、编写国际化编写文件
2、使用resourceBundleMessageSource管理国际化资源文件
3、在页面上使用fmt:message取出国际化内容
在资源文件夹下,创建一个i18n文件,然后创建login.properties和login_en_US.properties,这时你会发现多了一个文件夹。
国际化~.png在该文件中,我们再创建一个login_zh_CN.properties文件,点击文件,我们会发现如下图的可视化工具。
这个可视化工具,会一次配置到三个配置文件中,比较方便。
可视化.png对这三种环境进行设置
可视化中配置.png去页面中获取国际化的值:
html文件中.png注意以上thymeleaf的写法,不在标签内的值要用[[#{}]进行取值,在标签体内用th进行取值。
完成之后,要在控制首页国际化的标签中设置超链接。
<a class="btn btn-sm" th:href="@{/index.html(l='zh_CN')}">中文</a>
<a class="btn btn-sm" th:href="@{/index.html(l='en_US')}">English</a>
然后创建一个类来实现LocalResolver:
package com.szw.springboot05.config;
import org.springframework.web.servlet.LocaleResolver;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
public class MyLocaleResolver implements LocaleResolver {
//解析请求
@Override
public Locale resolveLocale(HttpServletRequest request) {
//获取请求中的语言参数
String language = request.getParameter("l");
//如果没有就使用默认的
Locale locale = Locale.getDefault();
//如果请求的链接携带了国际化的参数
if(!StringUtils.isEmpty(language)){
//zh_CN
String[] split = language.split("_");
//国家,地区
locale = new Locale(split[0],split[1]);
}
return locale;
}
@Override
public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) {
}
}
之后要在配置类中加载:
//自定义的国际化组件就会生效
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
这样才可以使组件实现,国际化就实现啦。
登录+拦截器
现在开始实现登录,由于我们没有数据库,所以用户名和密码设置为不为空和123就可以了。
package com.szw.springboot05.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.thymeleaf.util.StringUtils;
import javax.servlet.http.HttpSession;
@Controller
public class LoginController {
// @RequestMapping(value = "/user/login",method = RequestMethod.POST),相当于底下那个注解
@PostMapping(value = "/user/login")
public String login(@RequestParam(value = "username") String username,
@RequestParam(value = "password") String password,
Model model,
HttpSession session) {
if (!StringUtils.isEmpty(username) && "123".equals(password)) {
//登录成功,将该用户的信息添加到session中
session.setAttribute("loginUser",username);
//为了防止重复表单提交,可以设置为重定向
return "redirect:/main.html";
} else {
//登陆失败
model.addAttribute("msg","用户名或者密码错误!");
return "index";
}
}
}
我们在控制层完成后,要记得在配置类中的视图跳转中加上main.html->dashboard。
registry.addViewController("/main.html").setViewName("dashboard");
登录成功后,我们将该用户的信息添加到了session中。
为了防止用户没有登录就可以通过地址栏对网站进行访问,要在配置类中设置拦截器。
首先判断该用户是否登录:
package com.szw.springboot05.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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){
request.setAttribute("msg","没有权限,请先登录");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else {
return true;
}
}
}
然后在配置类中注册该拦截器:
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login","/","/css/**","/js/**","/img/**");
//静态资源无法加载,参考博客: https://blog.csdn.net/qq_41773240/article/details/93321854
}
这样登录和拦截就配置好啦。
公共资源的设置
登录后,我们发现每个页面的上部和左侧部基本一样。这时我们可以用thymeleaf的公共资源的配置。
创建红线所指的文件夹和文件。
[图片上传失败...(image-428ad6-1581486178423)]
该文件用于存放相同的样式。
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">欢迎您,[[${session.loginUser}]]</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" th:href="@{/main.html}">Sign out</a>
</li>
</ul>
</nav>
这个是上部的样式。在最外部的标签中加上th:fragment="topBox"。
然后我们在需要该样式的页面上引入即可。
<div th:replace="commons/bar::topBox"></div>
侧边栏样式也是如此。
增删改查
package com.szw.springboot05.controller;
import com.szw.springboot05.been.Department;
import com.szw.springboot05.been.Employee;
import com.szw.springboot05.dao.DepartmentDao;
import com.szw.springboot05.dao.EmployeeDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import javax.websocket.server.PathParam;
import java.util.Collection;
@Controller
public class EmpController {
@Autowired
EmployeeDao employeeDao;
@Autowired
DepartmentDao departmentDao;
//查询所有的员工返回列表
@GetMapping("/emps")
public String list(Model model){
Collection<Employee> employees = employeeDao.getAll();
//放在请求域中
model.addAttribute("emps",employees);
//这里thymeleaf会进行拼接
return "emp/list";
}
//来到添加员工页面
@GetMapping("/emp")
public String toAddPage(Model model){
//来到添加页面,查出所有的部门
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("depts",departments);
return "emp/add";
}
//员工添加
@PostMapping("/emp")
public String addEmp(Employee employee){
System.out.println(employee);
employeeDao.save(employee);
//redirect是重定向
//forward是请求转发,如果用请求转发,刷新浏览器时会进行重复提交表单
return "redirect:/emps";
}
//来到员工修改页面
@GetMapping("/emp/{id}")
public String toEditPage(@PathVariable("id") Integer id,Model model){
//查询出所有的部门
Collection<Department> departments = departmentDao.getDepartments();
model.addAttribute("depts",departments);
//查询点击员工的信息
Employee employee = employeeDao.getEmployeeById(id);
model.addAttribute("emp",employee);
return "emp/update";
}
//员工修改
@PutMapping("/emp")
public String updateEmp(Employee employee){
System.out.println("重定向。。");
employeeDao.save(employee);
return "redirect:/emps";
}
//删除员工
@GetMapping("/demp/{id}")
public String delete(@PathVariable("id")Integer id){
System.out.println("输出要删除"+id);
employeeDao.delete(id);
return "redirect:/emps";
}
}
以上是增删改查的controller,不做太多解释,业务逻辑与ssm基本一样。
网友评论