软件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. mixin 在传参中可以出现 参数 在类内部可以定义 作用域

    mixin 在传参中可以出现 参数  在类内部可以定义

  2. <..................> 哈佛大学哲学系 && 历史哲学笔记文献集

    哈佛大学哲学系课程表            (一)概况    (1)哈佛大学哲学系现有教师21人,其中访问教授7人,教师流动性较大,每年有一定的变化.以下为现任教师:Richard Moran(系主任 ...

  3. [NOIP2018TG]赛道修建

    [NOIP2018TG]赛道修建 考场上multiset调不出啊啊啊!!! 首先肯定是二分答案 做树形dp,f[i]表示i点的子树两两匹配后剩下的最长长度 匹配可以用multiset维护 但是菊花图跑 ...

  4. 修改mysql root的密码

    use mysql:update user set Password = Password('newPwd') where user='root';//更改root用户的密码flush privile ...

  5. 201703 ABAP面试题002

    转自: ABAP 面试问题及答案(一):数据库更新及更改 SAP Standard (转) 问题一:锁对象(Lock Object)和 FM(Function Module)激活锁定对象时,产生的 F ...

  6. ansible的主机变量

    ansible的主机变量(常用):ansible_ssh_host     #用于指定被管理的主机的真实IPansible_ssh_port     #用于指定连接到被管理主机的ssh端口号,默认是2 ...

  7. C# 函数3

    //获取部分     public class GF_GET     {         /// <summary>         /// 根据坐标点获取屏幕图像         /// ...

  8. hadoop学习第二天-了解HDFS的基本概念&&分布式集群的搭建&&HDFS基本命令的使用

    一.HDFS的相关基本概念 1.数据块 1.在HDFS中,文件诶切分成固定大小的数据块,默认大小为64MB(hadoop2.x以后是128M),也可以自己配置. 2.为何数据块如此大,因为数据传输时间 ...

  9. iOS UIWebView键盘处理

    让UIWebView弹出键盘上的按钮显示中文    http://www.cr173.com/html/19440_1.html 如果你有下面的问题,此文也许会帮到你. 键盘遮盖了UIWebView. ...

  10. junit在idea中的使用(1)--理论篇

     感觉本文前部分配置太过繁琐,大家可以参考我的这篇文章http://www.cnblogs.com/SuMeng/p/8279879.html(junit在IDEA中使用--实践篇),用添加maven ...