springboot整合spring data jpa 动态查询
Spring Data JPA虽然大大的简化了持久层的开发,但是在实际开发中,很多地方都需要高级动态查询,在实现动态查询时我们需要用到Criteria API,主要是以下三个:
1、Criteria 查询是以元模型的概念为基础的,元模型是为具体持久化单元的受管实体定义的,这些实体可以是实体类,嵌入类或者映射的父类。
2、CriteriaQuery接口:代表一个specific的顶层查询对象,它包含着查询的各个部分,比如:select 、from、where、group by、order by等注意:CriteriaQuery对象只对实体类型或嵌入式类型的Criteria查询起作用
3、Root接口:代表Criteria查询的根对象,Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似
在JPA中,标准查询是以元模型的概念为基础的.元模型是为具体持久化单元的受管实体定义的.这些实体可以是实体类,嵌入类或者映射的父类.提供受管实体元信息的类就是元模型类。使用元模型类最大的优势是凭借其实例化可以在编译时访问实体的持久属性.该特性使得criteria 查询更加类型安全。例如:Product实体类对应的元模型Product_:
package powerx.io.bean; import javax.annotation.Generated;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel; @Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor")
@StaticMetamodel(Product.class)
public abstract class Product_ { public static volatile SingularAttribute<Product, Double> price;
public static volatile SingularAttribute<Product, String> name;
public static volatile SingularAttribute<Product, Integer> id; }
这样的元模型不用手动创建,有多种构建方式,本人使用的IDE是STS,具体操作如下:选中项目——鼠标右键Properties进入配置界面——java compiler下Annotation Processing——勾选enable project specific settings——Annotation Processing下Factory path——add external JARs ——加入事先下载好的hibernate-jpamodelgen-5.2.10.Final.jar——apply后则会在项目根目录下生成.apt_generated包,包内含有对应的实体类元模型(看不到的同学需要把resource过滤去掉),还有其它的方式,可参考http://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html/chapter-usage.html。
使用criteria 查询简单Demo
@Resource
private EntityManager entityManager; public List<Product> findByConditions(String name, Double price) {
//创建CriteriaBuilder安全查询工厂
//CriteriaBuilder是一个工厂对象,安全查询的开始.用于构建JPA安全查询.
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
//创建CriteriaQuery安全查询主语句
//CriteriaQuery对象必须在实体类型或嵌入式类型上的Criteria 查询上起作用。
CriteriaQuery<Product> query = criteriaBuilder.createQuery(Product.class);
//Root 定义查询的From子句中能出现的类型
Root<Product> ProductRoot = query.from(Product.class);
//Predicate 过滤条件 构建where字句可能的各种条件
//这里用List存放多种查询条件,实现动态查询
List<Predicate> predicatesList = new ArrayList<>();
//name模糊查询 ,like语句
if (name != null) {
predicatesList.add(
criteriaBuilder.and(
criteriaBuilder.like(
ProductRoot.get(Product_.name), "%" + name + "%")));
}
// ProductPrice 小于等于 <= 语句
if (price != null) {
predicatesList.add(
criteriaBuilder.and(
criteriaBuilder.le(
ProductRoot.get(Product_.price), price)));
} query.where(predicatesList.toArray(new Predicate[predicatesList.size()]));
TypedQuery<Product> typedQuery = entityManager.createQuery(query);
List<Product> resultList = typedQuery.getResultList();
return resultList;
}
criteriaBuilder中各方法对应的语句:
equle : filed = value
gt / greaterThan : filed > value
lt / lessThan : filed < value
ge / greaterThanOrEqualTo : filed >= value
le / lessThanOrEqualTo: filed <= value
notEqule : filed != value
like : filed like value
notLike : filed not like value
如果每个动态查询的地方都这么写,那就感觉太麻烦了。那实际上,在使用Spring Data JPA的时候,只要我们的Repo层接口继承JpaSpecificationExecutor接口就可以使用Specification进行动态查询,在这里因为findAll(Specification<T> var1, Pageable var2)方法中参数 Specification<T> 是一个匿名内部类
那这里就可以直接用lambda表达式直接简化代码。
持久层接口类:
package powerx.io; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import powerx.io.bean.Product; public interface ProductDao extends JpaRepository<Product, Integer>,JpaSpecificationExecutor<Product> { }
service层:
@Autowired
private ProductDao productDao; public List<Product> findByConditions2(String name, Double price) {
return productDao.findAll((root, criteriaQuery, criteriaBuilder) -> {
List<Predicate> predicatesList = new ArrayList<>();
if (name != null) {
predicatesList.add(
criteriaBuilder.and(
criteriaBuilder.like(
root.get(Product_.name), "%" + name + "%")));
}
// itemPrice 小于等于 <= 语句
if (price != null) {
predicatesList.add(
criteriaBuilder.and(
criteriaBuilder.le(
root.get(Product_.price), price)));
}
return criteriaBuilder.and(
predicatesList.toArray(new Predicate[predicatesList.size()]));
});
}
控制器类:
package powerx.io; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; @RestController
public class ProductController { @Autowired
private ProductServiceImpl productServiceImpl; @GetMapping("/find")
public Object find(@RequestParam String name ,@RequestParam Double price) {
return productServiceImpl.findByConditions2(name, price);
}
}
实体类:
package powerx.io.bean; import java.io.Serializable; import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id; @Entity
public class Product implements Serializable{ private static final long serialVersionUID = 5800591455207338888L; @Id
@GeneratedValue
private Integer id; private String name; private Double price; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Double getPrice() {
return price;
} public void setPrice(Double price) {
this.price = price;
} }
使用springboot构建项目,pom.xml 和application.yml如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!-- 连接mysql数据库驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency> <!-- 整合jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
spring:
datasource:
url: jdbc:mysql://localhost:3306/springdatajpa
username: root
password: root
jpa:
show-sql: true
hibernate:
ddl-auto: update
启动项目,会根据实体类自动创建对应的表,加入测试数据,访问http://localhost:8080/find?name=apple&price=88,结果如下:

参考文章:https://www.jianshu.com/p/0939cec7e207
springboot整合spring data jpa 动态查询的更多相关文章
- springboot整合spring Data JPA
今天敲代码,一连串的错误,我也是服气~果然,我们不是在出bug,就是在找bug的路上…… 今天完成的是springboot整合spring data JPA ,出了一连串的错,真是头大 java.sq ...
- springboot集成Spring Data JPA数据查询
1.JPA介绍 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据.它的出现主要是为 ...
- spring data jpa 动态查询(工具类封装)
利用JPA的Specification<T>接口和元模型就实现动态查询了.但是这样每一个需要动态查询的地方都需要写一个这样类似的findByConditions方法,小型项目还好,大型项目 ...
- Spring Data JPA动态查询(多条件and)
entity: @Entity @Table(name = "data_illustration") public class Test { @Id @GenericGenerat ...
- spring-boot (三) spring data jpa
学习文章来自:http://www.ityouknow.com/spring-boot.html spring data jpa介绍 首先了解JPA是什么? JPA(Java Persistence ...
- spring data jpa 分页查询
https://www.cnblogs.com/hdwang/p/7843405.html spring data jpa 分页查询 法一(本地sql查询,注意表名啥的都用数据库中的名称,适用于特 ...
- Spring Boot 整合Spring Data JPA
Spring Boot整合Spring Data JPA 1)加入依赖 <dependency> <groupId>org.springframework.boot</g ...
- Spring Boot从入门到精通(九)整合Spring Data JPA应用框架
JPA是什么? JPA全称Java Persistence API,是Sun官方提出的Java持久化规范.是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中. ...
- Spring Boot 入门系列(二十七)使用Spring Data JPA 自定义查询如此简单,完全不需要写SQL!
前面讲了Spring Boot 整合Spring Boot JPA,实现JPA 的增.删.改.查的功能.JPA使用非常简单,只需继承JpaRepository ,无需任何数据访问层和sql语句即可实现 ...
随机推荐
- MATLAB搬移到别的电脑出现License Manager Error -9
是注册码的问题,不需要重装,主要是以前的安装包不见了.解决办法: 下一个KeyGen的MLMCrypt.exe文件.运行之后在当前目录下出现一个LICENSE.DAT文件. 复制到matlab.exe ...
- ACM 超级楼梯 发工资
超级楼梯 有一楼梯共M级,刚开始时你在第一级,若每次只能跨上一级或二级,要走上第M级,共有多少种走法? Input 输入数据首先包含一个整数N,表示测试实例的个数,然后是N行数据,每行包含一个整数M( ...
- 【小梅哥SOPC学习笔记】NIOS II工程目录改变时project无法编译问题
解决NIOS II工程移动在磁盘上位置后project无法编译问题 说明:本文档于2017年3月4日由小梅哥更新部分内容,主要是增加了讲解以Quartus II13.0为代表的经典版本和以15.1为代 ...
- RDD介绍与执行
repartition 增加或减少分区.会产生shuffle.(多个分区分到一个分区不会产生shuffle) coalesce coalesce常用来减少分区,第二个参数是减少分区的过程中是否产生sh ...
- 你不知道的Console
1.凡人视角 打印字符串 代码: console.log("I am a 凡人"); 打印提示消息 代码: console.info("Yes, you arm a 凡人 ...
- memcached整理の实践
对于memcached使用内存来存取数据,一般情况下,速度比直接从数据库或者文件系统存取要快,memcached最常用的场景是利用其“存取快”来保护数据库,防止高频率存取数据库. 缓存数据库查询结果 ...
- Java反射api详解
虽然已经用了很多反射相关的api,但是还没有详细研究官方api文档,下面以1.6为基础研究一下api文档(因为只找到了1.6的中文版...),同时补充1.7和1.8对反射相关api的改变.
- ibatis 参数之 String
<select id="query_cust_name" resultClass="_custForm" parameterClass="Str ...
- C# Winform 使用Application.Exit重新启动应用程序example
Application.Exit会在所有前台线程退出后,退出应用, Environment.Exit则立即终止进程,相比之下Environment.Exit更狠些 private static voi ...
- 13种PDF转图片的案列
Acrobat.dllc#PDFPDFRender4NET.dllpdf转图片 GitHub Clone Adress : https://github.com/stone0090/OfficeToo ...