软件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. css单行排版

    text-overflow: ellipsis; overflow: hidden; white-space: nowrap;

  2. mysql中对应oracle中的to_char()和to_number()函数

    TO_CHAR(): CAST(123   AS   CHAR(3)) TO_NUMBER(): cast( '123 '   as   SIGNED   INTEGER)

  3. 关于后台传来的json是含英文字母的string

    最近帮朋友写东西,遇上一个比较坑的后台,传来的json是字符串,并且还伴有英文字符,类似 callback({xxx:xxx,xxx:xxx}),我打印了一下后台传来的数据格式,发现时string,所 ...

  4. php5.4新特性实践

    本机安装的是wampserver2.2e-php5.4.3-httpd2.2.22-mysql5.5.24-32b.exe集成包 自带了php5.4 1. 数组写法 定义一个数组 过去: $arr = ...

  5. 移动端之touch事件--手指的滑动事件

    转自[B5教程网]:http://www.bcty365.com/content-142-5243-1.html 总结:touchmove的最后坐标减去touchstart的起始坐标.X的结果如果正数 ...

  6. ASIHttprequest 报错

    (void)requestReceivedResponseHeaders:(NSMutableDictionary *)newResponseHeaders { if ([self error] || ...

  7. UI通过UISlider编写游戏第六感

    #import "RootViewController.h" @interface RootViewController (){    UILabel *scoreLabel; } ...

  8. Linux中的判断式

    格式一:test [参数] 判断内容格式二:[ [参数] 判断内容 ] 说明: a.格式二可以认为是格式一的缩写 b.格式二里中括号和内容之间要有空格 基于文件的判断-d 判断文件是否存在,并且是目录 ...

  9. mysql学习笔记—常用sql函数

    SQL 拥有很多可用于计数和计算的内建函数. SQL Aggregate 函数 SQL Aggregate 函数计算从列中取得的值,返回一个单一的值. 有用的 Aggregate 函数: AVG() ...

  10. LeetCode-11-6

    1.  Two Sum Given an array of integers, return indices of the two numbers such that they add up to a ...