前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >序列化与反序列化系列二:JPA 与 Querydsl

序列化与反序列化系列二:JPA 与 Querydsl

作者头像
程序员架构进阶
发布2021-10-11 10:30:36
1.4K0
发布2021-10-11 10:30:36
举报
文章被收录于专栏:架构进阶

系列文章:

序列化与反序列化之 Protostuff(一)

一 前言

其实JPA放在这里有些牵强,不过我们开始这个系列的研究是与JPA相关的,起源于数据库查询中自动生成的一段Dabatase相关代码。事实上,在简化orm代码时,序列化和反序列化也确实是其中的一部分重要工作。那么我们就开始本篇学习。

二 Spring Data Jpa

2.1 简介

spring-data-jpa官网:https://spring.io/projects/spring-data-jpa。根据官网的描述:

Spring Data JPA是Spring Data大家族中的一员,使基于repositories的JPA实现变得简单。本模块对基于JPA的数据访问层做了增强支持。它使得构建使用数据访问技术的Spring驱动的应用程序变得更加容易。

实现应用的数据访问层通常都很笨重,最典型的就是传统的JDBC,为了执行简单的一段查询,我们需要写太多重复的(样板)代码。ORM框架Hibernate、Mybatis等都是为了解决这个问题而出现。Spring Data JPA致力于显著提升数据访问层的代码编写效率,开发者可以写自己的repository接口,包括定制化的查询方法,在此之后,Spring会提供这些接口的自动实现。

2.2 JPA与Hibernate关系

需要注意的是,JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,Hibernate就是实现了JPA接口的ORM框架。

JPA默认使用Hibernate作为ORM实现,所以,一般使用Spring Data JPA即会使用Hibernate。二者的关系就是:JPA是一套ORM规范,Hibernate实现了JPA规范。

根据Hibernate官方给出的概念:Hibernate是一个开源的对象关系映射(ORM)框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架,Hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

2.3 JPA与Mybatis对比

MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集。可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。

由于JPA默认使用Hibernate,所以JPA与Mybatis对比其实就是Hibernate与Mybatis的对比,这就是一个比较经典的问题了。简单来说:Hibernate在Java代码层面上,省去了绝大部分sql编写,取而代之的是用面向对象的方式操作关系型数据库的数据;MyBatis则是一个能够灵活编写sql语句,并将sql的入参和查询结果映射成POJOs的一个持久层框架。

2.3.1 Mybatis优势

在做框架选择时,需要考虑功能、灵活性、扩展性等因素。一些倾向于Mybatis的理由是,它提供了便利的 SQL 操作,自由度高,封装性好。Spring Data JPA对复杂SQL的支持不好,没有实体关联的两个表要做 join要花不少功夫。另外几个考虑点:

1.相对来说,jpa的学习成本比mybatis略高

2.公司业务需求频繁变更导致表结构复杂,此处使用mybatis比jpa更灵活

3.就方言来讲,一般公司选定数据库后再变更微乎其微,所以此处方言的优势可以忽略

2.3.2 Hibernate

反过来,Hibernate自然也有它的优势。在不需要特别复杂sql的场景,Hibernate提供的SQL操作功能已经足够应对,它封装好的特征就大有用途了。尤其是在有些场景(一些传统业务),在交付时可能需要根据客户购买的数据库去做适配,这时优势就很明显了。Mybatis一般都需要做sql级别的调整。

三 JPA之Querydsl

前面我们已经知道,JPA对于复杂的sql查询,处理起来还是比较复杂的。显然Spring也不会放任这个问题一直存在,QueryDSL就是用来简化JPA操作的。

Querydsl定义了一种常用的静态类型语法,用于在持久域模型数据之上进行查询。JDO和JPA是Querydsl的主要集成技术。JPA的Querydsl是JPQL和Criteria查询的替代方法,以一个通用的查询框架的形式,专注于通过Java API构建类型安全的SQL查询。

四 Querydsl使用

4.1 依赖引入

pom中依赖引入,本文使用的是4.2.1版本:

代码语言:javascript
复制
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-jpa</artifactId>
    <version>4.2.1</version>
</dependency>
<dependency>
    <groupId>com.querydsl</groupId>
    <artifactId>querydsl-apt</artifactId>
    <scope>provided</scope>
    <version>4.2.1</version>
</dependency>
代码语言:javascript
复制

4.2 maven编译插件

代码语言:javascript
复制
<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> 

该插件会查找使用javax.persistence.Entity注解的域类型,并为它们生成对应的查询类型。例如我们定义一个名为User的实体,通过Querydsl可以生成一个名为QUser的查询。

4.3 User实体类

代码语言:javascript
复制
package com.flamingskys.springboot.jpa.entity;

import lombok.Data;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Data
@Entity
@Table(name="t_user")
public class User implements Serializable{

    private static final long serialVersionUID = 1L;
    @Id()
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private String address;
    private int age; 
    
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]";
    }
} 

4.4 生成查询类

上述实体类创建好了之后,运行mvn clean complie命令,就会在我们在4.2中配置的目录下生成对应的查询类型。然后将生成的类拷贝到项目中,就可以使用了。

代码语言:javascript
复制
import static com.querydsl.core.types.PathMetadataFactory.*; 
import com.querydsl.core.types.dsl.*; 
import com.querydsl.core.types.PathMetadata; 
import javax.annotation.Generated; 
import com.querydsl.core.types.Path; 
/** 
 * QUser is a Querydsl query type for User 
 */ 
@Generated("com.querydsl.codegen.EntitySerializer") 
public class QUser extends EntityPathBase<User> { 
 private static final long serialVersionUID = 1153899872L; 
 public static final QUser user = new QUser("user"); 
 public final StringPath address = createString("address"); 
 public final NumberPath<Integer> age = createNumber("age", Integer.class); 
 public final NumberPath<Integer> id = createNumber("id", Integer.class); 
 public final StringPath name = createString("name"); 
 public QUser(String variable) { 
  super(User.class, forVariable(variable)); 
 } 
 
 public QUser(Path<? extends User> path) { 
  super(path.getType(), path.getMetadata()); 
 } 
 
 public QUser(PathMetadata metadata) { 
  super(User.class, metadata); 
 } 
} 

这个类就可以实现对单表t_user的增删改查操作。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-09-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员架构进阶 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 前言
  • 二 Spring Data Jpa
    • 2.1 简介
      • 2.2 JPA与Hibernate关系
        • 2.3 JPA与Mybatis对比
          • 2.3.1 Mybatis优势
          • 2.3.2 Hibernate
      • 三 JPA之Querydsl
      • 四 Querydsl使用
        • 4.1 依赖引入
          • 4.2 maven编译插件
            • 4.3 User实体类
              • 4.4 生成查询类
              相关产品与服务
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档