SpringDataJPA之JpaRepository和JpaSpecificationExecutor接口

简介: JpaRepository 接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法。


文章目录

   JpaRepository

       1.创建接口

       2.单元测试

   JpaSpecificationExecutor

       1.创建接口

       2.具体功能

           2.1 单条件查询

           2.2 多条件查询

           2.3 分页

           2.4 排序

           2.5 分页排序

 本文我们来介绍下SpringDataJPA继承结构中剩下的两个接口

JpaRepository

 JpaRepository 接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法。

1.创建接口

/**
 * SpringDataJPA 实现JpaRepository
 * 泛型 第一个参数是对应的Pojo类型
 *      第二个参数是注解的包装类型
 */
public interface UserDao extends JpaRepository<Users,Integer> {
}

2.单元测试

/**
 * @program: spring-data-jpa
 * @description: 单元测试
 * @author: 波波烤鸭
 * @create: 2019-05-18 09:48
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestDemo {
    @Autowired
    private UserDao usersDao;
    /**
     * 添加用户
     */
    @Test
    @Transactional// 在测试类对于事务提交方式默认的是回滚。
    @Rollback(false)//取消自动回滚
    public void testInsertUsers(){
        Users users = new Users();
        users.setUserage(20);
        users.setUsername("张三-jpa");
        this.usersDao.save(users);
    }
}

JpaSpecificationExecutor

 完成多条件查询,并且支持分页与排序。

1.创建接口

 JpaSpecificationExecutor接口不能够单独使用,需要和其他接口一块使用,如下

/**
 * JpaSpecificationExecutor 接口讲解
 * @author Administrator
 *注意:JpaSpecificationExecutor<Users>:不能单独使用,需要配合着 jpa 中的其他接口一起使用
 */
public interface UserDao extends JpaRepository<Users, Integer>
          , JpaSpecificationExecutor<Users> {
}

2.具体功能

2.1 单条件查询

/**
*  单条件查询
* 需求:根据用户姓名查询数据
*/
@Test
public void test1(){
   Specification<Users> spec = new Specification<Users>() {
       /**
        * @return Predicate:定义了查询条件
        * @param Root<Users> root:根对象。封装了查询条件的对象
        * @param CriteriaQuery<?> query:定义了一个基本的查询.一般不
       使用
        * @param CriteriaBuilder cb:创建一个查询条件
        */
       @Override
       public Predicate toPredicate(Root<Users> root,
                                    CriteriaQuery<?> query, CriteriaBuilder cb) {
           Predicate pre = cb.equal(root.get("username"), "王五");
           return pre;
       }
   };
   List<Users> list = this.usersDao.findAll(spec);
   for (Users users : list) {
       System.out.println(users);
   }
}

2.2 多条件查询

 多条件查询有两种方式,具体如下

/**
 * 多条件查询 方式一
 * 需求:使用用户姓名以及年龄查询数据
 */
@Test
public void test2() {
    Specification<Users> spec = new Specification<Users>() {
        @Override
        public Predicate toPredicate(Root<Users> root,
                                     CriteriaQuery<?> query, CriteriaBuilder cb) {
            List<Predicate> list = new ArrayList<>();
            list.add(cb.equal(root.get("username"), "王五"));
            list.add(cb.equal(root.get("userage"), 24));
            //此时条件之间是没有任何关系的。
            Predicate[] arr = new Predicate[list.size()];
            return cb.and(list.toArray(arr));
        }
    };
    List<Users> list = this.usersDao.findAll(spec);
    for (Users users : list) {
        System.out.println(users);
    }
}
/**
 * 多条件查询 方式二
 * 需求:使用用户姓名或者年龄查询数据
 */
@Test
public void test3(){
    Specification<Users> spec = new Specification<Users>() {
        @Override
        public Predicate toPredicate(Root<Users> root,
                                     CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.or(cb.equal(root.get("username"),"王五 "),cb.equal(root.get("userage"), 25));
        }
    };
    List<Users> list = this.usersDao.findAll(spec);
    for (Users users : list) {
        System.out.println(users);
    }
}

2.3 分页

/**
 * 需求:查询王姓用户,并且做分页处理
 */
@Test
public void test4(){
    //条件
    Specification<Users> spec = new Specification<Users>() {
        @Override
        public Predicate toPredicate(Root<Users> root,
                                     CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.like(root.get("username").as(String.class), "王%");
        }
    };
    //分页
    Pageable pageable = new PageRequest(2, 2);
    Page<Users> page = this.usersDao.findAll(spec, pageable);
    System.out.println("总条数:"+page.getTotalElements());
    System.out.println("总页数:"+page.getTotalPages());
    List<Users> list = page.getContent();
    for (Users users : list) {
        System.out.println(users);
    }
}

2.4 排序

/**
 * 需求:查询数据库中王姓的用户,并且根据用户 id 做倒序排序
 */
@Test
public void test5(){
    //条件
    Specification<Users> spec = new Specification<Users>() {
        @Override
        public Predicate toPredicate(Root<Users> root,
                                     CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.like(root.get("username").as(String.class),
                    "王%");
        }
    };
    //排序
    Sort sort = new Sort(Sort.Direction.DESC,"userid");
    List<Users> list = this.usersDao.findAll(spec, sort);
    for (Users users : list) {
        System.out.println(users);
    }
}

2.5 分页排序

/**
 * 需求:查询数据库中王姓的用户,做分页处理,并且根据用户 id 做倒序排序
 */
@Test
public void test6(){
    //排序等定义
    Sort sort = new Sort(Sort.Direction.DESC,"userid");
    //分页的定义
    Pageable pageable = new PageRequest(0,2, sort);
    //查询条件
    Specification<Users> spec = new Specification<Users>() {
        @Override
        public Predicate toPredicate(Root<Users> root,
                                     CriteriaQuery<?> query, CriteriaBuilder cb) {
            return cb.like(root.get("username").as(String.class),
                    "王%");
        }
    };
    Page<Users> page = this.usersDao.findAll(spec, pageable);
    System.out.println("总条数:"+page.getTotalElements());
    System.out.println("总页数:"+page.getTotalPages());
    List<Users> list = page.getContent();
    for (Users users : list) {
        System.out.println(users);
    }
}

如此我们对于单表的相关操作通过JpaSpecificationExecutor接口和JpaRepository接口就都可以实现了~


相关文章
|
1月前
|
资源调度 JavaScript 前端开发
在Vue 3项目中集成Element Plus组件库的步骤
总结起来,在集成过程当中我们关注于库本身提供功能与特性、环境搭建与依赖管理、模块化编程思想以及前端工程化等方面知识点;同时也涵盖前端性能优化(比如上文提及“按需加载”)与定制化开发(例如“自定义主题”)等高级话题.
144 16
|
8月前
|
存储 Java
Java中判断一个对象是否是空内容
在 Java 中,不同类型的对象其“空内容”的定义和判断方式各异。对于基本数据类型的包装类,空指对象引用为 null;字符串的空包括 null、长度为 0 或仅含空白字符,可通过 length() 和 trim() 判断;集合类通过 isEmpty() 方法检查是否无元素;数组的空则指引用为 null 或长度为 0。
|
前端开发 Java API
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
本文是Vert.x学习系列的第五部分,讨论了回调函数的限制、Future和Promise在异步操作中的应用、响应式扩展以及Kotlin协程,并通过示例代码展示了如何在Vert.x中使用这些异步编程模式。
292 5
vertx学习总结5之回调函数及其限制,如网关/边缘服务示例所示未来和承诺——链接异步操作的简单模型响应式扩展——一个更强大的模型,特别适合组合异步事件流Kotlin协程
|
缓存
RestTemplate请求访问简单使用
RestTemplate请求访问简单使用
198 1
|
关系型数据库 MySQL 数据库
深入OceanBase分布式数据库:MySQL 模式下的 SQL 基本操作
深入OceanBase分布式数据库:MySQL 模式下的 SQL 基本操作
|
Java 关系型数据库 数据库连接
java使用AOP切面获取请求日志并记录
java使用AOP切面获取请求日志并记录
|
Java Apache Maven
Java:commons-codec实现byte数组和16进制字符串转换
在上述代码中,`Hex.encodeHexString(bytes)`用于将byte数组转换为16进制字符串,`Hex.decodeHex(hexString)`用于将16进制字符串转换为byte数组。
402 0
|
Java 数据库连接
JPA - Persistence与EntityManagerFactory简解
JPA - Persistence与EntityManagerFactory简解
445 0