先来张效果图吧

一、pom.xml 导入依赖包

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><!--jpa依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.9</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--devtools热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional><scope>true</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>
</dependencies>

二、application.yml 配置

spring:datasource:url: jdbc:mysql://localhost:3306/db_itboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driverjpa:hibernate:ddl-auto: updateshow-sql: truethymeleaf:prefix: classpath:/templates/suffix: .htmlmode: HTMLencoding: UTF-8servlet:content-type: text/htmlcache: falseresources:chain:strategy:content:enabled: falsepaths: /**mvc:static-path-pattern: /static/**
server:port: 8081

三、User 实体类

@Entity                     //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "user")       //@Table指定和哪个表对应,如果省略该注解默认表名就是user
public class User {@Id      //这是一个主键@GeneratedValue(strategy = GenerationType.IDENTITY)   //自增主键@Column(name = "id", unique = true, length = 11)      //unique = true 是指这个字段的值在这张表里不能重复,所有记录值都要唯一,就像主键那样;private Integer id;@Column(nullable=false,name = "name")  //省略默认列名就是属性名、nullable=false是这个字段在保存时必需有值,不能还是null值就调用save去保存入库;private String name;@Column(nullable=true,name = "sex")   //nullable默认可以为空,如果改为false,参数没有值的时候就save会报错private Integer sex;private String position;...此处省略get、set方法//无参数的构造器public User() {}//添加信息:有参数的构造器public User(String name){this.name = name;}//更新信息:有参数的构造器public User(Integer id,String name){this.id = id;this.name = name;}
}

四、控制器、实现层核心接口编写

包结构如下:

UserDao.java

//继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法
public interface UserDao extends JpaRepository<User,Integer> {}

五、测试代码接口

UserController.java

   @Autowiredprivate UserDao userDao;/**** 根据id查询用户信息* @param id* @return*/@GetMapping(value = "getById/{id}")@ResponseBodypublic User getUser(@PathVariable("id") Integer id){Optional<User> user = userDao.findById(id);  //根据ID查询return user.ofNullable(user).map(user1->user.get()).orElse(null);}/**** 查询所有用户List集合* @return*/@GetMapping(value = "list")@ResponseBodypublic List<User> findAll(){return userDao.findAll();}/*** 添加用户信息* @return*/@PostMapping(value = "save")@ResponseBodypublic Map<String,Object> saveUser(){Map<String,Object> map = new HashMap<>();User user = userDao.save(new User("DT开发者002"));if (!StringUtils.isEmpty(user)){map.put("code",2000);map.put("message","添加成功");map.put("data",user);}else {map.put("code",20001);map.put("message","添加失败");}return map;}/**** 根据id修改用户信息* @return*/@PostMapping(value = "update/{id}")@ResponseBodypublic Map<String,Object> updateUserById(@PathVariable Integer id){Map<String,Object> map = new HashMap<>();//1、根据id查询用户信息Optional<User> user = userDao.findById(id);if(user.isPresent()){//2、调用接口进行更新User update = userDao.save(new User(user.get().getId(), "DT开发者0022"));//3、判断是否成功if(!StringUtils.isEmpty(update)){map.put("code",2000);map.put("message","修改成功");map.put("data",user);}else {map.put("code",2001);map.put("message","事务回滚");map.put("data",user);}System.out.println("ID==="+user.get().getId());}else {map.put("code",2001);map.put("message","修改失败");map.put("data",user);}return map;}/***根据主键id删除用户信息* @return*/@DeleteMapping(value = "remove/{id}")@ResponseBodypublic Map<String,Object> removeUserById(@PathVariable Integer id){Map<String,Object> map = new HashMap<>();userDao.deleteById(id);map.put("code",2000);map.put("message","删除成功");map.put("data",id);return map;}

自定义CRUD、UserController.java

/*** 自定义:根据用户名查询用户信息* @param name* @return*/@GetMapping(value = "findCustomByName")@ResponseBodypublic User findCustomByName(@PathParam("name") String name){return userService.findCustomByName(name);}/*** 自定义:根据用户名查询用户信息 (模糊查询)* @param name* @return*/@GetMapping(value = "findVagueByName")@ResponseBodypublic List<User> findVagueByName(@PathParam("name") String name){return userService.findVagueByName(name);}/*** 自定义:根据用户名id更新用户信息* @param user* @return*/@PostMapping(value = "updateCustomByById")@ResponseBodypublic Map<String,Object> updateCustomByById(User user){return userService.updateCustomByById(user);}/*** 自定义:根据用户名id删除用户信息* @param id* @return*/@DeleteMapping(value = "removeCustomByById/{id}")@ResponseBodypublic Map<String,Object> removeCustomByById(@PathVariable Integer id){return userService.removeCustomByById(id);}

UserServiceImpl .java

@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserDao userDao;/*** 自定义:根据用户名查询用户信息* @param name* @return*/@Overridepublic User findCustomByName(String name) {if(StringUtils.isNotBlank(name)){return userDao.findCustomByName(name);}else {return null;}}/*** 自定义:根据用户名查询用户信息 (模糊查询)* @param name* @return*/@Overridepublic List<User> findVagueByName(String name) {if(StringUtils.isNotBlank(name)){return userDao.findVagueByName(name);}else {return null;}}/*** 自定义:根据用户名id更新用户信息* @param user* @return*/@Override@Transactional  //必须加@Transactional,来代表这是一个事务级别的操作。jpa要求,'没有事务支持,不能执行更新和删除操作'public Map<String, Object> updateCustomByById(User user) {Map<String,Object> map = new HashMap<>();if(user !=null){//注意:1、返回值只有int和void 2、入参绝对不能定义成 User对象,JPA不支持,只有查询可以使用SPEL表达式int user1 = userDao.updateCustomByById(user.getId(),user.getName());if(user1 > 0){map.put("code","2000");map.put("message","修改成功");map.put("data",user1);}else {map.put("code","2001");map.put("message","修改失败");}}else {map.put("code","2001");map.put("message","参数不能为空");}return map;}/*** 自定义:根据用户名id删除用户信息* @param id* @return*/@Override@Transactionalpublic Map<String, Object> removeCustomByById(Integer id) {Map<String,Object> map = new HashMap<>();int count = userDao.removeCustomByById(id);if(count > 0){map.put("code","2000");map.put("message","删除成功");map.put("data",id);}else {map.put("code","2001");map.put("message","删除失败");}return map;}
}

UserDao.java

public interface UserDao extends JpaRepository<User,Integer> {/*** 自定义:根据用户名查询用户信息* @param name* @return*/@Query(value = "select id,name from user where name = :name",nativeQuery = true)User findCustomByName(@Param("name") String name);/*** 自定义:根据用户名查询用户信息 (模糊查询)* @param name* @return*///@Query(value = "select id,name from user where name like %:name%",nativeQuery = true) //第一种写法@Query(value = "select t.id,t.name from user t where t.name like %?1%",nativeQuery = true)  //第二种写法 1表示占位符,从第一个参数开始List<User> findVagueByName(String name);/*** 自定义:根据用户名id更新用户信息* @param id* @param name* @return*/@Modifying@Query(value = "update user set name = :name where id = :id",nativeQuery = true)int updateCustomByById(Integer id,String name);  //入参绝对不能定义成 User对象,JPA不支持,只有查询可以使用SPEL表达式/*** 自定义:根据用户名id删除用户信息* 执行完modifying query, EntityManager可能会包含过时的数据,因为EntityManager不会自动清除实体。* 只有添加clearAutomatically属性,EntityManager才会自动清除实体对象。* @param id* @return*/@Modifying(clearAutomatically = true)@Query(value = "delete from user where id = :id",nativeQuery = true)int removeCustomByById(Integer id);
}

六、JPA + BootStrap 无条件查询分页

UserController.java

/*** 分页(无条件查询)* @param modelMap* @param pageNumber* @param pageSize* @return*/
@GetMapping(value = "listUsers")
public String listUsers(ModelMap modelMap,@RequestParam(value = "pageNumber",defaultValue = "0") Integer pageNumber,@RequestParam(value = "pageSize",defaultValue = "5") Integer pageSize){//设置分页Pageable pageable = PageRequest.of(pageNumber,pageSize, Sort.Direction.DESC, "id");//进行查询Page<User> userPage = userDao.findAll(pageable);modelMap.addAttribute("data",userPage);return "index";
}

index.html

<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"xmlns:th="http://www.thymeleaf.org"xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"layout:decorator="page">
<head><meta charset="UTF-8"><title>分页</title><script src="https://cdn.bootcdn.net/ajax/libs/jquery/2.2.4/jquery.min.js"></script><!-- 最新的 Bootstrap 核心 JavaScript 文件 --><script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script><!-- 最新版本的 Bootstrap 核心 CSS 文件 --><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" ><style>.active{background: #49af4f !important;color: #fff !important;}</style>
</head>
<body style="padding: 50px;">
<div class="panel panel-success"><div class="panel-heading"><h2 class="panel-title" style="text-align: center;font-weight: bold;">无条件查询 | 分页</h2></div><div class="panel-body"><!--bootstrap表格--><table class="table table-hover"><thead><tr><th>ID</th><th>用户</th><th>性别</th><th>职位</th></tr></thead><tbody><tr th:each="user : ${data}"><td th:text="${user.id}"></td><td th:text="${user.name}"></td><td th:text="${user.sex == 1 ? '女':'男'}"></td><td th:text="${user.position}">2</td></tr></tbody></table><!--bootstrap自定义分页--><ul class="pager"><li th:if="${data.hasPrevious()}"><a th:href="@{/user/listUsers(pageNumber=0)}">首页</a></li><li th:if="${data.hasPrevious()}"><a th:href="@{/user/listUsers(pageNumber=${data.number}-1)}">上一页</a></li><!--总页数大于等于0并且小于等于5--><div th:if="${(data.totalPages le 5) and (data.totalPages gt 0)}" th:remove="tag"><!--根据一个数字在页面循环生成固定的标签--><div th:each="pg : ${#numbers.sequence(0, data.totalPages - 1)}" th:remove="tag"><!--如果循环的数等于当前页--><span th:if="${pg eq data.getNumber()}" th:remove="tag"><li><span class="active" th:text="${pg+1}"></span></li></span><!--如果循环的数不等于当前页--><span th:unless="${pg eq data.getNumber()}" th:remove="tag"><li><a th:href="@{/user/listUsers(pageNumber=${pg})}" th:text="${pg+1}"></a></li></span></div></div><!-- 总页数大于5时、中间留五个分页条 --><div th:if="${data.totalPages gt 5}" th:remove="tag"><li th:if="${data.getNumber()-2 ge 0}"><a th:href="@{/user/listUsers(pageNumber=${data.getNumber()}-2)}" th:text="${data.getNumber()-1}"></a></li><li th:if="${data.getNumber()-1 ge 0}"><a th:href="@{/user/listUsers(pageNumber=${data.getNumber()}-1)}" th:text="${data.getNumber()}"></a></li><li><span class="active" th:text="${data.getNumber()+1}"></span></li><li th:if="${data.getNumber()+1 lt data.totalPages}"><a th:href="@{/user/listUsers(pageNumber=${data.getNumber()}+1)}" th:text="${data.getNumber()+2}"></a></li><li th:if="${data.getNumber()+2 lt data.totalPages}"><a th:href="@{/user/listUsers(pageNumber=${data.getNumber()}+2)}" th:text="${data.getNumber()+3}"></a></li></div><li  th:if="${data.hasNext()}"><a th:href="@{/user/listUsers(pageNumber=${data.getNumber()}+1)}">下一页</a></li><li><a th:href="@{/user/listUsers(pageNumber=${data.totalPages}-1)}">尾页</a></li><li><span th:utext="'共'+${data.totalPages}+'页 / 总'+${data.totalElements}+'条'"></span></li></ul></div>
</div></body>
</html>

效果:

七、JPA + BootStrap 带条件查询分页

UserController.java

/*** 分页(带条件查询)* @param modelMap* @param pageNumber* @param pageSize* @param userQuery* @return*/
@GetMapping(value = "listUserQuery")
public String listUserQuery(ModelMap modelMap,@RequestParam(value = "pageNumber",defaultValue = "0") Integer pageNumber,@RequestParam(value = "pageSize",defaultValue = "5") Integer pageSize,UserQuery userQuery){//设置分页Pageable pageable = PageRequest.of(pageNumber,pageSize,Sort.Direction.ASC, "id");//进行查询Page<User> userPage = userService.findUserQuery(pageable,userQuery);modelMap.addAttribute("data",userPage);modelMap.addAttribute("name",userQuery.getName());modelMap.addAttribute("sex",userQuery.getSex());modelMap.addAttribute("position",userQuery.getPosition());return "home";
}

UserQuery.java

//数据查询对象,各层接收上层的查询请求。注意超过 2 个参数的查询封装,禁止使用 Map 类来传输
public class UserQuery {private String name;private Integer sex;private String position;...此处省略get、set
}

UserServiceImpl.java

/*** 分页(带条件查询)* @param pageable* @param userQuery* @return*/
@Override
public Page<User> findUserQuery(Pageable pageable, UserQuery userQuery) {Page<User> userPage = userDao.findAll(new Specification<User>(){@Overridepublic Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {List<Predicate> list = new ArrayList<>();if (StringUtils.isNotBlank(userQuery.getName())){list.add(criteriaBuilder.equal(root.get("name").as(String.class), userQuery.getName()));}if(userQuery.getSex() != null){list.add(criteriaBuilder.equal(root.get("sex").as(Integer.class), userQuery.getSex()));}if (StringUtils.isNotBlank(userQuery.getPosition())){list.add(criteriaBuilder.equal(root.get("position").as(String.class), userQuery.getPosition()));}Predicate[] p = new Predicate[list.size()];return criteriaBuilder.and(list.toArray(p));}},pageable);return userPage;
}

效果1

效果2

八、demo地址、可下载

完整代码已同步至Github,可下载 Github地址 、如果有问题可随时提问,觉得不错,欢迎点赞评论。

最新SpringBoot2.0X整合SpringData JPA实战完整篇相关推荐

  1. SpringBoot2零基础到项目实战-基础篇

    springboot2零基础到项目实战-基础篇 课程内容说明 课程单元 学习目标 基础篇 能够创建SpringBoot工程 基于SpringBoot实现ssm/ssmp整合 应用篇 能够掌握Sprin ...

  2. 最新C语言/C++语言培训项目实战(完整)

    C语言/C++语言培训视频教程 C语言/C++语言培训视频教程 C语言/C++语言培训视频教程 下载地址:百度网盘

  3. 解决SpringBoot整合SpringData JPA的PagingAndSortingRepository的Sort排序时遇到的错误:has protected access in ‘org.sp

    问题: 原因: pringboot2.2.1(含)以上的版本Sort已经不能再实例化了,构造方法已经是私有的了! 解决方法: 我们可以改用Sort.by获得Sort对象

  4. spring boot 整合多数据源JDBC、多数据源mybatis、多数据源springdata jpa

    目录 代码地址:(spring-boot github地址) 1.springboot整合JDBC 2.springboot整合mybatis 3.springboot整合springdata jpa ...

  5. SpringBoot简介、SpringBoot 入门程序搭建、与JDBC、Druid、Mybatis和SpringData JPA的整合

    一.SpringBoot 简介: spring boot并不是一个全新的框架,它不是spring解决方案的一个替代品,而是spring的一个封装.所以,你以前可以用spring做的事情,现在用spri ...

  6. 黑马 SpringData JPA笔记

    课程链接:https://www.bilibili.com/video/BV1Y4411W7Rx?from=search&seid=415951199875837982 第一 orm思想 ​ ...

  7. SpringBoot2.0整合多数据源拆分

    前言 本文环境承接springboot2.0整合使用mybatis(数据访问篇) 一.什么是多数据源 公司分为两个数据库,一个数据库专门存放共同配置文件,一个数据库垂直业务数据库.垂直根据业务划分具体 ...

  8. SpringBoot2.x整合Redis实战 4节课

    1.分布式缓存Redis介绍      简介:讲解为什么要用缓存和介绍什么是Redis,新手练习工具 1.redis官网 https://redis.io/download           2.新 ...

  9. SpringBoot2.x整合redis实战讲解

    SpringBoot2.x整合redis实战讲解 简介:使用springboot-starter整合reids实战 1.官网:https://docs.spring.io/spring-boot/do ...

最新文章

  1. Java学习笔记13
  2. leetcode874
  3. 国内主流.NET CMS系统整理
  4. Spring boot(3):Spring boot中Redis 的使用
  5. linux 自动安装 yum,LINUX6安装YUM仓库和实现开机自动挂载
  6. 【三维深度学习】多视角场景点云重建模型PointMVS
  7. Round 2—算法的复杂度
  8. 宝塔面板 服务器状态,宝塔面板中重启腾讯云服务器后无法登录宝塔面板怎么办?...
  9. linux php muma,php实现Linux服务器木马排查及加固功能
  10. SurfacePro6解决亮度自动调节问题
  11. Enriched Feature Guided Refinement Network for Object Detection(面向目标检测的丰富特征引导细化网络)
  12. window.btoa与window.atob
  13. 2021江苏省南通市高考成绩查询时间,2021年江苏南通高考时间:6月7日至9日
  14. Linux下打包命令tar
  15. 操作系统概念 第六章 同步
  16. 操作系统可以控制和管理计算机的硬件资源,Windows操作系统是用来控制和管理计算机所有硬件和软件的...
  17. nth-child选择器
  18. 中国传统节日网页html,【学习在线】中国传统节日的形成和发展
  19. 一切还算顺利,远方的你还好吗?
  20. Matlab exercise04

热门文章

  1. 信息学奥赛一本通(2052:【例3.2】范围判断)
  2. 小b删列(51Nod-2523)
  3. 小b和排序(51Nod-2484)
  4. 求递推序列的第N项(51Nod-1126)
  5. 级数求和(洛谷-P1035)
  6. 10 PP配置-生产主数据-工作中心相关-定义工作中心公式
  7. re匹配字符串的中间一段_爬虫利器之 re 模块
  8. cassandra可视化工具_耗时1个月整理!160种Python标准库、第三方库和外部工具都有了...
  9. 基于android新闻阅读器,Readian News是一款基于Android和网络的新闻阅读器,可让您掌控一切...
  10. 计算机等级考试机试试题,计算机等级考试二级VFP机试试题18