上一篇文章对Spring Data JPA更深( )一步剖析。

上一篇只是简单的介绍了Spring Data JPA的简单使用,而往往在项目中这一点功能并不能满足我们的需求。这是当然的,在业务中查询是一件非常头疼的事,毕竟不可能只是对一张表的查询是吧? 其实在业务中往往会涉及到多张表的查询,以及查询时需要的各种条件。当然这不用担心,毕竟这是对JPA的支持,而我们在用JPA原生态API的时候往往可能会把一些个方法写得很凌乱,没得一个具体的规范来写自己的方法在后期维护上肯定会很困难。当然你自己也可以封装一些方法来使用,而当我们使用到Spring Data JPA时,它已经帮助我们完成了这个方法的规范了。

来一起看一下复杂查询时它为我们提供的接口。

JpaSpecificationExecutor.class

  1. public interface JpaSpecificationExecutor<T> {
  2. T findOne(Specification<T> spec);
  3. List<T> findAll(Specification<T> spec);
  4. Page<T> findAll(Specification<T> spec, Pageable pageable);
  5. List<T> findAll(Specification<T> spec, Sort sort);
  6. long count(Specification<T> spec);
  7. }

在这个接口里面出现次数最多的类就是Specification.class,而这个类主要也就是围绕Specification来打造的,Specification.class是Spring Data JPA提供的一个查询规范,而你只需围绕这个规范来设置你的查询条件便可,我们来看一下Specification.class这个接口中有些什么东西。

Specification.class

  1. public interface Specification<T> {
  2. Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
  3. }

只有一个方法toPredicate,而其中的参数大家并不陌生,都是JPA规范中的,ROOT查询中的条件表达式、CriteriaQuery条件查询设计器、CriteriaBuilder条件查询构造器,而我们在使用复杂对象查询时,实现该方法用JPA去构造对象查询便可。

下面来看一个小例子:

  1. @Repository("userDao")
  2. public interface IUserDao extends JpaSpecificationExecutor<User>{

仍然只是一个空接口,这次继承的是JpaSpecificationExecutor了。 
再写一测试用例:查询用户表中name包含Sam的记录,并分页按照birth排倒序

  1. public class UserDaoTest {
  2. private static ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  3. private static IUserDao userDao = (IUserDao) context.getBean("userDao");
  4. public void findBySpecAndPaginate() {
  5. Page<User> page = userDao.findAll(new Specification<User>() {
  6. @Override
  7. public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
  8. root = query.from(User.class);
  9. Path<String> nameExp = root.get("name");
  10. return cb.like(nameExp, "%Sam%");
  11. }
  12. }, new PageRequest(1, 5, new Sort(Direction.DESC, new String[] { "birth" })));
  13. StringBuilder stout = new StringBuilder(" 以下是姓名包含Sam人员信息 : ").append("\n");
  14. stout.append("| 序号 | username | password | name | sex | birth |").append("\n");
  15. int sortIndex = 1;
  16. for (User u : page.getContent()) {
  17. stout.append(" | ").append(sortIndex);
  18. stout.append(" | ").append(u.getUsername());
  19. stout.append(" | ").append(u.getPassword());
  20. stout.append(" | ").append(u.getName());
  21. stout.append(" | ").append(u.getSex());
  22. stout.append(" | ").append(u.getBirth());
  23. stout.append(" | \n");
  24. sortIndex++;
  25. }
  26. System.err.println(stout);
  27. }
  28. public static void main(String[] args) {
  29. UserDaoTest test = new UserDaoTest();
  30. test.findBySpecAndPaginate();
  31. }
  32. }

当然,这只是一个测试,很简单的一个条件查询方法。你也可以设计复杂的查询来得到自己所需的结果,我这只是写一个很简单的方法来带大家入门。

写了两篇文章了,还没有讲Spring Data JPA为什么只需定义接口就可以使用,其实这也不难发现,查看源码,可以找到针对JpaRepository和JpaSpecificationExecutor有一个实现类,SimpleJpaRepository.class,这个类实现了刚才所提的两个接口。而Spring在给我们注入实现类的时候,就正是这个SimpleJpaRepository.class,具体的实现方式我就不在这意义赘述了,大家如果有兴趣可以去查看它的源码,和传统的JPA实现是一样的。

通过这篇文章我们学习到了,当要使用复杂的条件查询时,我们可以选择使用此接口来完善我们的需求,这篇文章就讲到这里,在下一篇文章中我主要是讲Spring Data JPA为我们提供的注解查询。

转自:http://z276356445t.iteye.com/blog/1602258

一步步学习 Spring Data 系列之JPA(二)的更多相关文章

  1. 一步步学习 Spring Data 系列之JPA(一)

    引入: Spring Data是SpringSource基金会下的一个用于简化数据库访问,并支持云服务的开源框架.其主要目标是使得数据库的访问变得方便快捷,并支持map-reduce框架和云计算数据服 ...

  2. Spring Data系列之Jpa(一)

    1.Spring Data的由来 Spring Data是SpringSource基金会创下的一个简化数据库访问.支持云服务的开源框架.其主要目的是让数据库访问变的方便快捷,可以用Spring Dat ...

  3. 学习Spring Data JPA

    简介 Spring Data 是spring的一个子项目,在官网上是这样解释的: Spring Data 是为数据访问提供一种熟悉且一致的基于Spring的编程模型,同时仍然保留底层数据存储的特​​殊 ...

  4. 学习-spring data jpa

    spring data jpa对照表 Keyword Sample JPQL snippet And findByLastnameAndFirstname - where x.lastname = ? ...

  5. Deep Learning(深度学习)学习笔记整理系列之(二)

    Deep Learning(深度学习)学习笔记整理系列 zouxy09@qq.com http://blog.csdn.net/zouxy09 作者:Zouxy version 1.0 2013-04 ...

  6. 一文深入浅出学习Spring框架系列,强烈推荐

    本系列主要介绍Spring框架整体架构,Spring的核心IOC,AOP的案例和具体实现机制:以及SpringMVC框架的案例和实现机制.@pdai 相关文章 首先, 从Spring框架的整体架构和组 ...

  7. 学习Spring框架系列(一):通过Demo阐述IoC和DI的优势所在

    Spring框架最核心东西便是大名鼎鼎的IoC容器,主要通过DI技术实现.下面我通过Demo的演变过程,对比学习耦合性代码,以及解耦和的过程,并深入理解面向接口编程的真正内涵. 这个例子包括如下几个类 ...

  8. MongoDB学习-->Spring Data Mongodb框架之Repository

    application-dev.yml server: port: 8888 mongo: host: localhost port: 27017 timeout: 60000 db: mamabik ...

  9. MongoDB学习-->Spring Data Mongodb-->MongodbTemplate

    配置文件application-dev.yml: server: port: 8888 mongo: host: localhost port: 27017 timeout: 60000 db: ma ...

随机推荐

  1. 小小改动帮你减少bundle.js文件体积(翻译)

    我已经从事过好多年的SPA开发工作,我发现很多的程序猿都从来不往 bundle.js 文件的体积上动脑筋,这让我有点懵逼. “安心洗路,等俺把代码混淆压缩后就一切666了”,若是有人这么说,我会翻白眼 ...

  2. 架构之路(八)从CurrentUser说起

    CurrentUser,也就是当前用户,这是我们系统中大量使用的一个概念. 确认当前用户 当然,我们利用的是cookie:用户的ID存放在cookie中,服务器端通过cookie中的Id,查找数据库, ...

  3. HTML5网页录音和压缩,边猜边做..(附源码)

    宣传一下自己的qq群: (暗号:C#交流) 欢迎喜欢C#,热爱C#,正在学习C#,准备学习C#的朋友来这里互相学习交流,共同进步 群刚建,人不多,但是都是真正热爱C#的 我也是热爱C#的 希望大家可以 ...

  4. 牛顿法求平方根 scala

    你任说1个整数x,我任猜它的平方根为y,如果不对或精度不够准确,那我令y = (y+x/y)/2.如此循环反复下去,y就会无限逼近x的平方根.scala代码牛顿智商太高了println( sqr(10 ...

  5. AngularJs之五

    一:angularJs的事件. 1.ng-click指令定义了AngularJS点击事件. <div ng-app="myapp" ng-controller="m ...

  6. 我们为什么使用Node

    引言:Node 已经迅速成为一个可行并且真正高效的web 开发平台.在Node 诞生之前,在服务端运行JavasScript 是件不可思议的事情,并且对其他的脚本语言来说,要实现非阻塞I/O 通常需要 ...

  7. ES6之块级作用域

    一.前言 在ECMAScript6(以下简称ES6)之前,ECMAScript的作用域只有两种: 1.  全局作用域: 2.  函数作用域. 正是因为有这两种作用域,所以在JavaScript中出现一 ...

  8. SpringMVC中定时任务配置

    在项目中使用定时任务是常有的事,比如每天定时进行数据同步或者备份等等. 以前在从事C语言开发的时候,定时任务都是通过写个shell脚本,然后添加到linux定时任务中进行调度的. 现在使用Spring ...

  9. c 进程和系统调用

    这一篇博客讲解进程和系统调用相关的知识 有这样一个场景,我需要输入一串文字,然后把我输入的文字加上一个本地的时间戳 保存在一个文件中,可以初步理解为一个备忘录也行 #include <stdio ...

  10. HTML5 学习总结(二)——HTML5新增属性与表单元素

    一.HTML5新增属性 1.1.contextmenu contextmenu的作用是指定右键菜单. <!DOCTYPE html> <html> <head> & ...