Spring Data JPA 自定义Repository接口与子接口
上篇文章介绍了 Repository接口的使用(Spring Data JPA介绍与Spring的整合),接下来重点掌握 Repository的CrudRepository子接口下的子接口。
在dao层的接口中定义方法,查询的方法:find或get或read开头,遵守一些规定:
Keyword | Sample | JPQL snippet |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Repository的子接口的使用时只需要 dao层继承该接口即可。
一、CrudRepository接口
CrudRepository接口还有一个PagingAndSortingRepository子接口:
CrudRepository 主要提供CRUD功能。
PagingAndSortingRepository 提供进行分页和排序记录的方法。
1、CrudRepository 主要提供CRUD功能。
CrudRepository接口的方法:很好理解就不解释了,下面使用几个即可快速掌握。
public interface UserDao extends CrudRepository<User, Long> {}
测试:
@Testpublic void test() {User user = new User();user.setUsername("赵云");user.setPassword("123456");user.setAge(18);user.setCreatetime(LocalDateTime.now());User save = userDao.save(user);System.out.println(save.getId()); // 4}@Testpublic void testList() {List<User> list = new ArrayList<>();for (int i = 0; i < 20; i++) {User user = new User();user.setUsername("赵云" + i);user.setPassword("123456");user.setAge(18 + i);user.setCreatetime(LocalDateTime.now());list.add(user);}List<User> saveAll = (List<User>) userDao.saveAll(list);// id 不存在,会报错:org.springframework.dao.EmptyResultDataAccessException: // No class cn.jq.springdatajpademo.model.User entity with id 2 exists!userDao.deleteById(2L);}
2、PagingAndSortingRepository 提供进行分页和排序记录的方法。
Pageable是一个接口,这里使用 PageRequest类
测试:
@Testpublic void test() {Sort.Order order1 = new Sort.Order(Sort.Direction.ASC, "age");Sort.Order order2 = new Sort.Order(Sort.Direction.DESC, "id");Sort sort = Sort.by(order1, order2);// 查询第3页Pageable pageRequest = PageRequest.of(2, 10, sort);Page<User> page = userDao.findAll(pageRequest);List<User> userList = page.getContent(); // 数据int number = page.getNumber(); // 当前页码,注意默认从0开始int totalPages = page.getTotalPages(); // 总页码数int numberOfElements = page.getNumberOfElements(); // 当前页码记录数long totalElements = page.getTotalElements(); // 总的数量int size = page.getSize(); // 每页的记录数System.out.println("userList = " + userList);System.out.println("number = " + number + 1);System.out.println("totalPages = " + totalPages);System.out.println("numberOfElements = " + numberOfElements);System.out.println("totalElements = " + totalElements);System.out.println("size = " + size);}
3、JpaRepository接口是项目开发时使用最多的接口。
JpaRepository继承自PagingAndSortingRepository接口,JpaRepository基于JPA的Repository接口,极大减少了JPA作为数据访问的代码,JpaRepository是实现Spring Data JPA技术访问数据库的关键接口。
public interface UserDao extends JpaRepository<User, Long> {}
测试:
@Testpublic void test() {User user = new User();user.setUsername("赵云胜多负少");user.setPassword("123456");user.setAge(18);user.setCreatetime(LocalDateTime.now());
// 主键存在update,不存在就insert操作
// user.setId(4L);User saveAndFlush = userDao.saveAndFlush(user);System.out.println(saveAndFlush.getId());}
二、JpaSpecificationExecutor接口
JpaSpecificationExecutor 是 JPA 2.0 提供的 Criteria API 的使用封装,可以用于动态生成 Query 来满足我们业务中的各种复杂场景。
Spring Data JPA 为我们提供了 JpaSpecificationExecutor 接口。该接口通过Specification来定义查询条件,使用Specification的要点就是CriteriaBuilder,通过这个对象来创建条件,之后返回一个Predicate对象。这个对象中就有了相应的查询需求,我们同样可以定义多个Specification,之后通过Specifications对象将其连接起来。
通过源码看出:SimpleJpaRepository类是JpaSpecificationExecutor接口的默认实现。
测试:
public interface UserDao extends JpaRepository<User, Long>, JpaSpecificationExecutor {}
@Testpublic void test() {Specification<User> s1 = new Specification<User>() {/*** @param *root: 代表查询的实体类.* @param criteriaQuery: 可以从中可到 Root 对象, 即告知 JPA Criteria 查询要查询哪一个实体类. 还可以* 来添加查询条件, 还可以结合 EntityManager 对象得到最终查询的 TypedQuery 对象.使用不多* @param *criteriaBuilder: CriteriaBuilder 对象. 用于创建 Criteria 相关对象的工厂. 当然可以从中获取到 Predicate 对象* @return: *Predicate 类型, 代表一个查询条件.*/@Overridepublic Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {Path<Integer> age = root.get("age");Predicate p1 = criteriaBuilder.greaterThan(age, 18);Path username = root.get("username");Predicate p2 = criteriaBuilder.like(username, "%李四%");// where user0_.age>18 and ( user0_.username like ? )return criteriaBuilder.and(p1, p2);}};List list1 = userDao.findAll(s1);System.out.println(list1);}
三、自定义Repository接口
如果SpringData提供的JPA接口没有我们需要的查询方式,也是可以自定义Repository接口的。
spring data除了已经给我们提供了大量的 Repository接口,它支持我们自己定义Repository接口来扩展功能,实现一些个性化的需求。
1、自定义Repository接口的具体步骤:
1)新建一个自定义接口
// 自定义 Repository接口
public interface MyUserRepository {List<User> findByAge(Integer age);
}
2)新建该自定义接口的实现类,并对方法进行实现,需要注入 EntityManager对象完成对数据库的操作
public class MyUserRepositoryImpl implements MyUserRepository {// 这里使用JPA技术实现@PersistenceContextprivate EntityManager entityManager;@Overridepublic List<User> findByAge(Integer age) {String jpql = "select u from User u where u.age <= ?1";Query query = entityManager.createQuery(jpql, User.class);query.setParameter(1, age);List<User> resultList = query.getResultList();return resultList;}
}
注意:实现类的名称必须是该自定义接口的名称+Impl,名称会由SpringData解析。
EntityManager是JPA中用于增删改查的接口,它的作用相当于一座桥梁,连接内存中的 Java对象和数据库的数据存储。也可以根据它进行sql的原生查找。
3)在目标接口(dao层接口)中继承该自定义接口。
public interface UserDao extends JpaRepository<User, Long>, MyUserRepository {// spring data jpa 方法List<User> findUsersByUsernameLikeAndAgeLessThanEqual(String username, Integer age);
}
4)测试类,目标接口(dao层接口)就可以使用自定义接口方法
@Testpublic void testList() {List<User> userList = userDao.findByAge(18);System.out.println(userList);List<User> userList2 = userDao.findUsersByUsernameLikeAndAgeLessThanEqual("%赵云%", 18);System.out.println(userList2);}
参考文章:
Spring Data JPA之JpaSpecificationExecutor复杂动态查询实例
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。
Spring Data JPA 自定义Repository接口与子接口相关推荐
- Spring Data JPA使用必备(三):Spring Data JPA自定义SQL写法
Spring Data JPA的前两篇已经写了通过方法名格式自动生成SQL,也简单的提到了@Query注解.但是往往真正的业务逻辑里面,这些是完全不够用的,涉及到一些稍微复杂一点的查询就会有点问题,如 ...
- Spring Data JPA自定义SELECT查询语句,自定义UPDATE修改语句
查询语句: 1. 在@Query 注解里设置value ,?1.?2 分别代表第一第二个参数, nativeQuery=true 表示是否是原生SQL @Query(value = "se ...
- 快速搭建springmvc+spring data jpa工程
一.前言 这里简单讲述一下如何快速使用springmvc和spring data jpa搭建后台开发工程,并提供了一个简单的demo作为参考. 二.创建maven工程 http://www.cnblo ...
- 学习Spring Data JPA
简介 Spring Data 是spring的一个子项目,在官网上是这样解释的: Spring Data 是为数据访问提供一种熟悉且一致的基于Spring的编程模型,同时仍然保留底层数据存储的特殊 ...
- Spring Data JPA简单学习
从一个简单的 JPA 示例开始 本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示 ...
- Spring Data JPA教程
在Java类或对象与关系数据库之间管理数据是一项非常繁琐且棘手的任务. DAO层通常包含许多样板代码,应简化这些样板代码,以减少代码行数并使代码可重复使用. 在本教程中,我们将讨论Spring数据的J ...
- JAVA入门[20]-Spring Data JPA简单示例
Spring 对 JPA 的支持已经非常强大,开发者只需关心核心业务逻辑的实现代码,无需过多关注 EntityManager 的创建.事务处理等 JPA 相关的处理.Spring Data JPA更是 ...
- 【Spring Data JPA自学笔记二】初识Spring Data JPA
文章目录 Spring Data JPA是什么? Spring Data JPA的配置 配置pom.xml 配置applicationContext.xml Spring Data JPA的使用 Sp ...
- spring data jpa从入门到精通_程序员笔记:Spring Data JPA入门
什么是JPA JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为了 ...
最新文章
- linux 内核网络协议栈--数据从接收到IP层(二)
- 关闭或开启memory_target
- mysql数据库任务驱动教程答案_MySQL数据库任务驱动式教程
- c++11多线程之packaged_task<>介绍与实例
- P7077-函数调用【拓扑排序,dp】
- dates.format_在SQL中使用DATES及其不同的内置函数NOW(),FORMAT()
- ACM-ICPC 2018 南京赛区网络预赛 B. The writing on the wall
- 附录 SpringBoot 默认的扫描包是哪个?
- css样式(二)(伪类 | 伪元素 | 导航 | 图像拼合 | 属性选择器 )
- 中移动总裁李跃:发展Wifi才是长久之计
- oracle extract类型,Oracle中extract()函数
- Qt中QImage用于16位图像的显示,QImage数据对齐
- 分享两款免费的流程图、原型图工具
- cdr怎么抠图轮廓线条_cdr怎么快速抠图呢 需要技巧
- 3D图库框架范围与示例
- 外牌免检车辆上海年检
- OnlyOffice快速入门
- 浅谈数据中心 IT 机房的空气调节(下篇)-制冷中断
- flea-db使用之封装JDBC接入
- Win10连接上了wifi,但显示Internet无网络访问权限的解决方法