学习Spring-Data-Jpa(六)---05、spring-data-commons中的repository
1、spring-data-commons项目
spring-data-commons项目是所有spring-data项目的核心,我们来看一下该项目下的repository包中的接口和注解。
2、Repository接口和@RepositoryDefinition注解
当中最重要的就是Repository接口了。它是做数据库操作的最底层的抽象接口、最顶级的父类,打开Repository接口看其源码,发现里面其实什么方法都没有,仅仅起到一个标识作用。捕获要管理的域类型和域类的id类型。用途是保存类型信息,并能够在类路径扫描期间发现继承该接口的接口,帮助我们创建代理类。
@Indexed public interface Repository<T, ID> { }
@Indexed 我们发现在Repository接口上有一个@Indexed 注解,是Spring5提供的注解,用于提升应用启动性能。这个注解单独存在不起作用,要想使其生效的话,要添加spring-context-indexer依赖。在编译时会将@CompoentScan扫描指定package中要生成的bean写在METE-INF/spring.components文件中,当项目启动时,就会读取这个文件,不会再扫描指定的package了,从而提升性能。
我们只要继承Repository接口,并根据它的规则来命名接口方法,就可以进行数据库操作。(与继承Repository接口相等价的就是,在接口上添加@RepositoryDefinition注解)
示例:
/**
* 书籍持久层
* @author caofanqi
* 使用@RepositoryDefinition注解与继承Repository具有相同的效果
*/
//@RepositoryDefinition(domainClass = Book.class,idClass = Long.class)
public interface BookRepository extends Repository<Book,Long>{
/**
* 根据书名查找书籍
* @param bookName 书籍名称
* @return 该书籍名称的书列表
*/
List<Book> findBooksByBookNameContains(String bookName);
}
@Transactional
@Rollback(false) @SpringBootTest class BookRepositoryTest { @Resource private BookRepository bookRepository; @Test void findBooksByBookNameContains() { System.out.println("bookRepository : " + bookRepository.getClass().getName()); List<Book> books = bookRepository.findBooksByBookNameContains("Java"); System.out.println(books); } }
这样就会根据我们传入的参数去like查询符合条件的书籍,生成的sql语句如下:
3、CrudRepository接口与注解@NoRepositoryBean
CrudRepository是Repository接口的子接口,提供了一套通用的CRUD方法。接口上的@NoRepositoryBean注解的意思是,不让Spring生成该类的代理类。
@NoRepositoryBean //不让Spring为该类生成代理类,仅仅提供一套通用的CRUD方法。 public interface CrudRepository<T, ID> extends Repository<T, ID> { /** * 保存方法*/ <S extends T> S save(S entity); /** * 保存*/ <S extends T> Iterable<S> saveAll(Iterable<S> entities); /** * 根据id进行查询*/ Optional<T> findById(ID id); /** * 判断给定id的数据是否存在*/ boolean existsById(ID id); /** * 查询全部,数据量很大的时候,谨慎使用*/ Iterable<T> findAll(); /** * 根据给定ids查询符合条件的数据 */ Iterable<T> findAllById(Iterable<ID> ids); /** * 统计条数*/ long count(); /** * 根据id删除*/ void deleteById(ID id); /** * 删除给定实体*/ void delete(T entity); /** * 删除给定实体*/ void deleteAll(Iterable<? extends T> entities); /** * 删除全部 */ void deleteAll(); }
我们要想使用这些方法,只需自己的Repository继承该接口即可。
4、PagingAndSortingRepository接口
是CrudRepository的子接口,也不会生成代理,只是提供分页和排序的方法。
@NoRepositoryBean public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> { /** * 根据sort去所有对象排序的集合*/ Iterable<T> findAll(Sort sort); /** * 根据pageable进行分页,pageable中可以包含sort*/ Page<T> findAll(Pageable pageable); }
分页相关对象:
Sort查询的排序选项,至少提供一个属性列表来进行排序,不能是null或空,默认是升序ASC;
可以通过Sort.by 来构建Sort对象:
public static Sort by(String... properties) 根据给定的属性列表进行升序排序;
public static Sort by(Direction direction, String... properties) 指定属性和排序方向,Direction.ASC(升序)、Direction.DESC(降序);
public static Sort by(Order... orders)/public static Sort by(List<Order> orders) 根据给定的一组order进行排序。
Order,实现一个排序对,提供方向和属性,为sort提供输入。也就是说,可以针对每一个属性设置不同的升序或降序。
可以通过一下方式来构建Order对象:
public static Order by(String property) ,指定属性返回order对象,默认使用升序。
public static Order asc(String property),返回指定属性升序的order对象。
public static Order desc(String property),返回指定属性降序的order对象。
Pageable分页信息的抽象接口,实现类是PageRequest;
可以通过一下方式来构建Pageable对象:
public static PageRequest of(int page, int size),创建一个未排序的PageRequest,page从0开始;
public static PageRequest of(int page, int size, Direction direction, String... properties),创建一个根据给定方向和属性排序的分页对象。
public static PageRequest of(int page, int size, Sort sort),创建一个根据sort进行排序的分页对象。
Page,封装分页结果信息,可以通过如下方法获取分页信息。
page.getContent() ,分页查询结果列表;
page.getNumberOfElements(),当前分页结果列表中的元素个数;
page.getTotalElements(),当前条件下总条数;
page.getTotalPages(),总页数;
page.getNumber(),我们自己传的page;
page.getSize(),我们自己传入的size。
代码示例:
@Test void testPagingAndSortingRepository(){ Sort.Order id = Sort.Order.by("id"); Sort.Order bookName = Sort.Order.desc("bookName"); Sort sort = Sort.by(id,bookName); Pageable pageable = PageRequest.of(2,2, sort); Page<Book> page = bookRepository.findAll(pageable); System.out.println("分页查询结果列表:" + page.getContent()); System.out.println("当前分页结果列表中的元素个数:" + page.getNumberOfElements()); System.out.println("当前条件下总条数:" + page.getTotalElements()); System.out.println("总页数:" +page.getTotalPages()); System.out.println("我们自己传的page:" +page.getNumber()); System.out.println("我们自己传入的size:" +page.getSize()); }
源码地址:https://github.com/caofanqi/study-spring-data-jpa
原文地址:https://www.cnblogs.com/caofanqi/p/11831362.html
- 运用Kubernetes进行分布式负载测试
- Spring Cloud(五)断路器监控(Hystrix Dashboard)
- 微信技术团队的又一力作,WCDB 简单易用的数据库框架
- Redis特性和应用场景
- Spring Cloud(四)服务提供者 Eureka + 服务消费者 Feign
- 智能下拉刷新框架-SmartRefreshLayout
- Spring Cloud(三)服务提供者 Eureka + 服务消费者(rest + Ribbon)
- Spring Cloud(二)Consul 服务治理实现
- Spring Cloud(一)服务的注册与发现(Eureka)
- Shard 分片集群
- 面试官最爱的volatile关键字
- 玩转 WebView ,突破系统限制,让缓存更简单,更灵活
- Mycat 读写分离 数据库分库分表 中间件 安装部署,及简单使用
- 50道Java线程题
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- ESlint + stylelint + VSCode自动格式化代码(2020)
- PAT (Basic Level) Practice (中文)1032 挖掘机技术哪家强 (20 分)
- PAT (Advanced Level) Practice 1023 Have Fun with Numbers (20 分)
- PAT (Basic Level) Practice (中文)1034 有理数四则运算 (20 分)
- 移动端开发的几点建议
- 数据结构题集(严书)图 常见习题代码
- PAT (Basic Level) Practice (中文)1036 跟奥巴马一起编程 (15 分)
- PAT (Advanced Level) Practice 1024 Palindromic Number (25 分)
- Flink 连接 hive 解决 java.net.UnknownHostException
- PAT (Advanced Level) Practice 1147 Heaps (30 分)
- Java自动化测试(app自动化环境搭建 31)
- PAT (Basic Level) Practice (中文)1038 统计同成绩学生 (20 分)
- 数据结构题集(严书)串 常见习题代码
- PAT (Basic Level) Practice (中文)1040 有几个PAT (25 分)
- 201909-4ccf计算机职业资格认证考试 第四题 推荐系统