Spring Boot Jpa之构建动态SQL查询语句
2018-04-20 17:58
751 查看
Spring Boot Jpa之构建动态SQL查询语句
概念
创建使用Java Persistence API的存储库是一个繁琐的过程,需要大量时间并需要大量样板代码。一种推荐的方式是使用元
1.JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。,而Hibernate是它的一种实现。除了Hibernate,还有EclipseLink(曾经的toplink),OpenJPA等可供选择,所以使用Jpa的一个好处是,可以更换实现而不必改动太多代码。2.Hibernate作为JPA的一种实现,jpa的注解已经是hibernate的核心,hibernate只提供了一些补充,而不是两套注解。hibernate对jpa的支持够足量,在使用hibernate注解建议使用jpa。
使用criteria 查询简单Demo
1.实体类
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.annotation.JSONField; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.hibernate.annotations.DynamicInsert; import org.hibernate.annotations.DynamicUpdate; import org.hibernate.annotations.GenericGenerator; import javax.persistence.*; import java.util.Date; /** * 学生 实体类 * @jason.zhong */ @Entity @DynamicUpdate(true) @DynamicInsert(true) @Table(name="student") @JsonIgnoreProperties(value={"hibernateLazyInitializer", "handler"}) public class StudentVo { /** * 主键 */ @Id @GenericGenerator(name = "uuidGenerator", strategy = "org.hibernate.id.UUIDGenerator") // 唯一性不受进程重启,机器重启等影响UUID生成方式 @GeneratedValue(generator = "uuidGenerator") // 使用上面定义的uuidGenerator作为主键生成器 @Column(name = "id", columnDefinition="CHAR(36)", unique = true, nullable = false, insertable = false, updatable = false) private String id; /** * 创建时间 */ @Column(name = "created_at", columnDefinition="DATETIME", nullable = false, updatable = false) @JSONField(format="yyyy-MM-dd HH:mm:ss") private Date createdAt; /** * 修改时间 */ @Column(name = "updated_at", columnDefinition="DATETIME") @JSONField(format="yyyy-MM-dd HH:mm:ss") private Date updatedAt; /** * 学号 */ @Column(name = "student_no", columnDefinition="INTEGER(10) UNSIGNED") private Integer studentNo; /** * 姓名 */ @Column(name="name", columnDefinition="VARCHAR(50)") private String name; /** * 性别 */ @Column(name="sex", columnDefinition="TINYINT(1) UNSIGNED") private Short sex; /** * 年龄 */ @Column(name = "age", columnDefinition="INTEGER(3) UNSIGNED") private Integer age; @Override public String toString() { return JSON.toJSONString(this); } public String getId() { return id; } public void setId(String id) { this.id = id; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } public Date getUpdatedAt() { return updatedAt; } public void setUpdatedAt(Date updatedAt) { this.updatedAt = updatedAt; } public Integer getStudentNo() { return studentNo; } public void setStudentNo(Integer studentNo) { this.studentNo = studentNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Short getSex() { return sex; } public void setSex(Short sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
2.服务
import java.util.List; /** * 学生 服务 * @jason.zhong */ public interface StudentService { /** * 获取学生信息 * @param student * @return */ List<StudentVo> getAllStudent(StudentVo student); }
3.实现类
import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import java.util.ArrayList; import java.util.List; /** * 学生 实现类 * @jason.zhong */ @Service public class StudentServiceImpl implements StudentService { /** * entityManager */ @Autowired private EntityManager entityManager; /** * 安全查询创建工厂 */ private CriteriaBuilder cb = null; /** * 安全查询主语句 */ private CriteriaQuery<StudentVo> criteriaQuery = null; /** * Root 定义查询的From子句中能出现的类型 */ private Root<StudentVo> register = null; public StudentServiceImpl(EntityManager entityManager) { this.entityManager = entityManager; this.cb = this.entityManager.getCriteriaBuilder(); this.criteriaQuery = this.cb.createQuery(StudentVo.class); this.register = this.criteriaQuery.from(StudentVo.class); } @Override public List<StudentVo> getAllStudent(StudentVo student) { this.criteriaQuery.where(this.getPredicates(student)); TypedQuery<StudentVo> typedQuery = this.entityManager.createQuery(this.criteriaQuery); List<StudentVo> result = typedQuery.getResultList(); return result; } /** * 设置过滤条件 * @param student * @return */ private Predicate[] getPredicates(StudentVo student) { List<Predicate> predicate=new ArrayList<Predicate>(); //学号 if (student.getStudentNo() != null) { predicate.add(this.cb.equal(this.register.<Integer> get("studentNo"), student.getStudentNo())); } //姓名 if (StringUtils.isNotBlank(student.getName())) { predicate.add(this.cb.like(this.register.<String> get("name"), '%' + student.getName()+ '%')); } //性别 if (student.getSex() != null) { predicate.add(this.cb.equal(this.register.<Integer> get("sex"), student.getSex())); } //年龄 if (student.getAge() != null) { predicate.add(this.cb.le(this.register.<Integer> get("age"), student.getAge())); } return predicate.toArray(new Predicate[0]); } }
构建CriteriaQuery 实例API说明
1.CriteriaBuilder 安全查询创建工厂,创建CriteriaQuery,创建查询具体具体条件Predicate 等.
CriteriaBuilder是一个工厂对象,安全查询的开始.用于构建JPA安全查询.可以从EntityManager 或 EntityManagerFactory类中获得CriteriaBuilder.
例如:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
2.CriteriaQuery 安全查询主语句
[p]CriteriaQuery对象必须在实体类型或嵌入式类型上的Criteria 查询上起作用。它通过调用 CriteriaBuilder, createQuery 或CriteriaBuilder.createTupleQuery 获得。
CriteriaBuilder就像CriteriaQuery 的工厂一样。
CriteriaBuilder工厂类是调用EntityManager.getCriteriaBuilder 或 EntityManagerFactory.getCriteriaBuilder而得。
StudentVo实体的 CriteriaQuery 对象以下面的方式创建:
例如:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<StudentVo> criteriaQuery = cb.createQuery(StudentVo.class);
3.Root 定义查询的From子句中能出现的类型
AbstractQuery是CriteriaQuery 接口的父类。它提供得到查询根的方法。Criteria查询的查询根定义了实体类型,能为将来导航获得想要的结果,它与SQL查询中的FROM子句类似。
Root实例也是类型化的,且定义了查询的FROM子句中能够出现的类型。
查询根实例能通过传入一个实体类型给 AbstractQuery.from方法获得。
Criteria查询,可以有多个查询根。
StudentVo实体的查询根对象可以用以下的语法获得 :
例如:
Root<StudentVo> register = criteriaQuery.from(StudentVo.class);
4.Predicate 过滤条件
过滤条件应用到SQL语句的FROM子句中。在criteria 查询中,查询条件通过Predicate 或Expression 实例应用到CriteriaQuery 对象上。
这些条件使用 CriteriaQuery .where 方法应用到CriteriaQuery 对象上。
CriteriaBuilder 也是作为Predicate 实例的工厂,Predicate 对象通过调用CriteriaBuilder 的条件方法( equal,notEqual, gt, ge,lt, le,between,like等)创建。
Predicate 实例也可以用Expression 实例的 isNull, isNotNull 和 in方法获得,复合的Predicate 语句可以使用CriteriaBuilder的and, or andnot 方法构建。
下面的代码片段展示了Predicate 实例查询学号为10010303的学生实例:[/p]例如:
Predicate predicate = cb.equal(register.<Integer> get("studentNo"), 10010303); criteriaQuery.where(predicate);
5.排序结果
Criteria查询的结果能调用CriteriaQuery.orderBy方法排序,该方法接收一个Order对象做为参数。通过调用 CriteriaBuilder.asc 或 CriteriaBuilder.Desc,Order对象能被创建。以下代码片段中,StudentVo实例是基于name的升序排列。criteriaQuery.orderBy(cb.asc(register.<String> get("name")));
6.分页
Criteria查询的结果能调用typedQuery.setFirstResult(int).setMaxResults(int)方法来进行分页,setFirstResult设置开始位置(下标从0开始),setMaxResults设置每页显示条数。TypedQuery<StudentVo> typedQuery = entityManager.createQuery(criteriaQuery); typedQuery.setFirstResult(0).setMaxResults(10);
相关文章推荐
- Spring Boot Jpa之构建动态SQL查询语句
- 基于Spring Boot,使用JPA动态调用Sql查询数据
- springboot jpa hibernate 实现动态查询
- springboot jpa hibernate 实现动态查询
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
- springboot学习笔记一: service层获取调用dao层查询接口,获取到的bean为空,但是用sql语句去查数据库却有数据
- 使用spring-boot-starter-data-jpa 怎么配置使运行时输出SQL语句
- Springboot中对jpa动态查询条件的封装
- Spring boot data JPA 自定义JPQL语句,以及PagingAndSortingRepository接口实现分页查询
- Spring data JPA中使用Specifications动态构建查询
- springboot整合spring data jpa 动态查询
- Spring data JPA中使用Specifications动态构建查询
- SpringBoot中使用Spring Data Jpa 实现简单的动态查询的两种方法
- Springboot整合JPA以及动态条件查询的实现
- springboot jpa hibernate 实现动态查询
- 使用spring-boot-starter-data-jpa 怎么配置使运行时输出SQL语句
- 使用spring-boot-starter-data-jpa 怎么配置使运行时输出SQL语句
- Spring data JPA使用Specification实现动态查询例子
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(三)构建后端
- Spring Boot+JPA+Mysql+ThymeLeaf快速构建CURD系统(一)Spring Boot介绍