软件152 尹以操

首先谢谢大佬的简书文章:http://www.jianshu.com/p/45ad65690e33#

这篇文章中讲的是spring中使用spring data jpa,使用了xml配置文件。我现在使用的是spring boot ,没有了xml文件配置就方便多了。我同样尝试了两种方式,也都是简单的查询,需要更复杂的查询,还需要我研究研究。往下看,需要先配置springboot的开发环境,需要大致了解springboot,这里可以看下面两篇文章:

springboot 项目新建

springboot使用小记

创建实体类:

package com.entity;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table; /**
*create by yyc 2017年6月11日上午9:59:59
*/
@Entity
@Table(name="test_user")
public class TestUser { @Id
@GeneratedValue
private int userId;
private Integer userAge;
private String userName;
private Integer high;//高
//省略getter、setter }

为了测试,先创建一个简单的实体类。

写元数据模型:

Criteria API

这套API可用于构建对数据库的查询。

类型安全。通过定义元数据模型,在程序编译阶段就可以对类型进行检查,不像SQL需要与Mysql进行交互后才能发现类型问题。

如下即为元数据模型。创建一个元模型类,类名最后一个字符为下划线,内部的成员变量与UserInfo.class这个实体类的属性值相对应。

package com.entity;

import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;
import com.TestUser;
@StaticMetamodel(TestUser.class)
public class TestUser_ { public static volatile SingularAttribute<TestUser, Integer> userId;// 用户ID,自增量
public static volatile SingularAttribute<TestUser, Integer> userAge;
public static volatile SingularAttribute<TestUser, String> userName;
public static volatile SingularAttribute<TestUser, Integer> high; }

可移植。API并不依赖具体的数据库,可以根据数据库类型的不同生成对应数据库类型的SQL,所以其为可移植的。
面向对象。Criteria API是使用的是各种类和对象如CriteriaQuery、Predicate等构建查询,是面向对象的。而如果直接书写SQL则相对于面向的是字符串。

现在开始SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方式方法

第一种方式:通过JPA的Criteria API实现

  1. EntityManager获取CriteriaBuilder
  2. CriteriaBuilder创建CriteriaQuery
  3. CriteriaQuery指定要查询的表,得到Root<UserInfo>,Root代表要查询的表
  4. CriteriaBuilder创建条件Predicate,Predicate相对于SQL的where条件,多个Predicate可以进行与、或操作。
  5. 通过EntityManager创建TypedQuery
  6. TypedQuery执行查询,返回结果
package com.repository;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.entity.TestUser;
import com.entity.TestUser_; /**
*create by yyc 2017年6月11日下午9:08:39
*/
@Repository
public class TestUserExtendDao { // @Autowired
@PersistenceContext//@Autowired和@PersistenceContext注解任取一
EntityManager em; @SuppressWarnings("unused")
public List<TestUser> getTestUserInfo(final Integer age, final String name, final Integer high){
//
CriteriaBuilder cb = em.getCriteriaBuilder();
//
CriteriaQuery<TestUser> query = cb.createQuery(TestUser.class); //3
//from
Root<TestUser> root = query.from(TestUser.class); //4
//where
Predicate p1 = null;
if (age != 0) {
System.out.println("正在操作age!!!");
Predicate p2 = cb.equal(root.get(TestUser_.userAge), age);
if (p1 != null) {
p1=cb.and(p1, p2);
} else {
p1 = p2;
}
}
if (false==name.isEmpty()) {
System.out.println("正在操作name!!!");
Predicate p2 = cb.equal(root.get(TestUser_.userName), name);
if (p1 != null) {
p1=cb.and(p1, p2);
} else {
p1 = p2;
}
}
if (high != 0) {
System.out.println("正在操作high!!!");
Predicate p2 = cb.equal(root.get(TestUser_.high), high);
if (p1 != null) {
p1=cb.and(p1, p2);
} else {
p1 = p2;
}
}
//
query.where(p1);
//
List<TestUser> testUsers = em.createQuery(query).getResultList();
return testUsers;
}
}

第二种方式:DAO层接口实现JpaSpecificationExecutor<T>接口

  JpaSpecificationExecutor如下,方法参数Specification接口有一个方法toPredicate,返回值正好是Criteria API中的Predicate,而Predicate相对于SQL的where条件。与上一个方法相比,这种写法不需要指定查询的表是哪一张,也不需要自己通过Criteria API实现排序和分页,只需要通过新建Pageable、Sort对象并传参给findAll方法即可,简便一些。

这是JpaSpecificationExecutor接口中的方法:

public interface JpaSpecificationExecutor<T> {
  T findOne(Specification<T> spec);
  List<T> findAll(Specification<T> spec);
  Page<T> findAll(Specification<T> spec, Pageable pageable);
  List<T> findAll(Specification<T> spec, Sort sort);
  long count(Specification<T> spec);
}

TestRepository继承JpaSpecificationExecutor接口:

package com.repository;

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.entity.TestUser; /**
*create by yyc 2017年6月11日上午9:36:27
*测试动态sql
*/
public interface TestRepository extends PagingAndSortingRepository<TestUser, Integer>, JpaSpecificationExecutor<TestUser>{ }

实现Specification:

package com.entity;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;
import com.entity.TestUser; /**
* create by yyc 2017年6月11日上午10:17:44
*/
public class TestUserDaoSpec {
public static Specification<TestUser> getSpec(final Integer age, final String name, final Integer high) {
return new Specification<TestUser>() { @SuppressWarnings("unused")
@Override
public Predicate toPredicate(Root<TestUser> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate p1 = null;
if (age != 0) {
System.out.println("正在操作age!!!");
Predicate p2 = cb.equal(root.get(TestUser_.userAge), age);
if (p1 != null) {
p1=cb.and(p1, p2);
} else {
p1 = p2;
}
}
if (false==name.isEmpty()) {
System.out.println("正在操作name!!!");
Predicate p2 = cb.equal(root.get(TestUser_.userName), name);
if (p1 != null) {
p1=cb.and(p1, p2);
} else {
p1 = p2;
}
}
if (high != 0) {
System.out.println("正在操作high!!!");
Predicate p2 = cb.equal(root.get(TestUser_.high), high);
if (p1 != null) {
p1=cb.and(p1, p2);
} else {
p1 = p2;
}
}
return p1;
}
};
} }

Service层的调用测试类:

package com.service.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.entity.TestUser;
import com.entity.TestUserDaoSpec;
import com.repository.TestRepository;
import com.repository.TestUserExtendDao;
import com.result.Result;//一个方法返回的封装,这里直接忽略即可 /**
*create by yyc 2017年6月11日上午9:40:51
*/
@Service("testService")
public class TestService { @Autowired
private TestRepository testRepository; @Autowired
private TestUserExtendDao testUserExtendDao; //测试第一种方式
public Result getTestUsersByExtendDao(){
List<TestUser> list = testUserExtendDao.getTestUserInfo(20, "", 170);//通过两个条件,string设为空
printTestUserInfo(list);
return new Result("查询成功!", list);
} //测试第二种方式
public Result getTestUsersByThreeParameter(){
List<TestUser> list = testRepository.findAll(TestUserDaoSpec.getSpec(20, "yyc", 170));//通过三个条件
printTestUserInfo(list);
return new Result("查询成功!",list);
}
public Result getTestUsersByTwoParameter1(){
List<TestUser> list = testRepository.findAll(TestUserDaoSpec.getSpec(20, "yyc", 0));//通过两个条件,Integer设为0
printTestUserInfo(list);
return new Result("查询成功!",list);
} public Result getTestUsersByOneParameter(){
List<TestUser> list = testRepository.findAll(TestUserDaoSpec.getSpec(0, "lrs", 0));//通过一个条件查询
printTestUserInfo(list);
return new Result("查询成功!",list);
} private void printTestUserInfo(List<TestUser> list) {
if (list!=null) {
for (TestUser testUser : list) {
System.out.println("userId:"+testUser.getUserId()+
" userName:"+testUser.getUserName()+
" userAge:"+testUser.getUserAge()+
" userHigh:"+testUser.getHigh());
}
} }
}

再次感谢大佬们的文章:

http://www.jianshu.com/p/45ad65690e33#

http://blog.csdn.net/ie8848520/article/details/8161986

http://www.cnblogs.com/jiangxiaoyaoblog/p/5635152.html

SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法的更多相关文章

  1. Spring data jpa 实现简单动态查询的通用Specification方法

    本篇前提: SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法 这篇文章中的第二种方法 实现Specification 这块的方法 只适用于一个对象针对某一个固定字 ...

  2. springboot(五):spring data jpa的使用

    在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法以及注意事项 使用spr ...

  3. SpringBoot(五) :spring data jpa 的使用

    原文出处: 纯洁的微笑 在上篇文章springboot(二):web综合开发中简单介绍了一下spring data jpa的基础性使用,这篇文章将更加全面的介绍spring data jpa 常见用法 ...

  4. 最近项目中使用Spring data jpa 踩过的坑

    最近在做一个有关OA项目中使用spring data JPA 操作数据库,结果遇到了补个不可思议的麻烦.困惑了好久. 首先看一下问题吧,这就是当时测试“设置角色时,需要首先删除该用户已经拥有的角色时” ...

  5. SpringBoot系列之Spring Data Jpa集成教程

    SpringBoot系列之Spring Data Jpa集成教程 Spring Data Jpa是属于Spring Data的一个子项目,Spring data项目是一款集成了很多数据操作的项目,其下 ...

  6. SpringBoot入门:Spring Data JPA 和 JPA(理论)

    参考链接: Spring Data JPA - Reference Documentation Spring Data JPA--参考文档 中文版 纯洁的微笑:http://www.ityouknow ...

  7. spring data jpa 的简单使用

    先说简单一下JPA 概念:JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据. 影响 ...

  8. Hibernate中使用Spring Data JPA

    一.配置文件的方式 1.pom.xml中引入相关依赖 <properties> <project.build.sourceEncoding>UTF-8</project. ...

  9. SpringBoot总结之Spring Data Jpa

    一.Spring Data Jpa简介 JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate.TopLink等. Spring D ...

随机推荐

  1. 《从零开始学Swift》学习笔记(Day 34)——静态属性是怎么回事?

    原创文章,欢迎转载.转载请注明:关东升的博客 我先来设计一个类:有一个Account(银行账户)类,假设它有3个属性:amount(账户金额).interestRate(利率)和owner(账户名). ...

  2. Genealogical tree

    Genealogical tree Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 6032 Accepted: 3973 Spec ...

  3. FW 配置一个私有的Docker仓库

    思维 66 3月1日 发布 建分支 0 分支 收藏 0 收藏 我们在本地开发时,如果内网能部署一台Docker服务器,无疑会极大的方便镜像的分享发布,有些私有镜像就是可以直接放到内网服务器上,省去了不 ...

  4. JavaWeb 之文件上传

    1. 文件上传的要求 1.1 上传对表单的限制 method="post"; enctype="multipart/form-data"; 表单中需要添加文件表 ...

  5. 从B 树、B+ 树、B* 树谈到R 树(转)

      作者:July.weedge.Frankie.编程艺术室出品. 说明:本文从B树开始谈起,然后论述B+树.B*树,最后谈到R 树.其中B树.B+树及B*树部分由weedge完成,R 树部分由Fra ...

  6. python并发编程&多线程(一)

    本篇理论居多,实际操作见:  python并发编程&多线程(二) 一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一 ...

  7. centos7 终端修改字体大小

    如果你觉得你的终端字体太小了,停下来看一看这里可以帮你快捷修改字体大小 修改字体大小(这个是最坑爹的) 其实关键的命令就一个:setfont 但是setfont后面要跟的字体到底要写什么就的具体去查了 ...

  8. (4.6)sql server索引缺失提示

    SQLSERVER如何查看索引缺失 sql server索引缺失提示 当大家发现数据库查询性能很慢的时候,大家都会想到加索引来优化数据库查询性能, 但是面对一个复杂的SQL语句,找到一个优化的索引组合 ...

  9. Java基础—String总结

    特点 String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. String实 ...

  10. LeetCode-day04

    35. Same Tree 判断两棵树相同 36. Invert Binary Tree 翻转树 37. Symmetric Tree 判断树是不是镜像对称的 38. Maximum Depth of ...