在Spring中有Repository的概念,repository原意指的是仓库,即数据仓库的意思。Repository居于业务层和数据层之间,将两者隔离开来,在它的内部封装了数据查询和存储的逻辑。这样设计的好处有两个:

  1. 降低层级之间的耦合:更换、升级ORM引擎(Hibernate)并不会影响业务逻辑
  2. 提高测试效率:如果在测试时能用Mock数据对象代替实际的数据库操作,运行速度会快很多

Repository和DAO的区别

DAO是传统MVC中Model的关键角色,全称是Data Access Object。DAO直接负责数据库的存取工作,乍一看两者非常类似,但从架构设计上讲两者有着本质的区别:

Repository蕴含着真正的OO概念,即一个数据仓库角色,负责所有对象的持久化管理。DAO则没有摆脱数据的影子,仍然停留在数据操作的层面上。Repository是相对对象而言,DAO则是相对数据库而言,虽然可能是同一个东西 ,但侧重点完全不同。

三种Repository介绍

在Spring和Spring Data JPA中,有三种Repository接口方便开发者直接操作数据仓库。
它们之间的关系如下:

CrudRepository

  <S extends T> S save(S entity);<S extends T> Iterable<S> save(Iterable<S> entities);T findOne(ID id);boolean exists(ID id);Iterable<T> findAll();Iterable<T> findAll(Iterable<ID> ids);long count();void delete(ID id);void delete(T entity);void delete(Iterable<? extends T> entities);void deleteAll();

CrudRepository类如其名,可以胜任最基本的CRUD操作。其中save方法在可两用,参数中不存在主键时执行insert操作,存在主键则执行update操作,相当于是一个upsert操作。

PagingAndSortingRepository

  Iterable<T> findAll(Sort sort);Page<T> findAll(Pageable pageable);

PagingAndSortingRepository继承了CrudRepository接口,增加了分页和排序的方法。

分页

要达到分页的目的,需要传入一个Pageble接口对象,controller中代码如下:

@GetMapping("")
public ResponseEntity<?> getList(@RequestParam(value="page", defaultValue="0") int page,@RequestParam(value="size", defaultValue="10") int size ) {Pageable pageable = new PageRequest(page, size);return new ResponseEntity<Object>(userService.getUserList(pageable), HttpStatus.OK);
}

<说明>

  1. @RequestParam注解,表明了需要传入URL参数page和size,用于计算分页的offset值。
  2. PageRequest是Pageable的实现类,传入初始化page和size即可生成分页参数。

在Service中,仅需加入pageable对象即可达到分页的效果。代码如下:

public Iterable<User> getUserList(Pageable pageable) {return userRepo.findAll(pageable);
}

此时在POSTMAN中输入访问地址:'127.0.0.1:8080/user?page=0&size=5',得到以下结果:

{"content": [{ "id": 12, "name": "F1" },{ "id": 13, "name": "A" },{ "id": 14, "name": "B" },{ "id": 15, "name": "C" },{ "id": 16, "name": "D" }],"last": false,"totalPages": 3,"totalElements": 11,"size": 5,"number": 0,"numberOfElements": 5,"first": true,"sort": null
}

从结果可以看出,不仅在content中有查询的数组信息,还包括totalPages等分页信息。

排序

与分页类似,要达到排序的目录,仅需要传入Sort对象即可,controller中代码如下:

@GetMapping("")
public ResponseEntity<?> getList(@RequestParam(value="page", defaultValue="0") int page,@RequestParam(value="size", defaultValue="10") int size ) {Sort sort = new Sort(Sort.Direction.DESC, "name");
// Pageable pageable = new PageRequest(page, size);return new ResponseEntity<Object>(userService.getUserList(sort), HttpStatus.OK);
}

同样的,在Service中需要新增接口,如下:

public Iterable<User> getUserList(Sort sort) {return userRepo.findAll(sort);
}

此时在POSTMAN中输入访问地址:'127.0.0.1:8080/user',得到以下结果:

[{ "id": 22, "name": "K" },{ "id": 21, "name": "J" },{ "id": 20, "name": "I" },{ "id": 19, "name": "H" },{ "id": 18, "name": "G" },{ "id": 12, "name": "F1" },{ "id": 17, "name": "E" },{ "id": 16, "name": "D" },{ "id": 15, "name": "C" },{ "id": 14, "name": "B" },{ "id": 13, "name": "A" }
]

得到的正是name属性按DESC排序的结果列表

排序后分页

PagingAndSortingRepository提供了分页和排序的接口,那如果两者都要做,该怎么写呢?
其实在Pageable中,还可以传入Sort属性,这样就可以在分页中达到排序的目的。

同样的,把Controller代码稍稍调整一下:

@GetMapping("")
public ResponseEntity<?> getList(@RequestParam(value="page", defaultValue="0") int page,@RequestParam(value="size", defaultValue="10") int size ) {Sort sort = new Sort(Sort.Direction.DESC, "name");Pageable pageable = new PageRequest(page, size, sort);return new ResponseEntity<Object>(userService.getUserList(pageable), HttpStatus.OK);
}

<说明>

  1. Sort对象作为PageRequest的第三个参数传入。

这样调整以后,UserService这边就不在需要入参为Sort的getUserList接口了。

此时在POSTMAN中输入访问地址:'127.0.0.1:8080/user?page=0&size=5',得到以下结果:

{"content":[{"id":22,"name":"K"},{"id":21,"name":"J"},{"id":20,"name":"I"},{"id":19,"name":"H"},{"id":18,"name":"G"}],"totalPages":3,"totalElements":11,"last":false,"size":5,"number":0,"first":true,"numberOfElements":5,"sort":[{"direction":"DESC","property":"name","ignoreCase":false,"nullHandling":"NATIVE","ascending":false,"descending":true}]
}

sort显然不应该出现在应答结果中,以后的代码会将它去除出去。

JpaRepository

  List<T> findAll();List<T> findAll(Sort sort);List<T> findAll(Iterable<ID> ids);<S extends T> List<S> save(Iterable<S> entities);void flush();<S extends T> S saveAndFlush(S entity);void deleteInBatch(Iterable<T> entities);void deleteAllInBatch();T getOne(ID id);@Override<S extends T> List<S> findAll(Example<S> example);@Override<S extends T> List<S> findAll(Example<S> example, Sort sort);

JpaRepository则进一步在PagingAndSorting的基础上,扩展了部分功能:

  1. 查询列表(返回值为List)
  2. 批量删除
  3. 强制同步
  4. Example查询

这部分将在以后的内容中不断细化。

Spring Boot学习笔记(三)Repository的使用相关推荐

  1. Spring Boot学习笔记-进阶(3)

    文章目录 Spring Boot学习笔记-进阶(3) 一.Spring Boot与缓存 二.Spring Boot与消息 三.Spring Boot与检索 四.Spring Boot与任务 异步任务 ...

  2. Spring Boot学习笔记-基础(2)

    Spring Boot学习笔记-基础(2) Spring Boot 优点: – 快速创建独立运行的Spring项目以及与主流框架集成 – 使用嵌入式的Servlet容器,应用无需打成WAR包 – st ...

  3. Spring Boot学习笔记(1)

    文章目录 Spring Boot学习笔记(1) Spring Boot 整合 JSP Spring Boot HTML Thymeleaf 常用语法 Spring Boot 数据校验 Spring B ...

  4. Spring Boot学习笔记-实践建言

    2019独角兽企业重金招聘Python工程师标准>>> 本文延续<Spring Boot学习笔记-快速示例>,从开发指南中摘出一些实践经验可供参考.这也是笔者看到的眼前一 ...

  5. Vue + Spring Boot 学习笔记01:实现用户登录功能

    Vue + Spring Boot 学习笔记01:实现用户登录功能 一.创建后端Spring Boot项目Book Management 二.创建前端Vue项目bm-vue 三.修改后端项目Book ...

  6. Spring框架学习笔记(三)(AOP,事务管理)

    Spring框架学习笔记(三) 九.AOP 9.1 AOP的注解配置 (1) 新建计算器核心功能(模拟:不能在改动核心代码) (2) 建立一个普通的Java类写增强代码(面向切面编程),使用Sprin ...

  7. 超赞:不愧是阿里内部“Spring boot学习笔记”从头到尾,全是精华

    spring boot为何会出现? 随着动态语言的流行(Ruby.Groovy. Scala. Node.js),Java 的开发显得格外的笨重:繁多的配置.低下的开发效率.复杂的部署流程以及第三方技 ...

  8. Vue + Spring Boot 学习笔记02:引入数据库实现用户登录功能

    Vue + Spring Boot 学习笔记02:引入数据库实现用户登录功能 在学习笔记01里,我们利用跨域打通了前端的Vue与后端的Spring Boot,实现了用户登录功能,但是后台的登录控制器在 ...

  9. Spring Boot 学习笔记(三)Spring boot 中的SSM

    Spring boot 下的 Spring mvc @Controller:即为Spring mvc的注解,处理http请求: @RestController:Spring4后新增注解,是@Contr ...

  10. Spring Boot学习笔记 [完结]

    Spring Boot 文章目录 Spring Boot 1.微服务 1.1 什么是微服务? 1.2 单体应用架构 1.3 微服务架构 2. 第一个SpringBoot程序 2.1.原理 2.2 原理 ...

最新文章

  1. sql优化之:深入浅出理解索引(系列二)(讲解非常透彻)
  2. golang并发和并行
  3. SpringMVC的数据转换、格式化和数据校验
  4. centos7自带python版本_CentOS7升级python2.7.5到python3.7以上版本
  5. Leetcode 动态规划 Trapping Rain Water
  6. 20210501:字符串与哈希表力扣专题学习记录
  7. ckati与ninja构建demo
  8. 【BZOJ1500】[NOI2005]维修数列
  9. 最简单的方法实现小程序按钮跳转到指定界面
  10. python qt build environment
  11. wpf 写个简单的控件吧
  12. golang日志收集方案之ELK
  13. java基础之测试类
  14. 基于ZFS+SAS的Tier2/backup存储系统解决方案
  15. CSV导入到clickhouse
  16. 怎么用dos系统进入服务器,怎么进入dos_如何进入dos的方法(图文介绍)
  17. java8 stream 原理_【修炼内功】[Java8] Stream是怎么工作的
  18. 初中计算机卡片的制作教案,其他教案-贺卡的设计与制作
  19. 好看的colormap颜色
  20. 三角脉冲信号的表达式_三角形脉冲信号怎么用斜变信号表示?为什么当t=τ时,图上的线是连下来的...

热门文章

  1. JavaScript最牛加密,域名绑定配置规则讲解,域名相关知识科普
  2. win7 找不到 计算机策略组,win7系统打开组策略提示gpedit.msc找不到的解决方法
  3. sqlServer 开启CDC
  4. 全国电信及网通 DNS 列表
  5. SEO学习笔记六(SEO实战密码读书笔记)
  6. python进度条 装饰器_2种方式解决Python执行卡顿问题
  7. 模型理论5_经济金融学院开展“动态随机一般均衡模型理论及应用”主题讲座(五)...
  8. CSS 二级导航的消失——在鼠标离开一级导航后、触碰二级导航前消失的问题解决方案
  9. 论文阅读 [TPAMI-2022] U2Fusion: A Unified Unsupervised Image Fusion Network
  10. 怎样用mysql做留言板_PHP+Mysql 实现留言板