首先得先建一个spring boot项目
导入了相关的依赖
jpa是自己建实体类 然后加上相关注解 这样运行主程序会自动给数据库建立表
在yml里配置
server:
servlet:
context-path: /springboot05
spring:
jpa:
hibernate:
ddl-auto: update #create会清除原有的表建新的 update只会更新
show-sql: true
datasource:
#1.JDBC
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/yy?useUnicode=true&characterEncoding=utf8
username: root
password: 123
druid:
#2.连接池配置
#初始化连接池的连接数量 大小,最小,最大
initial-size: 5
min-idle: 5
max-active: 20
#配置获取连接等待超时的时间
max-wait: 60000
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
time-between-eviction-runs-millis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 30000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: true
test-on-return: false
# 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
#3.基础监控配置
web-stat-filter:
enabled: true
url-pattern: /*
#设置不统计哪些URL
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
session-stat-enable: true
session-stat-max-count: 100
stat-view-servlet:
enabled: true
url-pattern: /druid/* #项目请求druid访问的路径 项目名加/druid
reset-enable: true
#设置监控页面的登录名和密码
login-username: admin
login-password: 123
allow: 127.0.0.1
#deny: 192.168.1.100 代表什么IP地址可用访问
上面是jap相关配置 下面是数据库连接池配置 然后在pom里降低MySQL的版本
5.1.44 ${mysql.version}
然后开始建立实体类 上面有对应的注解 建好之后启动主程序类就可在数据库生成对应的表
package com.yy.springboot.entity;
import lombok.ToString;
import sun.awt.SunHints;
import javax.persistence.*;
/**
* @author黄圆圆
* @site [email protected]
* @company yy公司
* @create 2019-03-19 19:47
*/
@Entity
@Table(name = "t_springboot_teacher")
@ToString
public class Teacher {
@Id//表明是主键 并且自增长
@GeneratedValue
private Integer tid;
@Column(length = 16)//表示实体类与表的映射关系 列
private String tname;
@Column(length = 4)
private String sex;
@Column(length = 100)
private String description;
@Column(length = 200)
private String imagePath;
public Integer getTid() {
return tid;
}
public void setTid(Integer tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
}
然后开始写对应每个层 dao层 jpa的方式继承两个类就可以了 方法它自己有 调用就好了
* 只要继承JpaRepository,通常所用的增删查改方法都有
* 第一个参数:操作的实体类
* 第二个参数:实体类对应数据表的主键
*
* 要使用高级查询必须继承
* org.springframework.data.jpa.repository.JpaSpecificationExecutor接口
*/
public interface TeacherDao extends JpaRepository, JpaSpecificationExecutor {
}
service层
package com.yy.springboot.service;
import com.yy.springboot.dao.TeacherDao;
import com.yy.springboot.entity.Teacher;
import com.yy.springboot.util.PageBean;
import com.yy.springboot.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
/**
* @author黄圆圆
* @site [email protected]
* @company yy公司
* @create 2019-03-19 20:06
*/
@Service
public class TeacherServiceImpl implements TeacherService {
@Autowired
private TeacherDao teacherDao;
@Override
public Teacher save(Teacher teacher) {
return teacherDao.save(teacher);
}
@Override
public void deleteById(Integer id) {
teacherDao.deleteById(id);
}
@Override
public Teacher findById(Integer id) {
return teacherDao.findById(id).get();
}
@Override
public Page listPager(Teacher teacher, PageBean pageBean) {
// jpa的Pageable分页是从0页码开始
Pageable pageable = PageRequest.of(pageBean.getPage() - 1, pageBean.getRows());
return teacherDao.findAll(new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Predicate predicate = criteriaBuilder.conjunction();
if (teacher != null) {
if (StringUtils.isNotBlank(teacher.getTname())) {
predicate.getExpressions().add(criteriaBuilder.like(root.get("tname"), "%" + teacher.getTname() + "%"));
}
}
return predicate;
}
}, pageable);
}
}
里面有一个方法是需要用到分页 以前分页是jsp页面用标签去写 用spring boot创建的项目页面是HTML的 不能用标签 所以就需要用一个助手类来完成 是用bootstrap3来写的
package com.yy.springboot.util;
import java.util.Map;
import java.util.Set;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2019-02-20 21:38
*
* 基于bootstrap3生成分页代码
*/
public class PageUtil {
public static String createPageCode(PageBean pageBean) {
StringBuffer sb = new StringBuffer();
/*
* 拼接向后台提交数据的form表单
* 注意:拼接的form表单中的page参数是变化的,所以不需要保留上一次请求的值
*/
sb.append("
");
if (pageBean.getTotal() == 0) {
return "未查询到数据";
} else {
sb.append("首页 ");
if (pageBean.getPage() > 1) {
sb.append("上一页 ");
} else {
sb.append("上一页 ");
}
for (int i = pageBean.getPage() - 1; i <= pageBean.getPage() + 1; i++) {
if (i < 1 || i > pageBean.getMaxPage()) {
continue;
}
if (i == pageBean.getPage()) {
sb.append("" + i + " ");
} else {
sb.append("" + i + " ");
}
}
if (pageBean.getPage() < pageBean.getMaxPage()) {
sb.append("下一页 ");
} else {
sb.append("下一页 ");
}
sb.append("尾页 ");
}
/*
* 给分页条添加与后台交互的js代码
*/
sb.append("");
return sb.toString();
}
}
pagebean
package com.yy.springboot.util;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.Map;
public class PageBean implements Serializable {
private static final long serialVersionUID = 2422581023658455731L;
//页码
private int page = 1;
//每页显示记录数
private int rows = 5;
//总记录数
private int total = 0;
//是否分页
private boolean isPagination = true;
//上一次的请求路径
private String url;
//获取所有的请求参数
private Map map;
public PageBean() {
super();
}
//设置请求参数
public void setRequest(HttpServletRequest req) {
String page = req.getParameter("page");
String rows = req.getParameter("rows");
String pagination = req.getParameter("pagination");
this.setPage(page);
this.setRows(rows);
this.setPagination(pagination);
this.url = req.getContextPath() + req.getServletPath();
this.map = req.getParameterMap();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public void setPage(String page) {
if (null != page && !"".equals(page.trim()))
this.page = Integer.parseInt(page);
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public void setRows(String rows) {
if (null != rows && !"".equals(rows.trim()))
this.rows = Integer.parseInt(rows);
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public void setTotal(String total) {
this.total = Integer.parseInt(total);
}
public boolean isPagination() {
return isPagination;
}
public void setPagination(boolean isPagination) {
this.isPagination = isPagination;
}
public void setPagination(String isPagination) {
if (null != isPagination && !"".equals(isPagination.trim()))
this.isPagination = Boolean.parseBoolean(isPagination);
}
/**
* 获取分页起始标记位置
*
* @return
*/
public int getStartIndex() {
//(当前页码-1)*显示记录数
return (this.getPage() - 1) * this.rows;
}
/**
* 末页
*
* @return
*/
public int getMaxPage() {
int totalpage = this.total / this.rows;
if (this.total % this.rows != 0)
totalpage++;
return totalpage;
}
/**
* 下一页
*
* @return
*/
public int getNextPage() {
int nextPage = this.page + 1;
if (this.page >= this.getMaxPage())
nextPage = this.getMaxPage();
return nextPage;
}
/**
* 上一页
*
* @return
*/
public int getPreivousPage() {
int previousPage = this.page - 1;
if (previousPage < 1)
previousPage = 1;
return previousPage;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", isPagination=" + isPagination
+ "]";
}
}
stringutils
package com.yy.springboot.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
public class StringUtils {
// 私有的构造方法,保护此类不能在外部实例化
private StringUtils() {
}
/**
* 如果字符串等于null或去空格后等于"",则返回true,否则返回false
*
* @param s
* @return
*/
public static boolean isBlank(String s) {
boolean b = false;
if (null == s || s.trim().equals("")) {
b = true;
}
return b;
}
/**
* 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
*
* @param s
* @return
*/
public static boolean isNotBlank(String s) {
return !isBlank(s);
}
/**
* set集合转string
*
* @param hasPerms
* @return
*/
public static String SetToString(Set hasPerms) {
return Arrays.toString(hasPerms.toArray()).replaceAll(" ", "").replace("[", "").replace("]", "");
}
/**
* 转换成模糊查询所需参数
*
* @param before
* @return
*/
public static String toLikeStr(String before) {
return isBlank(before) ? null : "%" + before + "%";
}
/**
* 将图片的服务器访问地址转换为真实存放地址
*
* @param imgpath 图片访问地址(http://localhost:8080/uploadImage/2019/01/26/20190126000000.jpg)
* @param serverDir uploadImage
* @param realDir E:/temp/
* @return
*/
public static String serverPath2realPath(String imgpath, String serverDir, String realDir) {
imgpath = imgpath.substring(imgpath.indexOf(serverDir));
return imgpath.replace(serverDir, realDir);
}
/**
* 过滤掉集合里的空格
*
* @param list
* @return
*/
public static List filterWhite(List list) {
List resultList = new ArrayList();
for (String l : list) {
if (isNotBlank(l)) {
resultList.add(l);
}
}
return resultList;
}
/**
* 从html中提取纯文本
*
* @param strHtml
* @return
*/
public static String html2Text(String strHtml) {
String txtcontent = strHtml.replaceAll("?[^>]+>", ""); //剔出的标签
txtcontent = txtcontent.replaceAll("\\s*|\t|\r|\n", "");//去除字符串中的空格,回车,换行符,制表符
return txtcontent;
}
public static void main(String[] args) {
}
}
controller层 里面需要一个上传图片的依赖
commons-fileupload commons-fileupload 1.3.3
package com.yy.springboot.contorller;
import com.yy.springboot.entity.Teacher;
import com.yy.springboot.service.TeacherService;
import com.yy.springboot.util.PageBean;
import com.yy.springboot.util.PageUtil;
import com.yy.springboot.util.StringUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
@Controller
@RequestMapping("/teacher")
public class TeacherController {
@Autowired
private TeacherService teacherService;
@RequestMapping("/listPager")
public ModelAndView list(Teacher teacher, HttpServletRequest request) {
PageBean pageBean = new PageBean();
pageBean.setRequest(request);
ModelAndView modelAndView = new ModelAndView();
Page teachers = teacherService.listPager(teacher, pageBean);
modelAndView.addObject("teachers", teachers.getContent());
pageBean.setTotal(teachers.getTotalElements() + "");
modelAndView.addObject("pageCode", PageUtil.createPageCode(pageBean)/*.replaceAll("<","<").replaceAll(">:",">")*/);
modelAndView.setViewName("list");
return modelAndView;
}
@RequestMapping("/toEdit")
public ModelAndView toEdit(Teacher teacher) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("edit");
modelAndView.addObject("sexArr", new String[]{"男", "女"});
if (!(teacher.getTid() == null || "".equals(teacher.getTid()))) {
Teacher t = teacherService.findById(teacher.getTid());
modelAndView.addObject("teacher", t);
}
return modelAndView;
}
@RequestMapping("/add")
public String add(Teacher teacher, MultipartFile image) {
try {
String diskPath = "E://temp/" + image.getOriginalFilename();
String serverPath = "http://localhost:8080/springboot/uploadImages/" + image.getOriginalFilename();
if (StringUtils.isNotBlank(image.getOriginalFilename())) {
FileUtils.copyInputStreamToFile(image.getInputStream(), new File(diskPath));
teacher.setImagePath(serverPath);
}
teacherService.save(teacher);
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/teacher/listPager";
}
@RequestMapping("/edit")
public String edit(Teacher teacher, MultipartFile image) {
String diskPath = "E://temp/" + image.getOriginalFilename();
String serverPath = "http://localhost:8080/springboot/uploadImages/" + image.getOriginalFilename();
if (StringUtils.isNotBlank(image.getOriginalFilename())) {
try {
FileUtils.copyInputStreamToFile(image.getInputStream(), new File(diskPath));
teacher.setImagePath(serverPath);
} catch (IOException e) {
e.printStackTrace();
}
}
teacherService.save(teacher);
return "redirect:/teacher/listPager";
}
@RequestMapping("/del/{bid}")
public String del(@PathVariable(value = "bid") Integer bid) {
teacherService.deleteById(bid);
return "redirect:/teacher/listPager";
}
}
在查询所有的方法那里返回一个page是因为pagebean要拿到总记录数去返回 如果返回list集合就拿不到pagebean的值
然后还需要一个资源文件配置类
/**
* 资源映射路径
* 上传文件映射配置类MyWebAppConfigurer.java
*/
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/uploadImages/**").addResourceLocations("file:F:/image/");
super.addResourceHandlers(registry);
}
}
后台基本这么多 然后是前台 引入boostrap相关css js
list.html
两种跳转传值方法
书籍列表
新增
ID
头像
姓名
性别
简介
操作
删除
修改
edit.html
三元运算跳转方法
用户编辑界面
最后运行效果如图