概述

ORM映射为我们带来便利的同时,也失去了较大灵活性,如果SQL较复杂,要进行动态查询,那必定是一件头疼的事情(也可能是lz还没发现好的方法),记录下自己用的三种复杂查询方式。

环境

springBoot

IDEA2017.3.4

JDK8

pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

org.springframework.boot

spring-boot-starter-parent

2.1.6.RELEASE

com.xmlxy

seasgame

0.0.1-SNAPSHOT

seasgame

Demo project for Spring Boot

1.8

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.springframework.boot

spring-boot-starter-data-jpa

mysql

mysql-connector-java

runtime

org.springframework.boot

spring-boot-devtools

runtime

true

org.projectlombok

lombok

true

org.springframework.boot

spring-boot-starter-data-jpa

io.springfox

springfox-swagger2

2.8.0

io.springfox

springfox-swagger-ui

2.8.0

org.springframework.boot

spring-boot-configuration-processor

true

org.springframework.boot

spring-boot-starter-security

net.sf.json-lib

json-lib

2.2.2

jdk15

com.belerweb

pinyin4j

2.5.1

org.springframework.boot

spring-boot-starter-thymeleaf

javax.servlet

javax.servlet-api

3.1.0

provided

war

org.springframework.boot

spring-boot-maven-plugin

org.apache.maven.plugins

maven-compiler-plugin

1.8

1.8

seasgame

org.apache.maven.plugins

maven-compiler-plugin

2.3.2

${project.build.sourceEncoding}

1.7

1.7

org.apache.maven.plugins

maven-surefire-plugin

true

@Query

当一个SQL较为复杂时,第一个想到的就是原生的SQL语句。如果只是简单的查询,那情况还没这么糟糕

@Query(value = " SELECT IFNULL(sum(right_num),0) sumRight FROM t_record WHERE record_owner_id = ?1 AND responder_no = ?2 ",nativeQuery = true)

Map sumRightNum(int studentId,int responderNo);

但如果需要进行动态查询,或更改,那这个value就变得复杂了。

package com.xmlxy.seasgame.dao;

import com.xmlxy.seasgame.entity.ScoreEntity;

import org.springframework.data.jpa.repository.Modifying;

import org.springframework.data.jpa.repository.Query;

import org.springframework.data.repository.CrudRepository;

import org.springframework.data.repository.query.Param;

import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**

*

* Description:

* @author hwc

* @date 2019/9/5

* @return

*/

public interface ScoreDao extends CrudRepository

{

/**

*

* Description:

*@param scoreEntity

* @author hwc

* @date 2019/9/6

*/

@Transactional(rollbackFor = Exception.class)

@Modifying

@Query(value = "UPDATE t_score t SET " +

"t.responder_no = CASE WHEN :#{#scoreEntity.responderNo} IS NULL THEN t.responder_no ELSE :#{#scoreEntity.responderNo} END," +

"t.max_level = CASE WHEN :#{#scoreEntity.maxLevel} IS NULL THEN t.max_level ELSE :#{#scoreEntity.maxLevel} END," +

"t.right_num = CASE WHEN :#{#scoreEntity.rightNum} IS NULL THEN t.right_num ELSE :#{#scoreEntity.rightNum} END," +

"t.use_time = CASE WHEN :#{#scoreEntity.userTime} IS NULL THEN t.use_time ELSE :#{#scoreEntity.userTime} END WHERE student_id = :#{#scoreEntity.getStudentId()}",nativeQuery = true)

void updateScore(@Param("scoreEntity") ScoreEntity scoreEntity);

}

JPQL

如果Java代码内发出JPQL查询,就需要利用到EntityManager的响应方法了。一般执行以下流程

获取一个EntityManager实例

调用实例的方法createQuery,创建一个Query实例,如果有需要可以指定检索的最大数量和起始位置

使用Query方法getResultList执行查询,当然更新和删除操作得使用executeUpdate执行

进行一个复杂的动态SQL查询

public Page getScoreByRank(int gradeId,int classId,Pageable pageable)

{

StringBuilder countSelectSql = new StringBuilder("");

countSelectSql.append(" SELECT COUNT(*) ");

countSelectSql.append(" FROM ");

countSelectSql.append(" t_score s, ");

countSelectSql.append(" t_student st ");

countSelectSql.append(" WHERE ");

countSelectSql.append(" s.student_id = st.student_id ");

StringBuilder selectSql = new StringBuilder();

selectSql.append(" SELECT s.student_id,st.real_name,st.student_class,s.max_level,s.use_time,s.right_num ");

selectSql.append(" FROM t_score s ");

selectSql.append(" JOIN t_student st ON s.student_id = st.student_id ");

selectSql.append(" WHERE 1 = 1 ");

Map params = new HashMap<>();

StringBuilder whereSql = new StringBuilder();

if (gradeId != -1)

{

whereSql.append(" AND st.student_grade = :student_grade ");

params.put("student_grade",gradeId);

}

/**班级ID*/

if (classId != -1)

{

whereSql.append(" AND st.student_class = :classId ");

params.put("classId",classId);

}

String orderSql = " ORDER BY s.max_level DESC,s.use_time,s.right_num ASC ";

String countSql = new StringBuilder().append(countSelectSql).append(whereSql).toString();

Query countQuery = entityManager.createNativeQuery(countSql);

for (Map.Entry entry : params.entrySet())

{

countQuery.setParameter(entry.getKey(),entry.getValue());

}

BigInteger totalCount = (BigInteger)countQuery.getSingleResult();

String querySql = new StringBuilder().append(selectSql).append(whereSql).append(orderSql).toString();

Query query = entityManager.createNativeQuery(querySql,RankEntity.class);

for (Map.Entry entry:params.entrySet())

{

query.setParameter(entry.getKey(),entry.getValue());

}

query.setFirstResult((int) pageable.getOffset());

query.setMaxResults(pageable.getPageSize());

List rankEntities = query.getResultList();

Page page = new PageImpl<>(rankEntities,pageable,totalCount.longValue());

return page;

}

注意:如果没有重新定义Pageable那么pageNumber必须减1,因为是从0开始的。

Criteria

这是一种规范查询是以元模型的概念为基础的,这个元模型可以是实体累,嵌入类,或者映射的父类,简单介绍几个里面用到接口。

CriteraQuery是一个特定的顶层查询对象,里面包含select,from,where,order by等各个部分,然而他只对实体类或嵌入类的标准查询起作用。

Root标准查询的根对象,根定义了实体类型,是你想要查询要获得的结果,也可以添加查询条件,结合实体管理对象得到查询的对象。

CriteriaBuilder接口用来构建CritiaQuery的构建器

StudentEntity类

package com.xmlxy.seasgame.entity;

import io.swagger.annotations.ApiModel;

import lombok.Data;

import javax.persistence.*;

import javax.print.attribute.standard.MediaSize;

import java.io.Serializable;

/**

*

* Description:学生对象

* @param

* @author hwc

* @date 2019/8/8

*/

@Entity

@Table(name = "t_base_student")

@ApiModel

@Data

public class StudentEntity implements Serializable

{

private static final long serialVersionUID = 546L;

@Id

@GeneratedValue(strategy = GenerationType.AUTO)

@Column(name = "student_id")

private Integer studentId;

@Column(name = "student_grade")

private Integer studentGrade;

@Column(name = "student_class")

private Integer studentClass;

@Column(name = "address")

private String address;

@Column(name = "telephone")

private Integer telephone;

@Column(name = "real_name")

private String realName;

@Column(name = "id_number")

private String idNumber;

@Column(name = "study_id")

private String studyId;

@Column(name = "is_delete")

private int isDelete;

@Column(name = "uuid")

private String uuid;

}

dao层

public interface StudentDao extends JpaRepository,JpaSpecificationExecutor

{

}

动态查询

public Page getTeacherClassStudent(int pageNumber,int pageSize,int gradeId, int classId,String keyword)

{

pageNumber = pageNumber < 0 ? 0 : pageNumber;

pageSize = pageSize < 0 ? 10 : pageSize;

Specification specification = new Specification()

{

@Override

public Predicate toPredicate(Root root, CriteriaQuery> criteriaQuery, CriteriaBuilder criteriaBuilder)

{

//page : 0 开始, limit : 默认为 10

List predicates = new ArrayList<>();

predicates.add(criteriaBuilder.equal(root.get("studentGrade"),gradeId));

predicates.add(criteriaBuilder.equal(root.get("studentClass"),classId));

if (!Constant.isEmptyString(keyword))

{

predicates.add(criteriaBuilder.like(root.get("realName").as(String.class),"%" + keyword + "%"));

}

return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));

}

};

/*studentId必须是实体类属性与数据库对应,否则报ropertyReferenceException异常*/

PageRequest page = new PageRequest(pageNumber,pageSize,Sort.Direction.ASC,"studentId");

Page pages = studentDao.findAll(specification,page);

return pages;

}

因为这个项目应用比较简单,所以条件只有一个,如果条件较多,甚至可以定义一个专门的类去接收拼接参数,然后判

断,成立就add进去。

总结

以上所述是小编给大家介绍的JPA多条件复杂SQL动态分页查询功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

jpa mysql sql分页查询语句_JPA多条件复杂SQL动态分页查询功能相关推荐

  1. mysql 查询语句_MySQL相关(一)- 一条查询语句是如何执行的

    前言 学习一个新知识最好的方式就是上官网,所以我先把官网贴出来 MySQL官网 (点击查阅),如果大家有想了解我没有说到的东西可以直接上官网看哈~目前 MySQL 最新大版本为8.0,但是鉴于目前应用 ...

  2. 检索数据_8_查询语句里执行条件判断

    查询语句里执行条件判断 需求描述 需求:查询雇员表emp里的员工名称.工资.工资分类状态.这里的工资分类状态按照以下规则显示:如果工资小于等于2000则显示UNDERPAID(即报酬比较低的),如果工 ...

  3. java中动态查询条件,Java实现动态添加查询条件

    今天遇到一个问题,就是需要根据前端页面发送的条件查询数据库记录,但是前端发送的条件是不确定的.如果使用mybatis的xml方法可以使用if标签灵活的添加判断条件,但是现在我使用的就是单纯的sql. ...

  4. mysql 查询语句属性值_MySQL学习——SQL查询语句(一)

    查询数据是指从数据库中获取所需要的数据,查询数据是数据库操作中最常用也是最重要的操作,用户可以根据对数据的需求,使用不同的查询方式,通过不同的查询方式可以获得不同的数据,在MySQL中使用select ...

  5. mysql 子表 关联查询语句_MySQL-基本查询语句及方法,连表和子查询

    一.基本查询语句 create table emp( id intnotnull unique auto_increment, name varchar(20) notnull, sex enum(' ...

  6. mysql分组查询学生平均年龄_8.21MySQL(四)基本查询语句及方法、连表、子查询...

    一.基本查询语句及方法 sql语句书写顺序 select id,name from emp where id > 3 and id < 6; sql语句执行顺序 from  # 确定到底是 ...

  7. jpa mysql sql分页查询语句_jpa 中 Query 的分页查询和更新

    1,查询分页 注意这个地方nativeQuery=true 代表的是可执行原生sql 先查询出来所有的数据,然后再差个总条数 返回page @Query(nativeQuery = true, val ...

  8. java access 分页查询语句,爱不释手—几条常见的数据库分页之SQL语句代码

    我们在编写MIS系统和Web应用程序等系统时,都涉及到与数据库的交互,如果数据库中数据量很大的话,一次检索所有的记录,会占用系统很大的资源,因此我们常常采用,需要多少数据就只从数据库中取多少条记录,即 ...

  9. mysql分库分表分页查询语句_MySQL分库分表分库后的查询(8th)

    前言 这边我们以使用python程序要展示一下再分库分表后,我们需要如何对数据库进行操作. python操作数据库 我们这边还是沿用之前的那5中:场景1:购买者下订单#!/usr/bin/env py ...

最新文章

  1. 安装Oralce时,系统参数详解
  2. windows安装TensorFlow和Keras遇到的问题及其解决方法
  3. 真·机械朋克!物理学家用扬声器搭建神经网络,登上今日Nature
  4. Flex DataGrid可编辑对象实现Enter跳转
  5. Linux下Openssl的安装全过程
  6. 怎么时装linux可用空间变大,[合集]OpenSUSE安装octave时装1G多texliv - 精华区 - 优秀的Free OS(Linux)版 - 北大未名BBS...
  7. motorola 企业移动解决方案
  8. java学习:理解final
  9. 机器学习中的Bias,Error,Variance的区别
  10. 【渝粤教育】电大中专计算机职业素养 (6)作业 题库
  11. PB与各种数据库连接
  12. mysql relay log参数汇总
  13. LINUX删除指定子目录下所有指定文件名
  14. DSP28335看门狗复位
  15. 20HTML5期末大作业:影视视频网站设计——爱影评在线电影(10页面) HTML+CSS+JavaScript 学生DW网页设计作业成品 web课程设计网页规划与设计 计算机毕设网页设计源码
  16. 使用pycharm编写python爬虫时出现乱码的解决方案UnicodeEncodeError: ‘gbk‘ codec can‘t encode character ‘\U0001f601‘ in
  17. 渗透测试的介绍和防范
  18. 牛逼!java程序员必看经典书单,以及各个阶段学习建议!
  19. C盘全面清理教程,彻底清理所有垃圾
  20. Android 百度地图 SDK v3.0.0 (四) 引入离线地图功能

热门文章

  1. std::map只修改不用加锁
  2. opencv undefined reference to symbol '_ZN2c...异常
  3. 人工操作阶段计算机是如何工作的,第一章计算机基础概述全解.ppt
  4. linux判断网卡是否挂载,检查网卡是否加载 - Linux服务器网卡驱动安装及故障排除_服务器应用_Linux公社-Linux系统门户网站...
  5. mysql makefile_编译安装mysql,找不到makefile
  6. 推荐一款IDE开发工具插件GitToolBox
  7. Selenium之XPATH轴定位(第三篇)
  8. CentOS6.3环境下openresty安装drizzle模块
  9. 使用xdebug+wincachegrind的心得
  10. java接口返回值_java后台调用接口并返回值