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. eval 命令

    eval命令用于重新运算求出参数的内容. eval可读取一连串的参数,然后再依参数本身的特性来执行. 语法: eval [参数]示例:eval echo 123

  2. 学习笔记:CentOS 7学习之十二:查找命令

    目录 1.which-whereis-locate-grep-find查找命令 1.1 which 1.2 whereis 1.3 locate 1.4 grep 1.5 find命令 2. 命令的判 ...

  3. Linux常用安装配置

    一.创建.删除.分组 创建用户 命令:useradd  用户名 或    adduser 用户名 注意:只有root用户才能创建新用户 例如,创建一个名为zhangsan的用户 使用passwd命令为 ...

  4. 基于.NET架构的树形动态报表设计与应用

    在一些统计报表中,利用树形结构报表来实现维度钻取功能是十分常见的.通过逐级钻取,可以快速查看更细粒度的指标数据,如项目施工进度报告等. 使用葡萄城报表控件——ActiveReports ,即可轻松设计 ...

  5. sql常用到的查询连接

    一.内连接(Inner Join) select * from a inner join b on a.name=b.name; 此语句的结果为同时匹配表a和表b的记录集.即内连接取的是两个表的交集. ...

  6. Python特色数据类型--元组

    元组是不可改变的,创建后就不能做任何修改操作了 1.元组用()表示

  7. Replication-Manager

    MYSQL5.7下搭建Replication-Manager 环境说明 在主机1,主机2,主机3上安装MySQL服务端和客户端. 主机1 主机2 主机3 操作系统 CentOS7.4 CentOS7. ...

  8. python函数篇0-2

    函数的有三中不同的参数: 普通参数 默认参数 动态参数# ######### 定义函数 ######### # name 叫做函数func的形式参数,简称:形参def func(name):    p ...

  9. 另类--kafka集群中jmx端口设置

    # 监控kafka集群 # 有一个问题,需要在kafka-server-start.sh文件中配置端口,有如下三种办法 # 第一种:复制并修改kafka目录,比如kafka-1,kafka-2,kaf ...

  10. 在Window Server 2016中使用Web Deploy方式发布.NET Web应用

    1.在IIS里面点击获取新的Web平台组件 2.下载Web平台组件并安装 3.在其中搜索Web Deploy,找到3.5版本,并安装 4.继续搜索Web Deploy 3.6版本,并安装 安装好之后, ...