前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >第七章:使用QueryDSL与SpringDataJPA实现子查询

第七章:使用QueryDSL与SpringDataJPA实现子查询

作者头像
恒宇少年
发布于 2018-06-27 09:32:29
发布于 2018-06-27 09:32:29
5.2K00
代码可运行
举报
运行总次数:0
代码可运行

在上一章我们讲到了QueryDSL的聚合函数,让我们重新认识了QueryDSL的便利之处,它可以很好的使用原生SQL的思想来进行Java形式的描述,编写完成也不需要考虑更换数据库存在的不兼容问题。当然QueryDSL还有很多我们没有发掘出来的核心技术,我们今天来讲解下”子查询“,看看QueryDSL是怎么完美的诠释了使用Java写SQL。

本章目标

基于SpringBoot平台完成QueryDSL整合JPA实现多表、单表子查询。

构建项目

我们使用idea工具创建一个SpringBoot项目,然后添加部分依赖并配置QueryDSL自动生成QueryBean插件,pom.xml代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yuqiyu.querydsl.sample</groupId>
    <artifactId>chapter7</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>chapter7</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--阿里巴巴数据库连接池,专为监控而生 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.26</version>
        </dependency>
        <!-- 阿里巴巴fastjson,解析json视图 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.15</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <!--<scope>provided</scope>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--queryDSL-->
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
            <version>${querydsl.version}</version>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <version>${querydsl.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.16</version>
        </dependency>
        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!--添加QueryDSL插件支持-->
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

我们从第一章到本章pom.xml内容几乎没有变动,所以有之前章节学习的小伙伴可以直接拿过来使用。 下面我们需要创建两表,当然为了方便我们直接使用第四章内的表结构,

商品信息表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- ----------------------------
-- Table structure for good_infos
-- ----------------------------
DROP TABLE IF EXISTS `good_infos`;
CREATE TABLE `good_infos` (
  `tg_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
  `tg_title` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT '商品标题',
  `tg_price` decimal(8,2) DEFAULT NULL COMMENT '商品单价',
  `tg_unit` varchar(20) CHARACTER SET utf8 DEFAULT NULL COMMENT '单位',
  `tg_order` varchar(255) DEFAULT NULL COMMENT '排序',
  `tg_type_id` int(11) DEFAULT NULL COMMENT '类型外键编号',
  PRIMARY KEY (`tg_id`),
  KEY `tg_type_id` (`tg_type_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

商品类型表

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- ----------------------------
-- Table structure for good_types
-- ----------------------------
DROP TABLE IF EXISTS `good_types`;
CREATE TABLE `good_types` (
  `tgt_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键自增',
  `tgt_name` varchar(30) CHARACTER SET utf8 DEFAULT NULL COMMENT '类型名称',
  `tgt_is_show` char(1) DEFAULT NULL COMMENT '是否显示',
  `tgt_order` int(2) DEFAULT NULL COMMENT '类型排序',
  PRIMARY KEY (`tgt_id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;

创建实体

我们对应上面两张表的结构创建两个实体并添加对应的SpringDataJPA注解配置,如下所示:

商品类型实体
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yuqiyu.querydsl.sample.chapter7.bean;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

/**
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/7/14
 * Time:10:04
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 */
@Entity
@Table(name = "good_types")
@Data
public class GoodTypeBean
    implements Serializable
{
    //主键
    @Id
    @GeneratedValue
    @Column(name = "tgt_id")
    private Long id;
    //类型名称
    @Column(name = "tgt_name")
    private String name;
    //是否显示
    @Column(name = "tgt_is_show")
    private int isShow;
    //排序
    @Column(name = "tgt_order")
    private int order;
}
商品实体
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yuqiyu.querydsl.sample.chapter7.bean;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;

/**
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/7/14
 * Time:10:08
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 */
@Entity
@Table(name = "good_infos")
@Data
public class GoodInfoBean
    implements Serializable
{
    //主键
    @Id
    @GeneratedValue
    @Column(name = "tg_id")
    private Long id;
    //商品标题
    @Column(name = "tg_title")
    private String title;
    //商品价格
    @Column(name = "tg_price")
    private double price;
    //商品单位
    @Column(name = "tg_unit")
    private String unit;
    //商品排序
    @Column(name = "tg_order")
    private int order;
    //类型外键
    @Column(name = "tg_type_id")
    private Long typeId;
}

创建控制器

接下来我们创建一个商品控制器用来我们本章内容的讲解,在控制器初始化时我们需要实例化JPAQueryFactory对象,在实例化之前需要注入EntityManager对象,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.yuqiyu.querydsl.sample.chapter7.controller;

import com.querydsl.jpa.JPAExpressions;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import javax.persistence.EntityManager;
import java.util.List;

/**
 * ========================
 * Created with IntelliJ IDEA.
 * User:恒宇少年
 * Date:2017/7/14
 * Time:9:30
 * 码云:http://git.oschina.net/jnyqy
 * ========================
 */
@RestController
public class GoodController
{
    //实体管理对象
    @Autowired
    private EntityManager entityManager;

    //jpa查询工厂对象
    private JPAQueryFactory queryFactory;

    @PostConstruct
    public void init()
    {
        queryFactory = new JPAQueryFactory(entityManager);
    }
}

模糊查询

我们现在有个需求需要查询出商品类型名称包含蔬菜的商品列表,在原生SQL内也有多种方式可以实现如:子查询、关联查询等。我们在QueryDSL内也是一样的,我们就拿子查询来处理这个需求吧,方法代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    /**
     * 子查询 模糊查询
     * @return
     */
    @RequestMapping(value = "/childLikeSelect")
    public List<GoodInfoBean> childLikeSelect()
    {
        //商品基本信息查询实体
        QGoodInfoBean _Q_good = QGoodInfoBean.goodInfoBean;
        //商品类型查询实体
        QGoodTypeBean _Q_good_type = QGoodTypeBean.goodTypeBean;

        return queryFactory
                .selectFrom(_Q_good)//查询商品基本信息表
                .where(
                        //查询类型名称包含“蔬菜”
                        _Q_good.typeId.in(
                                JPAExpressions.select(
                                        _Q_good_type.id
                                )
                                .from(_Q_good_type)
                                .where(_Q_good_type.name.like("%蔬菜%"))
                        )
                ).fetch();
    }

我们上面的代码查询了商品表内的全部信息并且根据类型编号使用了"in"方法来实现子查询,子查询是查询的商品类型表内的信息并且类型的名称包含“蔬菜”,不过子查询仅仅返回了商品类型的编号。

我们来启动下项目测试我们这个方法是否是我们预期的效果查询出商品类型名称包含”蔬菜“两个字的列表。 项目启动控制台输出日志出现Tomcat started on port(s): 8080 (http),表示已经启动成功,日志如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.4.RELEASE)

......
2017-07-14 10:15:22.255  INFO 11884 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-07-14 10:15:22.259  INFO 11884 --- [           main] c.y.q.s.chapter7.Chapter7Application     : Started Chapter7Application in 2.941 seconds (JVM running for 3.578)
2017-07-14 10:15:26.086  INFO 11884 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2017-07-14 10:15:26.086  INFO 11884 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2017-07-14 10:15:26.104  INFO 11884 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 18 ms
2017-07-14 10:15:26.215  INFO 11884 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator  : HHH000397: Using ASTQueryTranslatorFactory

访问我们配置的地址http://127.0.0.1:8080/childLikeSelect查看界面输出内容如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[
    {
        "id": 2,
        "title": "油菜",
        "price": 12.6,
        "unit": "斤",
        "order": 2,
        "typeId": 1
    }
]

我们看到数据返回”油菜“对应的商品类型编号是"1",对应数据库的类型是”绿色蔬菜“,这证明了我们的编码跟返回的数据是一致的,那么接下来我们来看下QueryDSL为我们自动生成的SQL,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Hibernate: 
    select
        goodinfobe0_.tg_id as tg_id1_0_,
        goodinfobe0_.tg_order as tg_order2_0_,
        goodinfobe0_.tg_price as tg_price3_0_,
        goodinfobe0_.tg_title as tg_title4_0_,
        goodinfobe0_.tg_type_id as tg_type_5_0_,
        goodinfobe0_.tg_unit as tg_unit6_0_ 
    from
        good_infos goodinfobe0_ 
    where
        goodinfobe0_.tg_type_id in (
            select
                goodtypebe1_.tgt_id 
            from
                good_types goodtypebe1_ 
            where
                goodtypebe1_.tgt_name like ? escape '!'
        )

价格最高的商品列表

我们又有了新的需求,需要查询出价格最高的商品列表,代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
     * 子查询 价格最高的商品列表
     * @return
     */
    @RequestMapping(value = "/childEqSelect")
    public List<GoodInfoBean> childEqSelect()
    {
        //商品基本信息查询实体
        QGoodInfoBean _Q_good = QGoodInfoBean.goodInfoBean;

        return queryFactory
                .selectFrom(_Q_good)
                //查询价格最大的商品列表
                .where(_Q_good.price.eq(
                        JPAExpressions.select(
                                _Q_good.price.max()
                        )
                        .from(_Q_good)
                ))
                .fetch();
    }

我们使用JPAExpressions创建一个子查询,查询出商品表内最大商品价格作为父查询的查询条件。

重启项目后访问地址http://127.0.0.1:8080/childEqSelect,接口返回内容如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[
    {
        "id": 4,
        "title": "秋葵",
        "price": 22.6,
        "unit": "斤",
        "order": 3,
        "typeId": 1
    }
]

我们数据库内有三条数据,价格最高的也就是名为“秋葵”的商品了。下面我们再来看下控制台输出的SQL如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Hibernate: 
    select
        goodinfobe0_.tg_id as tg_id1_0_,
        goodinfobe0_.tg_order as tg_order2_0_,
        goodinfobe0_.tg_price as tg_price3_0_,
        goodinfobe0_.tg_title as tg_title4_0_,
        goodinfobe0_.tg_type_id as tg_type_5_0_,
        goodinfobe0_.tg_unit as tg_unit6_0_ 
    from
        good_infos goodinfobe0_ 
    where
        goodinfobe0_.tg_price=(
            select
                max(goodinfobe1_.tg_price) 
            from
                good_infos goodinfobe1_
        )

价格高于平均价格的商品列表

现在我们需要查询高于平均价格的商品列表,那我们该怎么编写呢?代码如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 /**
     * 子查询 价格高于平均价格的商品列表
     * @return
     */
    @RequestMapping(value = "/childGtAvgSelect")
    public List<GoodInfoBean> childGtAvgSelect()
    {
        //商品基本信息查询实体
        QGoodInfoBean _Q_good = QGoodInfoBean.goodInfoBean;
        return queryFactory
                .selectFrom(_Q_good)
                //查询价格高于平均价的商品列表
                .where(
                        _Q_good.price.gt(
                                JPAExpressions.select(_Q_good.price.avg())
                                .from(_Q_good)
                        )
                ).fetch();
    }

我们使用JPAExpressions来创建一个子查询并且返回商品表内价格平均值,查询到的值作为父查询的查询条件。 接下来我们重启项目后访问地址http://127.0.0.1:8080/childGtAvgSelect,接口返回的内容如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[
    {
        "id": 1,
        "title": "金针菇",
        "price": 5.5,
        "unit": "斤",
        "order": 1,
        "typeId": 3
    },
    {
        "id": 2,
        "title": "油菜",
        "price": 12.6,
        "unit": "斤",
        "order": 2,
        "typeId": 1
    }
]

我们再来看下控制台输出的生成SQL内容如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Hibernate: 
    select
        goodinfobe0_.tg_id as tg_id1_0_,
        goodinfobe0_.tg_order as tg_order2_0_,
        goodinfobe0_.tg_price as tg_price3_0_,
        goodinfobe0_.tg_title as tg_title4_0_,
        goodinfobe0_.tg_type_id as tg_type_5_0_,
        goodinfobe0_.tg_unit as tg_unit6_0_ 
    from
        good_infos goodinfobe0_ 
    where
        goodinfobe0_.tg_price<(
            select
                avg(goodinfobe1_.tg_price) 
            from
                good_infos goodinfobe1_
        )

我们可以看到生成的SQL完全是按照我们预期来创建的。

总结

以上内容就是本章的全部内容,我们使用三个简单的例子来讲述了QueryDSL子查询,QueryDSL完美的将原生的SQL编写方式转移到了Java程序内,内置了几乎所有的原生SQL的函数、关键字、语法等。

本章代码已经上传到码云: SpringBoot配套源码地址:https://gitee.com/hengboy/spring-boot-chapter SpringCloud配套源码地址:https://gitee.com/hengboy/spring-cloud-chapter SpringBoot相关系列文章请访问:目录:SpringBoot学习目录 QueryDSL相关系列文章请访问:QueryDSL通用查询框架学习目录 SpringDataJPA相关系列文章请访问:目录:SpringDataJPA学习目录 感谢阅读!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.07.14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
第四十七章:SpringBoot2.0新特性 - Quartz自动化配置集成本章目标SpringBoot 企业级核心技术学习专题构建项目测试总结
在新版本的SpringBoot2.0发布后,急迫尝鲜的我将相关的项目已经更换为最新版本,在SpringBoot源码GitHub看到更新日志,表明了针对Quartz新版本进行了 AutoConfiguration自动化配置,省去了很多繁琐的配置。 官网更新日志 Auto-configuration support is now include for the Quartz Scheduler. We’ve also added a new spring-boot-starter-quartz starte
恒宇少年
2018/06/27
2K0
第四章:使用QueryDSL与SpringDataJPA实现多表关联查询
对于业务逻辑复制的系统来说都存在多表关联查询的情况,查询的返回对象内容也是根据具体业务来处理的,我们本章主要是针对多表关联根据条件查询后返回单表对象,在下一章我们就会针对多表查询返回自定义的对象实体。 本章目标 基于SpringBoot框架平台完成SpringDataJPA与QueryDSL多表关联查询返回单表对象实例,查询时完全采用QueryDSL语法进行编写。 构建项目 我们使用idea工具先来创建一个SpringBoot项目,添加的依赖跟第三章:使用QueryDSL与SpringDataJPA完成Up
恒宇少年
2018/06/27
3.2K0
基于SpringBoot、Elasticsearch实现酒店查询功能!
在一些应用中,Elasticsearch应用于全文搜索的很少,多是用于ToC端的查询,更像是一个缓存数据库。
Java程序猿
2021/02/19
9650
一起来学 SpringBoot 2.x | 第七篇:整合 Mybatis
摘要: 原创出处 http://blog.battcn.com/2018/05/09/springboot/v2-orm-mybatis/ 「唐亚峰」欢迎转载,保留摘要,谢谢!
芋道源码
2019/10/29
6380
第一篇:如何拆分微服务
修改order-service中的根据id查询订单业务,要求在查询订单的同时,根据订单中包含的userId查询出用户信息,一起返回。
GeekLiHua
2025/01/21
1361
第一篇:如何拆分微服务
第五章:使用QueryDSL与SpringDataJPA实现查询返回自定义对象
在我们实际项目开发中,往往会遇到一种多表关联查询并且仅需要返回多表内的几个字段最后组合成一个集合或者实体。这种情况在传统的查询中我们无法控制查询的字段,只能全部查询出后再做出分离,这种也是我们最不愿意看到的处理方式,这种方式会产生繁琐、复杂、效率低、代码阅读性差等等问题。QueryDSL为我们提供了一个返回自定义对象的工具类型,而Java8新特性Collection中stream方法也能够完成返回自定义对象的逻辑,下面我们就来看下这两种方式如何编写? 本章目标 基于SpringBoot平台完成SpringD
恒宇少年
2018/06/27
4.7K0
神奇的 SQL 之子查询,细节满满 !
  讲子查询之前,我们先来看看视图,何谓视图 ? 视图是基于 SQL 语句的结果集的可视化的表,包含行和列,就像一个真实的表,但只是一张虚拟表,我们可以将其视作为一张普通的表;视图只供数据查询,不能进行数据更改,也不能保存数据,查询数据来源于我们的实体表;说的简单点,视图就是复杂 SELECT 语句的一个代号,为查询提供便利。视图总是显示最近的数据,每当我们查询视图时,数据库引擎通过使用 SQL 语句来重建数据。
青石路
2019/08/09
7870
神奇的 SQL 之子查询,细节满满 !
第六章:使用QueryDSL的聚合函数
在企业级项目开发过程中,往往会经常用到数据库内的聚合函数,一般ORM框架应对这种逻辑问题时都会采用编写原生的SQL来处理,而QueryDSL完美的解决了这个问题,它内置了SQL所有的聚合函数下面我们简
恒宇少年
2018/06/27
3.6K0
深入探索Spring Data JPA, 从Repository 到 Specifications 和 Querydsl
数据访问层,所谓的CRUD是后端程序员的必修课程,Spring Data JPA 可以让我们来简化CRUD过程,本文由简入深,从JPA的基本用法,到各种高级用法。
JadePeng
2020/11/13
2K0
springJPA 之 QueryDSL(一)
引言 不可否认的是 JPA 使用是非常方便的,极简化的配置,只需要使用注解,无需任何 xml 的配置文件,语义简单易懂,但是,以上的一切都建立在单表查询的前提下的,我们可以使用 JPA 默认提供的方法,简单加轻松的完成 CRUD 操作。 但是如果涉及到多表动态查询, JPA 的功能就显得有些捉襟见肘了,虽然我们可以使用注解 @Query ,在这个注解中写 SQL 或者 HQL 都是在拼接字符串,并且拼接后的字符串可读性非常的差,当然 JPA 还为我们提供了 Specification 来做这件事情,从我个人使用体验上来讲,可读性虽然还不错,但是在初学者上手的时候, Predicate 和 CriteriaBuilder 使用方式估计能劝退不少人,而且如果直接执行 SQL 连表查询,获得是一个 Object[] ,类型是什么?字段名是什么?这些都无法直观的获得,还需我们手动将 Object[] 映射到我们需要的 Model 类里面去,这种使用体验无疑是极其糟糕的。
全栈程序员站长
2022/09/20
5.3K0
爬取京东手机信息
学习了HttpClient和Jsoup,就掌握了如何抓取数据和如何解析数据,接下来,我们做一个小练习,把京东的手机数据抓取下来。
Remember_Ray
2020/09/15
1.2K0
爬取京东手机信息
第二章:使用QueryDSL与SpringDataJPA实现单表普通条件查询
在企业开发中ORM框架有很多种如:Hibernate,Mybatis,JdbcTemplate等。每一种框架的设计理念是不一样的,Hibernate跟我们本章讲解的SpringDataJPA是一致的框架都是全自动理念作为设计核心,让用户更少的去写SQL语句通过简单的配置就可以实现各种查询。而Mybatis框架则是半自动理念作为设计核心,SQL让用户自己定义实现了更好的灵活性。 本章目标 本章我们目标实现QueryDSL通用查询语言整合SpringDataJPA完成单表的查询多样化。 构建项目 下面我们先来创
恒宇少年
2018/06/27
1.7K0
第三十章:SpringBoot使用MapStruct自动映射DTO
MapStruct是一种类型安全的bean映射类生成java注释处理器。 我们要做的就是定义一个映射器接口,声明任何必需的映射方法。在编译的过程中,MapStruct会生成此接口的实现。该实现使用纯java方法调用的源和目标对象之间的映射,MapStruct节省了时间,通过生成代码完成繁琐和容易出错的代码逻辑。下面我们来揭开它的神秘面纱 本章目标 基于SpringBoot平台完成MapStruct映射框架的集成。 SpringBoot 企业级核心技术学习专题 专题 专题名称 专题描述 001 Spring
恒宇少年
2018/06/27
5.4K0
第一章:Maven环境下如何配置QueryDSL环境
QueryDSL是一个通用的查询框架,框架的核心原则是创建安全类型的查询,开始QueryDSL仅支持Hibernate(HQL),在不断开源人士加入QueryDSL团队后,陆续发布了针对JPA,JDO,JDBC,Lucene,Hibernate Search,MangoDB,Collections 和RDF(Relational Data Format) Bean等。 本章目标 我们本系列的章节主要使用QueryDSL与SpringDataJPA在SpringBoot开发环境下进行整合使用,目前Spr
恒宇少年
2018/06/27
1.7K3
第三章:使用QueryDSL与SpringDataJPA完成Update&Delete
我们上一章讲解了有关QueryDsl整合SpringDataJPA完成简单的单表条件查询,采用了两种模式进行查询一种是完全QueryDsl而另外一种则是整合的形式,既然单表的查询已经讲解接下来我们来看看QueryDsl与SpringDataJPA整合后的Update&Delete的多种处理模式。 本章目标 基于SpringBoot框架平台完成QueryDsl整合SpringDataJPA单表Update&Delete操作。 构建项目 我们使用idea工具创建一个空的SpringBoot项目,把上一章第二章:
恒宇少年
2018/06/27
4.6K2
第三十五章:SpringBoot与单元测试的小秘密
单元测试对于开发人员来说是非常熟悉的,我们每天的工作也都是围绕着开发与测试进行的,在最早的时候测试都是采用工具Debug模式进行调试程序,后来Junit的诞生也让程序测试发生了很大的变化。我们今天来讲解下基于SpringBoot结合Junit怎么来完成单元测试。 本章目的 基于SpringBoot平台整合Junit分别完成客户端、服务端的单元测试。 SpringBoot 企业级核心技术学习专题 专题 专题名称 专题描述 001 Spring Boot 核心技术 讲解SpringBoot一些企业级层面的核心组
恒宇少年
2018/06/27
1.4K0
MyBatis-Plus联表查询(Mybatis-Plus-Join)
mybatis-plus作为mybatis的增强工具,简化了开发中的数据库操作。一旦遇到left join或right join的左右连接,还是得老老实实的打开xml文件,手写上一大段的sql语句。今天总结一下一款叫做mybatis-plus-join的工具(后面就简称mpj了),可以用类似mybatis-plus中QueryWrapper的方式来进行联表查询。
鱼找水需要时间
2023/02/16
8.3K0
MyBatis-Plus联表查询(Mybatis-Plus-Join)
ApiBoot Logging使用SpringCloud Openfeign透传链路信息
ApiBoot Logging可以无缝整合SpringCloud来采集请求日志,目前支持RestTemplate、Openfeign两种方式,我们本章来讲解下在使用Openfeign完成服务之间请求相互调用的一条链路请求日志是否可以都采集到。
恒宇少年
2019/11/11
5750
深入理解 QueryDSL 的 BooleanBuilder:构建复杂逻辑表达式
在 Java 的查询构建库 QueryDSL 中, BooleanBuilder 是一个非常有用的工具类。它允许开发者通过链式调用轻松地构建复杂的布尔逻辑表达式。本文将详细介绍 BooleanBuilder 的各种方法,并通过代码示例展示如何使用这些方法。
訾博ZiBo
2025/01/06
970
Querydsl结构化查询之jpa
Querydsl是一个Java开源框架用于构建类型安全的SQL查询语句。它采用API代替拼凑字符串来构造查询语句,不仅可以结合jpa等用来查询关系型数据,还提供了相关的api用来查询mongodb,lucene的数据
kl博主
2023/11/18
2920
推荐阅读
相关推荐
第四十七章:SpringBoot2.0新特性 - Quartz自动化配置集成本章目标SpringBoot 企业级核心技术学习专题构建项目测试总结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验