SpringData JPA进阶查询—JPQL/原生SQL查询、分页处理、部分字段映射查询

上一篇介绍了入门基础篇SpringDataJPA访问数据库。本篇介绍SpringDataJPA进一步的定制化查询,使用JPQL或者SQL进行查询、部分字段映射、分页等。本文尽量以简单的建模与代码进行展示操作,文章比较长,包含查询的方方面面。如果能耐心看完这篇文章,你应该能使用SpringDataJPA应对大部分的持久层开发需求。如果你需要使用到动态条件查询,请查看下一篇博客,专题介绍SpringDataJPA的动态查询。


一、入门引导与准备


JPQL(JavaPersistence Query Language)是一种面向对象的查询语言,它在框架中最终会翻译成为sql进行查询,如果不知JPQL请大家自行谷歌了解一下,如果你会SQL,了解这个应该不废吹灰之力。

1.核心注解@Query介绍


使用SpringDataJPA进行JPQL/SQL一般查询的核心是@Query注解,我们先来看看该注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@QueryAnnotation
@Documented
public @interface Query {
	String value() default "";
	String countQuery() default "";
	String countProjection() default "";
	boolean nativeQuery() default false;
	String name() default "";
	String countName() default "";
}
该注解使用的注解位置为方法、注解类型,一般我们用于注解方法即可。@QueryAnnotation标识这是一个查询注解;

@Query注解中有6个参数,value参数是我们需要填入的JPQL/SQL查询语句;nativeQuery参数是标识该查询是否为原生SQL查询,默认为false;countQuery参数为当你需要使用到分页查询时,可以自己定义(count查询)计数查询的语句,如果该项为空但是如果要用到分页,那么就使用默认的主sql条件来进行计数查询;name参数为命名查询需要使用到的参数,一般配配合@NamedQuery一起使用,这个在后面会说到;countName参数作用与countQuery相似,但是使用的是命名查询的(count查询)计数查询语句;countProjection为涉及到投影部分字段查询时的计数查询(count查询);关于投影查询,待会会说到。

有了@Query基础后,我们就可以小试牛刀一把了,对于jar包依赖,我们用的依旧是上一节的依赖,代码如下:

2.准备实验环境


<parent>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-parent</artifactId>  
    <version>1.4.1.RELEASE</version>  
</parent>  
  
<properties>  
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
    <java.version>1.8</java.version>  
    <springBoot.groupId>org.springframework.boot</springBoot.groupId>  
</properties>  
  
<dependencies>  
    <!-- SpringBoot Start -->  
    <dependency>  
        <groupId>${springBoot.groupId}</groupId>  
        <artifactId>spring-boot-starter-web</artifactId>  
    </dependency>  
    <!-- jpa -->  
    <dependency>  
        <groupId>${springBoot.groupId}</groupId>  
        <artifactId>spring-boot-starter-data-jpa</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>${springBoot.groupId}</groupId>  
        <artifactId>spring-boot-starter-test</artifactId>  
    </dependency>  
    <!-- mysql -->  
    <dependency>  
        <groupId>mysql</groupId>  
        <artifactId>mysql-connector-java</artifactId>  
    </dependency>  
    <dependency>  
        <groupId>junit</groupId>  
        <artifactId>junit</artifactId>  
        <version>4.12</version>  
    </dependency>  
</dependencies>

项目结构如下:


JpaConfiguration配置类与上篇的相同:

@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@EnableTransactionManagement(proxyTargetClass=true)
@EnableJpaRepositories(basePackages={"org.fage.**.repository"})
@EntityScan(basePackages={"org.fage.**.entity"})
public class JpaConfiguration {
	@Bean
	PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){
		return new  PersistenceExceptionTranslationPostProcessor();
	}
}
App类:

@SpringBootApplication
@ComponentScan("org.fage.**")
public class App {
	public static void main(String[] args) throws Exception {
		SpringApplication.run(App.class, args);
	}
}

对于实体建模依旧用到上一篇所用的模型Department、User、Role,Department与User为一对多,User与Role为多对多,为了方便后面介绍投影,user多增加几个字段,代码如下:

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

	private static final long serialVersionUID = -72
  • 30
    点赞
  • 95
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
可以使用 Spring Data JPA 提供的投影(Projection)功能来查询部分字段。 投影可以根据实体类的属性选择需要查询字段,返回一个自定义的接口或者一个DTO(Data Transfer Object)对象。 具体实现可以参考以下步骤: 1. 创建一个自定义接口或DTO对象,定义需要查询字段。 例如,需要查询用户表中的用户名和邮箱,可以创建一个自定义接口如下: ``` public interface UserProjection { String getUsername(); String getEmail(); } ``` 2. 在Repository接口中定义查询方法,使用`@Query`注解指定查询语句,并在查询语句中使用`SELECT`关键字选择需要查询字段。 例如,查询用户名和邮箱的方法可以定义如下: ``` public interface UserRepository extends JpaRepository<User, Long> { @Query("SELECT u.username AS username, u.email AS email FROM User u WHERE u.id = :id") UserProjection findUsernameAndEmailById(@Param("id") Long id); } ``` 在查询语句中,使用`AS`关键字将查询结果映射到自定义接口中定义的属性中。 3. 在Service层调用Repository中定义的查询方法,获取需要查询字段。 例如,在Controller中调用Service中的方法: ``` @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/user/{id}") public UserProjection getUser(@PathVariable Long id) { return userService.findUsernameAndEmailById(id); } } ``` 这样就可以查询到用户表中指定字段的数据了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值