相关pom依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

  application.yml配置

spring:
jpa:
hibernate:
ddl-auto: update
show-sql: true

自动建表相关代码

package com.lingerqi.springboot03.entity;

import lombok.Data;

import javax.persistence.*;

/**
* @author xyls
* @blog name & blog address 027@0030
* @create  2019-11-30 16:42
*/
@Data
@Entity
@Table(name = "t_springboot_book_1")
public class Book {
@Id
@GeneratedValue
private Integer bid;
@Column(length = 100)
private String bname;
@Column
private float price; }

jpa值增删改查

* 只要继承JpaRepository,通常所用的增删查改方法都有

*  第一个参数:操作的实体类

*  第二个参数:实体类对应数据表的主键

*/

public interface JpaDao extends JpaRepository<Book, Integer> {

}

controller层

@Autowired
private JpaDao jpaDao; @RequestMapping("/add")
public String add(Book book){
jpaDao.save(book);
return "success";
} @RequestMapping("/edit")
public String edit(Book book){
jpaDao.save(book);
return "success";
} @RequestMapping("/del")
public String del(Book book){
jpaDao.delete(book);
return "success";
} @RequestMapping("/getOne")
public Book getOne(Integer bid){
// 会出现懒加载问题:org.hibernate.LazyInitializationException: could not initialize proxy - no Session
// return jpaDao.getOne(bid);
return jpaDao.findById(bid).get();
} @RequestMapping("/getAll")
public List<Book> getAll(){
return jpaDao.findAll();
}

    

新增:

jpa值复杂查询

 *  要使用高级查询必须继承
* org.springframework.data.jpa.repository.JpaSpecificationExecutor<T>接口
*/
public interface JpaDao extends JpaRepository<Book, Integer>, JpaSpecificationExecutor<Book> {
}

controller层

 

@RequestMapping("/getCondition")
public List<Book> getCondition(Book book){
return jpaDao.findAll(new Specification<Book>() {
@Override
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
Predicate predicate = criteriaBuilder.conjunction();
if(book != null){
if(null != book.getBname() && !"".equals(book.getBname())){
predicate.getExpressions().add(criteriaBuilder.like(root.get("bname"),"%"+book.getBname()+"%"));
}
}
return predicate;
}
});
}

SpringBoot+bootstarp界面版增删改查及图片上传

pom:

<mysql.version>5.1.44</mysql.version>
<version>${mysql.version}</version> <dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>

application.yml文件配置

 

server:
port: 80
servlet:
context-path: / spring:
jpa:
hibernate:
ddl-auto: 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/mybatis_ssm?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: 123
druid:
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
pool-prepared-statements: true
max-pool-prepared-statement-per-connection-size: 20
filter:
stat:
merge-sql: true
slow-sql-millis: 5000
web-stat-filter:
enabled: true
url-pattern: /*
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/*
reset-enable: true
login-username: root
login-password: 123
allow: 127.0.0.1
#deny: 192.168.1.100
thymeleaf:
cache: false # 解决图片上传大小限制问题,也可采取配置类
servlet:
multipart:
max-file-size: 20MB
max-request-size: 60MB
Springbootapplication.java:
@EnableTransactionManagement
@SpringBootApplication

  

上传文件映射配置类MyWebAppConfigurer.java

package com.lingerqi.springboot03.config;

/**
* @author xyls
* @blog name & blog address 027@0030
* @create  2019-12-01 11:10
*/ import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; /**
* 资源映射路径
*/
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/uploadImages/**").addResourceLocations("file:E:/temp/");
super.addResourceHandlers(registry);
}
}  

后台代码

StringUtils

package com.lingerqi.springboot03.utils;

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<String> filterWhite(List<String> list){
List<String> resultList=new ArrayList<String>();
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("</?[^>]+>", ""); //剔出<html>的标签
txtcontent = txtcontent.replaceAll("<a>\\s*|\t|\r|\n</a>", "");//去除字符串中的空格,回车,换行符,制表符
return txtcontent;
} public static void main(String[] args) {
}
}

 

PageUtil

package com.lingerqi.springboot03.utils;

import java.util.Map;
import java.util.Set; /**
* @author xyls
* @blog name & blog address 027@0030
* @create  2019-12-01 11:10
*
* 基于bootstrap3生成分页代码
*/
public class PageUtil {
public static String createPageCode(PageBean pageBean) {
StringBuffer sb = new StringBuffer();
/*
* 拼接向后台提交数据的form表单
* 注意:拼接的form表单中的page参数是变化的,所以不需要保留上一次请求的值
*/
sb.append("<form id='pageBeanForm' action='"+pageBean.getUrl()+"' method='post'>");
sb.append("<input type='hidden' name='page'>");
Map<String, String[]> parameterMap = pageBean.getParamMap();
if(parameterMap != null && parameterMap.size() > 0) {
Set<Map.Entry<String, String[]>> entrySet = parameterMap.entrySet();
for (Map.Entry<String, String[]> entry : entrySet) {
if(!"page".equals(entry.getKey())) {
String[] values = entry.getValue();
for (String val : values) {
sb.append("<input type='hidden' name='"+entry.getKey()+"' value='"+val+"'>");
}
}
}
}
sb.append("</form>"); if(pageBean.getTotal()==0){
return "未查询到数据";
}else{
sb.append("<li><a href='javascript:gotoPage(1)'>首页</a></li>");
if(pageBean.getPage()>1){
sb.append("<li><a href='javascript:gotoPage("+pageBean.getPreviousPage()+")'>上一页</a></li>");
}else{
sb.append("<li class='disabled'><a href='javascript:gotoPage(1)'>上一页</a></li>");
}
for(int i=pageBean.getPage()-1;i<=pageBean.getPage()+1;i++){
if(i<1||i>pageBean.getMaxPage()){
continue;
}
if(i==pageBean.getPage()){
sb.append("<li class='active'><a href='#'>"+i+"</a></li>");
}else{
sb.append("<li><a href='javascript:gotoPage("+i+")'>"+i+"</a></li>");
}
}
if(pageBean.getPage()<pageBean.getMaxPage()){
sb.append("<li><a href='javascript:gotoPage("+pageBean.getNextPage()+")'>下一页</a></li>");
}else{
sb.append("<li class='disabled'><a href='javascript:gotoPage("+pageBean.getMaxPage()+")'>下一页</a></li>");
}
sb.append("<li><a href='javascript:gotoPage("+pageBean.getMaxPage()+")'>尾页</a></li>");
} /*
* 给分页条添加与后台交互的js代码
*/
sb.append("<script type='text/javascript'>");
sb.append(" function gotoPage(page) {");
sb.append(" document.getElementById('pageBeanForm').page.value = page;");
sb.append(" document.getElementById('pageBeanForm').submit();");
sb.append(" }");
sb.append(" function skipPage() {");
sb.append(" var page = document.getElementById('skipPage').value;");
sb.append(" if(!page || isNaN(page) || parseInt(page)<1 || parseInt(page)>"+pageBean.getMaxPage()+"){");
sb.append(" alert('请输入1~N的数字');");
sb.append(" return;");
sb.append(" }");
sb.append(" gotoPage(page);");
sb.append(" }");
sb.append("</script>");
return sb.toString();
}
}

dao层

package com.lingerqi.springboot03.repository;

import com.lingerqi.springboot03.entity.Teacher;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; /**
* @author xyls
* @blog name & blog address 027@0030
* @create  2019-11-30 16:42
*
* 只要继承JpaRepository,通常所用的增删查改方法都有
* 第一个参数:操作的实体类
* 第二个参数:实体类对应数据表的主键
*
* 要使用高级查询必须继承
* org.springframework.data.jpa.repository.JpaSpecificationExecutor<T>接口
*/
public interface TeacherDao extends JpaRepository<Teacher, Integer>, JpaSpecificationExecutor<Teacher> {
}

controler层

package com.lingerqi.springboot03.controller;

import com.lingerqi.springboot03.entity.Teacher;
import com.lingerqi.springboot03.service.TeacherService;
import com.lingerqi.springboot03.utils.PageBean;
import com.lingerqi.springboot03.utils.PageUtil;
import com.lingerqi.springboot03.utils.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; /**
* @author xyls
* @blog name & blog address 027@0030
* @create  2019-12-01 11:57
*/
@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<Teacher> teachers = teacherService.listPager(teacher, pageBean);
modelAndView.addObject("teachers", teachers.getContent());
pageBean.setTotal(teachers.getTotalElements() + "");
modelAndView.addObject("pageCode", PageUtil.createPageCode(pageBean)/*.replaceAll("<","<").replaceAll("&gt:",">")*/);
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 = "/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 = "/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";
}
}

页面层

list.html

<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>书籍列表</title>
<script type="text/javascript" th:src="@{/static/js/xxx.js}"></script>
<link rel="stylesheet" th:href="@{/static/js/bootstrap3/css/bootstrap.min.css}">
<link rel="stylesheet" th:href="@{/static/js/bootstrap3/css/bootstrap-theme.min.css}">
<script type="text/javascript" th:src="@{/static/js/bootstrap3/js/jquery-1.11.2.min.js}"></script>
<script type="text/javascript" th:src="@{/static/js/bootstrap3/js/bootstrap.min.js}"></script>
</head>
<body>
<form th:action="@{/teacher/listPager}" method="post">
书籍名称: <input type="text" name="tname" />
<input type="submit" value="提交"/>
</form>
<a th:href="@{/teacher/toEdit}">新增</a>
<table border="1px" width="600px">
<thead>
<tr>
<td>ID</td>
<td>头像</td>
<td>姓名</td>
<td>性别</td>
<td>简介</td>
<td>操作</td>
</tr>
</thead>
<tbody>
<tr th:each="teacher : ${teachers}">
<td th:text="${teacher.tid}"></td>
<td><img style="width: 60px;height: 60px;" id="imgshow" th:src="${teacher.imagePath}" th:alt="${teacher.tname}"/></td>
<!--<td th:text="${teacher.imagePath}"></td>-->
<td th:text="${teacher.tname}"></td>
<td th:text="${teacher.sex}"></td>
<td th:text="${teacher.description}"></td>
<td>
<a th:href="@{'/teacher/del/'+${teacher.tid}}">删除</a>
<a th:href="@{'/teacher/toEdit?tid='+${teacher.tid}}">修改</a>
</td>
</tr>
</tbody>
</table> <nav>
<ul class="pagination pagination-sm" th:utext="${pageCode}">
</ul> <!--<ul class="pagination pagination-sm">-->
<!--<form id='pageBeanForm' action='http://localhost:8080/springboot/teacher/listPager' method='post'><input type='hidden' name='page'></form>-->
<!--<li><a href='javascript:gotoPage(1)'>首页</a></li>-->
<!--<li class='disabled'><a href='javascript:gotoPage(1)'>上一页</a></li>-->
<!--<li class='active'><a href='#'>1</a></li>-->
<!--<li><a href='javascript:gotoPage(2)'>2</a></li>-->
<!--<li><a href='javascript:gotoPage(2)'>下一页</a></li>-->
<!--<li><a href='javascript:gotoPage(4)'>尾页</a></li>-->
<!--<script type='text/javascript'> function gotoPage(page) { document.getElementById('pageBeanForm').page.value = page; document.getElementById('pageBeanForm').submit(); } function skipPage() { var page = document.getElementById('skipPage').value; if(!page || isNaN(page) || parseInt(page)<1 || parseInt(page)>4){ alert('请输入1~N的数字'); return; } gotoPage(page); }</script>-->
<!--</ul>-->
</nav>
</body>
</html>

 edit.html:

<!DOCTYPE html>
<html lang="en">
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户编辑界面</title> <script type="text/javascript">
function preShow() { }
</script>
</head>
<body> <form th:action="@{${teacher.tid} ? '/teacher/edit' : '/teacher/add'}" method="post" enctype="multipart/form-data">
<input type="hidden" name="tid" th:value="${teacher.tid}" />
<input type="hidden" name="imagePath" th:value="${teacher.imagePath}" />
<img id="imgshow" src="" alt=""/>
<input type="file" name="image" onchange="preShow();"></br>
教员名称: <input type="text" name="tname" th:value="${teacher.tname}" /></br>
教员描述: <input type="text" name="description" th:value="${teacher.description}" /></br>
单选回显
<input type="radio" name="sex"
th:each ="s:${sexArr}"
th:value="${s}"
th:text ="${s}"
th:attr ="checked=${s == teacher.sex}"> <input type="submit" value="提交"/>
</form> </body>
</html>

案例结果截图

 

 

springboot之jpa支持的更多相关文章

  1. springboot之jpa的支持

    1.springboot之jpa支持 2.Springboot+bootstrap界面版之增删改查及图片上传 springboot之jpa支持 导入相关pom依赖 <dependency> ...

  2. springboot对JPA的支持

    springboot之jpa支持 导入相关pom依赖 <dependency> <groupId>org.springframework.boot</groupId> ...

  3. Springboot对JPA的支持及使用

    目的: 1.springboot之jpa支持 2.Springboot+bootstrap界面版之增删改查及图片上传 springboot之jpa支持 导入相关pom依赖 <dependency ...

  4. springboot集成jpa

    spring data jpa简介 spring data jpa是spring基于hibernate及jpa规范封装出来的一套持久层框架.该框架极大的降低了开发者工作量,提升开发效率.提供的关键字可 ...

  5. Springboot+Atomikos+Jpa+Mysql实现JTA分布式事务

    1 前言 之前整理了一个spring+jotm实现的分布式事务实现,但是听说spring3.X后不再支持jotm了,jotm也有好几年没更新了,所以今天整理springboot+Atomikos+jp ...

  6. Springboot+MyBatis+JPA集成

      1.前言 Springboot最近可谓是非常的火,本人也在项目中尝到了甜头.之前一直使用Springboot+JPA,用了一段时间发现JPA不是太灵活,也有可能是我不精通JPA,总之为了多学学Sp ...

  7. 第11章—使用对象关系映射持久化数据—SpringBoot+SpringData+Jpa进行查询修改数据库

    SpringBoot+SpringData+Jpa进行查询修改数据库 JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分.但它又不限于EJB 3.0,你可以在Web应用.甚至桌面应用 ...

  8. 集成Springboot+MyBatis+JPA

    1.前言 Springboot最近可谓是非常的火,本人也在项目中尝到了甜头.之前一直使用Springboot+JPA,用了一段时间发现JPA不是太灵活,也有可能是我不精通JPA,总之为了多学学Spri ...

  9. SpringBoot Data JPA 关联表查询的方法

    SpringBoot Data JPA实现 一对多.多对一关联表查询 开发环境 IDEA 2017.1 Java1.8 SpringBoot 2.0 MySQL 5.X 功能需求 通过关联关系查询商店 ...

随机推荐

  1. 字符串的扩展(ES6)

    文章目录 字符串的扩展 1. 字符的Unicode表示法 2. codePointAt() 3. String.fromCodePoint() 4. 字符串的遍历器接口 5. at()(提案) 6. ...

  2. 用Python抢到回家的车票,so easy!

    “ 盼望着,盼望着,春节的脚步近了,然而,每年到这个时候,最难的,莫过于一张回家的火车票. ​ 据悉,今年春运期间,全国铁路发送旅客人次同比将增长 8.0%.达到 4.4 亿人次. ​ 2020 年铁 ...

  3. 设计模式-单例模式code

    package singeton; import java.security.SecureRandom; /** * @author Zero * @since 2019-08-13. * Descr ...

  4. LICEcap 动画屏幕录制软件

    下载地址    https://licecap.en.softonic.com/ LICEcap捕捉屏幕的区域并保存为gif动画或lcf格式 效果请看下面的链接 https://www.cnblogs ...

  5. JavaScript数组循环

    JavaScript数组循环 一.前言 利用Javascript map(),reduce()和filter()数组方法可以遍历数组.而不是积累起来for循环和嵌套来处理列表和集合中的数据,利用这些方 ...

  6. IDEA的Maven设置阿里镜像

    作为一名.net开发学习java,虽然学习起来没啥难度,但是各种配置实在让人头大. 下面就简单记录下IDEA的Maven设置阿里镜像 进入开发软件的这个设置 点击进入 如图所示 第一个是你安装mave ...

  7. day 26-1 property、绑定与非绑定方法

    property property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值:就是把一个函数属性的访问方式变成像访问数据属性的方式一样. 我们首先来看一个对比效果 例一:在调用 bmi ...

  8. Prism_Event Aggregator(4)

    Event Aggregator Prism库提供了一种事件机制,可以在应用程序中松散耦合的组件之间进行通信.该机制基于事件聚合器服务,允许发布者和订阅者通过事件进行通信,但仍然没有彼此直接引用. 在 ...

  9. Auto入门 之 常用概念

    1.SEMI (Semiconductor Equipment And Materials International)  国际半导体设备与材料产业协会 2.SECS SECS协议是基于RS-232或 ...

  10. hadoop搭建的前期准备

    这个hadoop的搭建是以比赛前的练习为目的的,所以我直接以root用户来搭建hadoop,主要也是方便我自己以后复习用的 需要的软件:vmware15.5,xshell6,xftp6,jdk Lin ...