行业知识
SpringBoot中的增删改查案例
目录
一、案例说明
二、数据库
三、案例源码
3.1、pom文件
3.2、Application.yml
3.3、项目结构
a)整体结构
b)Java代码部分
c)资源文件部分
3.4、业务功能的实现
1)配置类
2)实体类
3)Mapper文件
4)Service
5)Controller
6)视图
四、测试效果图
启动项目
浏览器访问
添加功能
修改
删除
附件:pom文件
一、案例说明
Idea 2022.3.3汉化版 、mysql 5.7 、 JDK 8
springboot + thymeleaf + restful + layui.css + bootstrap
图书表和出版社表为例,实现增删改查的功能。
该案例需要准备一些样式表:
layui官网
bootstrap的下载地址
bootstrap-select下载地址
bootstrap-table下载地址
(在bootstrap-select和bootstrap-table中也都是使用文件中dist目录下的文件)
commons-lang3的官方教程
commons-lang3的官方API
1. commons-lang3是Apache提供的一个java.lang包的增强版本,Lang3为java.lang API提供了许多帮助程序实用程序,特别是字符串操作方法,基本数值方法,对象反射,并发,创建和序列化以及系统属性。此外,它还包含对java.urti.Date的基本增强,以及一系列专用于构建方法的实用程序,例如hashCode,toString和equals。
2.提供了官方的API地址,可通过文档获取需要的支持。
二、数据库
Book表
Publish表
温馨小贴士:book 表中字段 pic 为图片路径(表中是图片名字和格式)。
在案例中使用到了文件(图片)上传。则需要注意的是:文件保存位置。
//将所有/upimg/的访问请求都拦截到指定目录registry.addResourceHandler("/upimg/**").addResourceLocations("file:D://uploadImg//"); 由于在配置类BeanConfig中配置了拦截器(),将所有/upimg/的访问请求都拦截到指定目录。
所以,需要根据指定目录存放文件(图片)。
本案例文件(图片)存放地址为:
没有文件夹的要根据自己的设置进行创建,并存放使用的图片。否则,项目运行无法加载图片。
三、案例源码
3.1、pom文件
1、需要加载各种所需依赖坐标。
2、构建资源。
target文件夹是项目编译之后的资源文件夹。该文件夹中存在的内容才可以被项目中读取使用。
如果target中没有所需要的文件资源时, 检查pom.xml文件中是否拥有以下配置:
src/main/java **/*.yml **/*.properties **/*.xml false src/main/resources **/*.css **/*.js **/*.html **/*.png **/*.jpg **/*.properties **/*.yml **/*.xml **/*.conf false
3.2、Application.yml
# 服务器设置: 端口号和访问路径server: port: 8088 servlet: context-path: /shq# 数据源设置spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/2101_files?serverTimezone=UTC username: root password: 123456 thymeleaf: cache: false suffix: .html web: resources: static-locations: classpath:/templates/,classpath:/static/image/# 让控制台显示执行的SQL语句logging: level: cn: shq: mapper: debug# mybatis配置mybatis: type-aliases-package: cn.shq.model # 别名 configuration: auto-mapping-behavior: full #设置全自动映射 use-column-label: true # 列标签代替字段名#设置mapper的路径 mapper-locations: classpath:cn/shq/mapper/*.xml
3.3、项目结构
a)整体结构
b)Java代码部分
c)资源文件部分
案例中所使用的CSS、JS文件需要从各个官网上下载(本文头部提供的有各个网址)。
把静态文件放到static下面;把HTML文件放到templates下面;
3.4、业务功能的实现
1)配置类
BeasConfig.java
package cn.shq.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.util.ResourceUtils;import org.springframework.web.filter.HiddenHttpMethodFilter;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configurationpublic class BeanConfig extends WebMvcConfigurationSupport { /** * 拦截器 * */ @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) {// 自定义设置:指定程序中 路径为 /upimg/** 的文件,统统都到指定的Locations中去找(即 D://uploadImg//目录下去找) registry.addResourceHandler("/upimg/**").addResourceLocations("file:D://uploadImg//");// 访问路径为/static/的请求,都到项目中static目录中。 registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");// 在pom文件中 加载的各种前端文件 保存在resources/webjar目录下。// 如果没有这一行代码的配置,则运行测试发现:没有样式表,找不到对应的样式文件。 registry.addResourceHandler("/webjars/**").addResourceLocations(ResourceUtils.CLASSPATH_URL_PREFIX +"/META-INF/resources/webjars/"); super.addResourceHandlers(registry); } /** * 添加restful支持 */ @Bean public HiddenHttpMethodFilter hiddenHttpMethodFilter() { HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter(); hiddenHttpMethodFilter.setBeanName("HiddenHttpMethodFilter"); hiddenHttpMethodFilter.setMethodParam("_method"); return hiddenHttpMethodFilter; }} 2)实体类
Book.java
package cn.shq.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.format.annotation.DateTimeFormat;import java.util.Date;@Data@NoArgsConstructor@AllArgsConstructorpublic class Book { private long bookId; private String bookName; private String author; private long price; private long pubId; /** * @DateTimeFormat:可以解决日期格式问题。 * 因为页面传递过来的是String类型,而java中需要是Date类型。所以使用该注解可以进行类型转换。 * 也可以使用另外一种方式实现类型转换:自己写一个日期格式转换类。 * */ @DateTimeFormat(pattern = "yyyy-MM-dd") private Date pubDate; private String pic;} Publish.java
package cn.shq.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@NoArgsConstructor@AllArgsConstructorpublic class Publish { private long pubId; private String pubName; private String loc;} BookVO.java
package cn.shq.model;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.springframework.format.annotation.DateTimeFormat;import java.util.Date;@Data@NoArgsConstructor@AllArgsConstructorpublic class BookVO {// book类中的属性 private long bookId; private String bookName; private String author; private long price; private Date pubDate; private String pic;// publish 出版社 private Publish publish;} 3)Mapper文件
BookMapper.java
package cn.shq.mapper;import cn.shq.model.Book;import cn.shq.model.BookVO;import org.apache.ibatis.annotations.Mapper;import org.springframework.stereotype.Component;import java.util.List;@Mapper@Componentpublic interface BookMapper { // 查询全部 List selectAll(); // 添加 int insert(Book book); // 删除 (根据编号进行删除) int del(Integer bookId); // 修改 int update(Book book); // 条件查询 -----> 根据编号查找对应信息 Book findByID(Integer bookId);} BookMapper.xml
select b.*,p.* from book b,publish p where b.pubId=p.pubId insert into book(bookName,pubId,pubDate,pic)values(#{bookName},#{pubId,jdbcType=INTEGER},#{pubDate,jdbcType=TIMESTAMP},#{pic}) delete from book where bookId = #{bookId} update book set bookName= #{bookName},pubId = #{pubId},pubDate = #{pubDate},pic = #{pic} where bookId = #{bookId} select * from book where bookId = #{bookId} PublishMapper.java
package cn.shq.mapper;import cn.shq.model.Publish;import org.apache.ibatis.annotations.Mapper;import org.apache.ibatis.annotations.Select;import org.springframework.stereotype.Component;import java.util.List;@Mapper@Componentpublic interface PublishMapper { @Select("select * from publish") List selectAll();} 4)Service
BookService.java
package cn.shq.service;import cn.shq.model.Book;import cn.shq.model.BookVO;import java.util.List;public interface BookService { // 查询全部 List selectAll(); // 添加 int insert(Book book); // 删除 (根据编号进行删除) int del(Integer bookId); // 修改 int update(Book book); // 条件查询 -----> 根据编号查找对应信息 Book findByID(Integer bookId);} BookServiceImpl.java
package cn.shq.service.impl;import cn.shq.mapper.BookMapper;import cn.shq.model.Book;import cn.shq.model.BookVO;import cn.shq.service.BookService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service@Transactionalpublic class BookServiceImp implements BookService { @Autowired BookMapper bookMapper; @Override public List selectAll() { return bookMapper.selectAll(); } @Override public int insert(Book book) { return bookMapper.insert(book); } @Override public int del(Integer bookId) { return bookMapper.del(bookId); } @Override public int update(Book book) { return bookMapper.update(book); } @Override public Book findByID(Integer bookId) { return bookMapper.findByID(bookId); }} PublicServiceImpl.java
package cn.shq.service.impl;import cn.shq.mapper.PublishMapper;import cn.shq.model.Publish;import cn.shq.service.PublishService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import java.util.List;@Service@Transactionalpublic class PublishServiceImpl implements PublishService { @Autowired PublishMapper mapper; @Override public List selectAll() { return mapper.selectAll(); }} 5)Controller
在控制器中使用到了图片的文件上传以及页面传递的日期格式,所以需要写一个工具类。
工具类BaseController.java
该工具类在本案例中放在util包中。
package cn.shq.util;import org.apache.commons.lang3.time.DateUtils;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.InitBinder;import java.beans.PropertyEditorSupport;import java.io.File;import java.text.ParseException;import java.util.Date;public class BaseController extends DateUtils { //定义真实的上传路径 : 案例中所用到的文件(图片)保存在改目录下。 public final String REAL_PATH = "D:"+ File.separator+"uploadImg"+File.separator; //访问路径 public final String VISIT_PATH = File.separator+"upimg"+File.separator; /** * 将前台传递过来的日期格式的字符串,自动转化为Date类型 */ private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM", "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM" }; /** * 日期型字符串转化为日期 格式 */ public static Date parseDate(Object str) { if (str == null) { return null; } try { return parseDate(str.toString(), parsePatterns); } catch (ParseException e) { return null; } } @InitBinder public void initBinder(WebDataBinder binder) { // Date 类型转换 binder.registerCustomEditor(Date.class, new PropertyEditorSupport() { @Override public void setAsText(String text) { setValue(parseDate(text)); } }); }} 控制器类BookController.java
package cn.shq.controller;import cn.shq.model.*;import cn.shq.service.BookService;import cn.shq.service.PublishService;import cn.shq.util.BaseController;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.*;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.util.HashMap;import java.util.List;import java.util.Map;@Controllerpublic class BookController extends BaseController { @Autowired BookService bookService; @Autowired PublishService publishService; // 应用的上下文路径,也可以称为项目路径 @Value("${server.servlet.context-path}") String projName; // 将项目路径 注入到 projName中。 /** * 查询全部 * */ @GetMapping("/books") public String books(Model model){ List bs = bookService.selectAll(); System.out.println("bs:"+bs); model.addAttribute("bs",bs); return "index"; } /** * 文件上传 * */ @PostMapping("/doUpload") @ResponseBody public Map doUpload(MultipartFile photo) throws IOException { Map result = new HashMap(); //判断是否为空 if(null ==photo){ result.put("type","error"); result.put("msg","请选择上传的图片"); return result; } //判断大小 long size = photo.getSize(); if(size > 2000000){ result.put("type","error"); result.put("msg","上传的图片超过限定大小,请上传2M以内的图片!"); return result; } //拿到图片的后缀 int index = photo.getOriginalFilename().lastIndexOf("."); String suffix = photo.getOriginalFilename().substring(index); //判断后缀是否是图片 if(!".jpg,.jpeg,.png,.gif".toUpperCase().contains(suffix.toUpperCase())){ result.put("type","error"); result.put("msg","必须上传指定格式的图片.jpg,.jpeg,.png,.gif"); return result; } //修改文件的名字 String newFileName = System.currentTimeMillis()+""+suffix; //建立文件 ↓ 因为上面继承了工具类,则可以直接使用this表示。 File file = new File(this.REAL_PATH,newFileName); //写入磁盘 photo.transferTo(file);//把文件写入到指定的路径中; //返回给前端数据 result.put("type","success"); result.put("msg","上传成功!"); result.put("fileName",newFileName); result.put("imgName",projName+File.separator+this.VISIT_PATH+newFileName); result.put("filePath",this.VISIT_PATH); return result; } /** * 添加 * 1、点击添加按钮,先执行查询所有的出版社,然后跳往添加的页面。 * 2、执行添加操作。 * */ @GetMapping("/toAdd") public String toAdd(Model model){ List pubs = publishService.selectAll(); model.addAttribute("pubs",pubs); return "add"; } @PostMapping("/doAdd") public String doAdd(Book book){ bookService.insert(book); return "redirect:/books"; } //删除 @GetMapping("/doDel/{bookId}") public String doDel(@PathVariable Integer bookId){ bookService.del(bookId); return "redirect:/books"; } /** * 修改: * 1、点击修改按钮,先根据ID查询到对应书籍的信息,和出版社信息,跳往修改页面。 * 2、执行修改操作。 * */ @GetMapping("/toUpdate/{bookId}") public String toUpdate(@PathVariable Integer bookId,Model model){ Book book = bookService.findByID(bookId); List pubs = publishService.selectAll(); model.addAttribute("book",book); model.addAttribute("pubs",pubs); return "update"; } @PutMapping("/doUpdate") public String doUpdate(Book book){ bookService.update(book); return "redirect:/books"; }} 6)视图
index.html
首页 添加
| 图书编号 | 图书名称 | 出版社 | 出版日期 | 宣传页 | 操作 |
| 图书名称 | 出版社 | 出版日期 | 删除 修改 |
add.html
添加图书 图书名称 出版社 请选择 出版日期 科目图片 添加 $(function () { // 日期插件 : 日期格式 和 中国区域 $('#datetimepicker1').datetimepicker({ format: 'YYYY-MM-DD', locale: moment.locale('zh-cn') }); //点击上传 $("#upload").click(function(){ //判断是否选中一个文件 if($("#photoFile").val() == ""){ alert('必须选择图片!'); return; } //封装传给后台的数据 var formData = new FormData();//虚拟出来一个表单数据 formData.append("photo",document.getElementById("photoFile").files[0]); $.ajax({ url:'[[@{/doUpload}]]', type:'POST', data:formData, contentType: false, processData: false, dataType:'json', success:function(result){ $("#preview_photo").attr("src",result.filePath+result.fileName); alert($("#preview_photo").attr("src")); $("#pic").val(result.fileName); }, error:function(msg){ console.log(msg); } }); }); }); update.html
修改界面 图书名称 出版社 请选择 出版日期 科目图片 Submit $(function(){ $('#datetimepicker1').datetimepicker({ format: 'YYYY-MM-DD', locale: moment.locale('zh-cn') }); $('.selectpicker').selectpicker({}); //点击上传 $("#upload").click(function(){ //判断是否选中一个文件 if($("#photoFile").val() == ""){ alert('必须选择图片!'); return; } //封装传给后台的数据 var formData = new FormData();//虚拟出来一个表单数据 formData.append("photo",document.getElementById("photoFile").files[0]); $.ajax({ url:'[[@{/doUpload}]]', type:'POST', data:formData, contentType: false, processData: false, dataType:'json', success:function(result){ $("#preview_photo").attr("src",result.imgName); $("#pic").val(result.fileName); }, error:function(msg){ console.log(msg); } }); }); }); 四、测试效果图
启动项目
浏览器访问
地址:http://localhost:8088/shq/books
效果:
添加功能
修改
删除
附件:pom文件
4.0.0 org.springframework.boot spring-boot-starter-parent 2.7.12 cn.shq springBoot_CRUD 0.0.1-SNAPSHOT springBoot_CRUD springBoot_CRUD 1.8 org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.0 org.springframework.boot spring-boot-devtools runtime true mysql mysql-connector-java 8.0.25 org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine org.springframework.boot spring-boot-configuration-processor true org.webjars jquery 3.3.1 org.webjars layui 2.5.6 org.webjars bootstrap 4.5.2 org.webjars bootstrap-select 1.13.17 org.webjars bootstrap-datetimepicker 2.4.4 org.webjars bootstrap-table 1.16.0 org.webjars momentjs 2.24.0 org.apache.commons commons-lang3 3.9 tk.mybatis mapper-spring-boot-starter 2.1.5 com.alibaba druid 1.1.10 org.springframework.boot spring-boot-starter-jdbc src/main/java **/*.yml **/*.properties **/*.xml false src/main/resources **/*.css **/*.js **/*.html **/*.png **/*.jpg **/*.properties **/*.yml **/*.xml **/*.conf false org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok