Spring-Data-JPA在做数据存储方面真的很方便,它的目的就是写更少的代码,更多的事情,但是也有其力有未逮或者说处理起来比较闹心的地方。

  1.先来感受一下使用JPA做数据查询时,代码的简化程度


@CacheConfig(cacheNames = "news")
public interface NewsRepository extends PagingAndSortingRepository<NewsEntity, Long> {
@Cacheable
NewsEntity findOne(Long id); @Cacheable
NewsEntity findTop1ByOriginId(String originId); @Transactional
long deleteByOriginId(String originId); Page<NewsEntity> findDistinctByTitleStartingWithAndSimilarIdIsNullOrderByPubDateDesc(String title, Pageable pageable);
}

单表查询时,只需要根据JPA提供的规范去命名,根本不需要自己去写什么查询语句就可以。

  2.当然要自己写SQL语句也没有问题

@Query(value = "select e.* from news_detail e INNER JOIN news_info n  on e.news_id = n.id where n.pub_date >= ?1", nativeQuery = true)
List<Object> listBypubDateWithEntityDetail(String pubDate); @Query(value = "select n.id,GROUP_CONCAT(e.ent_id) from news_info n INNER JOIN map_news_company e on e.news_id = n.id where n.pub_date>= ?1 and n.id>?2 group by n.id order by n.id limit 10000", nativeQuery = true)
List<Object[]> listBypubDateWithEnts(String pubDate, long news_id);

使用原生的SQL也可以,JPA就是这么方便,然而总有需要操心的地方——多条件分组查询。用过Hibernate和Mybatis的,在写业务逻辑的时候,拼接查询条件的时候,一定写过很多if条件不为空的判断,这就是JPA操蛋的地方。

  3.看看例子

    @Query(value = "select pub_time,count(1) as count from t_weibo where content like %:keyword% and pub_time>=:dateFrom and pub_time<=:dateTo group by pub_time", nativeQuery = true)
List<Object[]> getWeibo(@Param("keyword") String keyword, @Param("dateFrom") Date dateFrom, @Param("dateTo") Date dateTo); @Query(value = "select pub_time,count(1) as count from t_weibo where content like %:keyword% and pub_time>=:dateFrom and pub_time<=:dateTo and region in ( select keyname from t_cell where provincename=:provincename) group by pub_time", nativeQuery = true)
List<Object[]> getWeiboByProvince(@Param("provincename") String provincename,@Param("keyword") String keyword,@Param("dateFrom") Date dateFrom, @Param("dateTo") Date dateTo);

这个例子两个方法的作用一样,条件个数不一样,这就是冗余了。

  4.如果是这样JPA被设计出来的意义是什么,jpa有一套来应对这些的措施,使用Specification这个来来完成条件拼接

User user1 = (User) userRepository.findOne(new Specification<User>() {
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
/*criteriaQuery.where(criteriaBuilder.equal(root.<String>get("name"), user.getName()),
criteriaBuilder.equal(root.<String>get("password"), user.getPwd()));*/
          Predicate predicate = null;
          if(user.getName!=null&&!user.getName().equal){
            if(predicate!=null){
             predicate = criteriaBuilder.equal(root.<String>get("name"), user.getName())
                    }else{
              predicate = criteriaBuilder.and(predicte,criteriaBuilder.equal(root.<String>get("name"), user.getName()))
                    }
                }
          if(predicate!=null){
            criteriaQuery.where(predicate);
          }
return null;
}
});

核心就是使用CriteriaBuilder 进行条件拼接

  5.还有一种方式就是使用QueryDsl插件来组合Spring Data JPA使用

添加maven依赖
<!--queryDSL-->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
配置querydsl插件
<build>
<plugins>
<!--该插件可以生成querysdl需要的查询对象,执行mvn compile即可-->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

此时编译(compile)一下maven项目,在这个(target/generated-sources/java)文件夹下看到对应于你建的实体类(User)的QueryDsl类(QUser)

@Entity
@Table(name = "users")
@Data
public class UserBean
{
@Id
@GeneratedValue
@Column(name = "u_id")
private Long id;
@Column(name = "u_username")
private String name;
@Column(name = "u_age")
private int age;
@Column(name = "u_score")
private double socre;
}

查询语句

@PersistenceContext
EntityManager entityManager;
@RequestMapping("query")
public List<GoodEntity> list(){
QUserBean userBean = QUserBean.userBean;
JPAQuery<UserBean> jpaQuery = new JPAQuery<>(entityManager);
return jpaQuery.select(userBean)
.from(userBean)
.where(userBean.name.eq("haha"))
.fetch();
}

  

SpringBoot使用JPA来做数据查询的更多相关文章

  1. springboot使用validation 插件做数据校验

    不多说废话. 首先,我们需要在入参实体对象中,使用注解,控制 @Datapublic class UpdateShufflingRequest { private String shuffling_l ...

  2. SpringBoot中JPA使用动态SQL查询

    https://www.jianshu.com/p/f72d82e90948 可以重点关注方法二,把原生sql传入数据库去查询 好处是:更加灵活坏处是:拼接sql比较痛苦,也容易出问题,比如拼接的sq ...

  3. 工作流activiti-03数据查询(流程定义 流程实例 代办任务) 以及个人小练习

    在做数据查询的时候通过调用api来查询数据是相当的简单 对分页也进行了封装listPage(0, 4) ;listPage:分页查询 0:表示起始位置,4:表示查询长度 但是公司的框架封装了分页数据  ...

  4. 第11章—使用对象关系映射持久化数据—SpringBoot+SpringData+Jpa进行查询修改数据库

    SpringBoot+SpringData+Jpa进行查询修改数据库 JPA由EJB 3.0软件专家组开发,作为JSR-220实现的一部分.但它又不限于EJB 3.0,你可以在Web应用.甚至桌面应用 ...

  5. springboot集成Spring Data JPA数据查询

    1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...

  6. SpringBoot Data JPA 关联表查询的方法

    SpringBoot Data JPA实现 一对多.多对一关联表查询 开发环境 IDEA 2017.1 Java1.8 SpringBoot 2.0 MySQL 5.X 功能需求 通过关联关系查询商店 ...

  7. SpringBoot数据访问(二) SpringBoot整合JPA

    JPA简介 Spring Data JPA是Spring Data大家族的一部分,它可以轻松实现基于JPA的存储库.该模块用于增强支持基于JPA的数据访问层,它使我们可以更加容易地构建使用数据访问技术 ...

  8. ajax基础语法、ajax做登录、ajax做用户名验证是否可用、ajax做关键字查询动态显示、ajax做用表格显示数据并增加操作列

    AJAX: AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新.   ...

  9. 带你搭一个SpringBoot+SpringData JPA的环境

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 不知道大家对SpringBoot和Spring Da ...

随机推荐

  1. HA cluster

    ------------恢复内容开始------------ 集群分类: LB负载均衡集群(lvs/nginx(http/upstream, stream/upstream)),HA高可用集群,HP高 ...

  2. luogu P4513 小白逛公园 (区间合并)

    链接:https://www.luogu.org/problemnew/show/P4513 思路: 很基础的区间合并,开四个数组: num: 区间数字的和 lsum:从左端点起最大连续字段和 rsu ...

  3. [转帖]图说Docker架构的各种信息

    图说Docker架构的各种信息 2018-07-18 15:16:04作者:linux人稿源:运维之美   https://ywnz.com/linuxyffq/2344.html 介绍Docker架 ...

  4. # MATLAB数据处理

    目录 MATLAB数据处理 数据归一化处理 冒号的作用(获取指定行列的数据) MATLAB数据处理 mean(A,(b)) %均值函数,b为设置对哪一维上的数据进行处理,默认为第一维(列),行为第二维 ...

  5. Elasticsearch5.x安装及常见错误的解决方法

    Elasticsearch是基于java开发的,机器上必须要先java环境,elasticsearch5.x建议用jdk8的最新版本.下面介绍elasticsearch5.x的安装步骤: 一.安装El ...

  6. Ruby Rails学习中:Sass 和 Asset Pipeline,布局中的链接(Rails路由,具名路由),用户注册: 第一步

    接上篇: 一.Sass 和 Asset Pipeline Rails 中最有用的功能之一是 Asset Pipeline, 它极大地简化了静态资源文件(CSS.JavaScript 和图像)的生成和管 ...

  7. less的引用及公共变量的抽离

    一.什么是less? less是什么自然不用多言,乃一个css预编译器,可以扩展css语言,添加功能如如允许变量(variables),混合(mixins),函数(functions) 和许多其他的技 ...

  8. IDEA将项目打包为指定class文件的jar

    转自:https://blog.csdn.net/makang456/article/details/86699375 [背景]     公司最近要和某大公司合作,将本公司的产品提供给其它公司单独部署 ...

  9. LintCode 547---两数组的交集

    public class Solution { /** * 给出两个数组,写出一个方法求出它们的交集 * @param nums1: an integer array * @param nums2: ...

  10. Vue-Cli项目如何查看依赖调用关系?

    Vue是个优秀的前端框架,不管是前端还是后端开发人员都能很快使用Vue来开发应用.但是随着项目开发的深入,组件之间的依赖就变得越来越多,耦合越来越严重.这时候我们迫切地需要分析下组件和依赖之间的调用关 ...