SpringDataJPA快速入门

前言

之前在学习 SpringBoot 框架的时候,使用到了 SpringData JPA,但是当时只是简单的查询,没有用到稍微复杂的查询。

JPA 的 JPQL 语法规则对于简单的查询实属利器,大大加快了开发速度。不久前,在公司将用户推荐功能单独抽取出为一个独立项目,由于公司一直沿用的底层框架太老,只能使用 JDK1.6,JDK 1.9都出来了,实在不能忍??,果断引入了 SpringData JPA。

然后最近公司其他同事接手了该项目,但是不太了解 SpringData JPA 的使用,于是有了此文,不会就可以直接让他看本篇博客了哈哈。

环境准备

这里不讲解 SpringData JPA 与框架的整合,只讲解 JPA 语法的使用

Entity 实体类

@Entity // 表示为一个实体类
@Table("employee") // 表名
public class Employee {

    @Id //主键标识注解
    @GeneratedValue // 主键生成方式
    private Integer id;

    private String name;

    private Integer age;

    //Getter/Setter省略
}

Repository 接口

// 继承 JpaRepository 接口,第一个参数为查询的实体类,第二个为实体类的主键数据类型
public interface EmployeeRepository extends JpaRepository<Employee, Integer>{

}

插入测试数据

@Test
public void testAdd() throws Exception {
    for (int i = 0; i < 100; i++) {
        Employee employee = new Employee();
        employee.setAge(i);
        employee.setName("test" + i);
        employeeRepository.save(employee);
    }
}

JPA 查询语法讲解

使用 JPQL 进行查询

// 新增/更新
employeeRepository.save(employee);

// where name = ?1
employeeRepository.findByName("test1")

// where name = ?1 and age = ?2
employeeRepository.findByNameAndAge("test1", 20);

// where age between ?1 and ?2 【包含头尾】
List<Employee> byAgeBetween = employeeRepository.findByAgeBetween(10, 16);

// where age < ?1
List<Employee> list = employeeRepository.findByAgeLessThan(10);

// where age > ?1
List<Employee> list = employeeRepository.findByAgeGreaterThan(90);

// where name is null  【不包含为空字符串的数据】
List<Employee> list = employeeRepository.findByNameIsNull();

// where name like "test9%" 以test9为开头的name
List<Employee> list = employeeRepository.findByNameLike("test9%");
或者
List<Employee> employees = employeeRepository.findByNameStartingWith("test")

// where name like "test_" 以test开头,且后面只模糊匹配一位
List<Employee> list2 = employeeRepository.findByNameLike("test_");

// where name like "%6" 模糊匹配以6结尾的
List<Employee> employees = employeeRepository.findByNameEndingWith(6)

// where name in (?1, ?2)
List<String> names = Arrays.asList("test1", "test2");
List<Employee> employees = employeeRepository.findByNameIn(names);

// where age <> ?1
List<Employee> employees = employeeRepository.findByAgeNot(99);

// where name = ?1 order by age desc
List<Employee> findByNameOrderByAgeDesc(String name);

使用自定义 Sql 以及 原生 Sql 查询

/** EmployeeRepository.java 添加方法 */

// 根据姓名与年龄查找,[通过占位符获取参数值]
@Query("select o from Employee o where name = ?1 and age = ?2")
List<Employee> queryEmployeeByParams(String name, Integer age);

// 根据姓名与年龄查找,[通过命名参数获取参数值],必须使用 @Param 注解
@Query("select o from Employee o where name = :name and age = :age")
List<Employee> queryEmployeeByParams2(@Param("name") String name, @Param("age") Integer age);

// 原生SQL,与上面不同的是,上面使用的是对象名称以及对象属性名称,Native SQL使用数据库表名以及字段名
@Query(nativeQuery = true, value = "select * from employee where name = :name and age = :age")
List<Employee> queryEmployeeByParams3(@Param("name") String name, @Param("age") Integer age);

JPA 更新操作

/** 需要搭配使用 @Query 与 @Modifying 和 @Transactional 注解使用*/

@Modifying
@Query("update Employee o set o.age = ?2 where o.id = ?1")
Integer updateAge(Integer id, Integer age);

在 Service 层调用

@Autowired
private EmployeeRepository employeeRepository;

@Transactional // 必须开启事务
public void update(Integer id, Integer age) {
    employeeRepository.save(id, age);
}

分页查询

// EmployeeRepository 接口定义
Page<Employee> findByNameStartingWith(String name, Pageable pageable);

// 测试类 EmployeeRepositoryTest.java
// 普通分页查询
@Test
public void testFindByNameStartingWith() {
    // 注意 page 从 0 开始
    Pageable request = new PageRequest(0, 10);
    Page<Employee> result = employeeRepository.findByNameStartingWith("test", request);
    for (Employee employee : result.getContent()) {
        System.out.println(employee);
    }
}

// 带排序条件的分页查询
@Test
public void testFindByNameStartingWith() {
    Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
    Sort sort = new Sort(order);
    Pageable request = new PageRequest(0, 10, sort);
    Page<Employee> result = employeeRepository.findByNameStartingWith("test", request);
    for (Employee employee : result.getContent()) {
        System.out.println(employee);
    }
}

动态 SQL 查询

在 Java 开发中,动态 SQL 是必不可少的,JPA 也可以实现,Repository 多继承一个接口 JpaSpecificationExecutor 即可。

// 修改之前的 EmployeeRepository, 使其多继承 JpaSpecificationExecutor 接口
public interface EmployeeRepository extends JpaRepository<Employee, Integer>, JpaSpecificationExecutor<Employee>{

    // ......
}

Pageable request = new PageRequest(0, 10);
Specification<Employee> specification = new Specification<Employee>() {
public Predicate toPredicate(Root<Employee> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        Path<Integer> path = root.get("age");
                return cb.gt(path, 50);
            }
        };
Page<Employee> all = employeeRepository.findAll(specification, request);

后记

这里感谢一下慕课网,快速入门多亏了 imooc 上的课程。

参考课程:

  • https://www.imooc.com/learn/821

原文地址:https://www.cnblogs.com/zt007/p/11578445.html

时间: 2024-08-30 15:41:30

SpringDataJPA快速入门的相关文章

spring-data-jpa快速入门(一)——

一.概述 官网:https://projects.spring.io/spring-data-jpa/ 1.什么是spring-data-jpa Spring Data JPA, part of the larger Spring Data family, makes it easy to easily implement JPA based repositories. This module deals with enhanced support for JPA based data acce

SpringData 基于SpringBoot快速入门

SpringData 基于SpringBoot快速入门 本章通过学习SpringData 和SpringBoot 相关知识将面向服务架构(SOA)的单点登录系统(SSO)需要的代码实现.这样可以从实战中学习两个框架的知识,又可以为单点登录系统打下基础.通过本章你将掌握 SpringBoot项目的搭建,Starter pom的使用,配置全局文件,核心注解SpringBootApplication 介绍以及单元测试 SpringBootTest注解的使用.SpringData 的入门使用,Repos

第二章-spring boot springDataJPA快速开发DAO层,junit测试

一.简介 第一章介绍了spring boot简单入门,这一章介绍一下如何通过springDataJPA快速实现DAO层开发. 二.环境 1. jdk1.8 2. springboot 1.5.9.RELEASE 3. apache maven(3.5.0) 4. 开发工具(IntelliJ IDEA ) 三.步骤 1)通过idea file->new project->Spring Initializr 创建项目,选中web->web,sql->JPA.MySQL.       

笔记:Spring Cloud Zuul 快速入门

Spring Cloud Zuul 实现了路由规则与实例的维护问题,通过 Spring Cloud Eureka 进行整合,将自身注册为 Eureka 服务治理下的应用,同时从 Eureka 中获取了所有其他微服务的实例信息,这样的设计非常巧妙的将服务治理体系中维护的实例信息利用起来,使得维护服务实例的工作交给了服务治理框架自动完成,而对路由规则的维护,默认会将通过以服务名作为 ContextPath 的方式来创建路由映射,也可以做一些特别的配置,对于签名校验.登录校验等在微服务架构中的冗余问题

javaweb-html快速入门

本文主要是进行HTML简单介绍(详细的属性查帮助文档就行了,这里主要为快速入门,赶时间,在最短的时间中看明白一个html文件的代码(如果能称之为代码的话)详细的样式表,布局啥的有时间再研究吧) HTML 1.html的简介 1.1,html的全称:HyperText Mark-up Language ,超文本标记型语言,是网页的语言. 超文本:比文本更加强大(后面还会讲到XML,可扩展标记性语言) 标记:就是标签,html所有操作都是通过标签直接或间接的操作(把需要操作的数据通过标签封装起来)

crosswalk 快速入门,利用WebRTC(html)开始开发视频通话

crosswalk 快速入门,利用WebRTC(html)开始开发视频通话 安装Python 从http://www.python.org/downloads/ 下载安装程序 安装完后,再添加到环境变量. 安装Oracle JDK 下载页面: http://www.oracle.com/technetwork/java/javase/downloads/ 选择要下载的Java版本(推荐Java 7). 选择一个JDK下载并接受许可协议. 一旦下载,运行安装程序. 安装Ant Ant:下载http

bash编程快速入门

首先,我们简单的介绍一下bash,bash是GNU计划编写的Unixshell,它是许多Linux平台上的内定shell,它提供了用户与系统的很好的交互,对于系统运维人员,bash的地位是举足轻重的,bash编程能很快处理日常的任务 bash入门,一个最简单的bash例子 #vim hello.sh #!/bin/bash #This is the first example of the bash #echo "Hello world" 下面,我们就这个简单的bash 脚本来介绍一下

定时器(Quartz)快速入门

Quartz概述 Quartz中的触发器 Quartz中提供了两种触发器,分别是CronTrigger和SimpleTrigger. SimpleTrigger 每 隔若干毫秒来触发纳入进度的任务.因此,对于夏令时来说,根本不需要做任何特殊的处理来"保持进度".它只是简单地保持每隔若干毫秒来触发一次,无论你的 SimpleTrigger每隔10秒触发一次还是每隔15分钟触发一次,还是每隔24小时触发一次. CronTrigger 在特定"格林日历"时刻触发纳入进程的

vue.js--60分钟快速入门

Vue.js--60分钟快速入门 Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js,Vue.js提供了更加简洁.更易于理解的API,使得我们能够快速地上手并使用Vue.js. 本文摘自:http://www.cnblogs.com/keepfool/p/5619070.html 如果你之前已经习惯了用jQuery操作DOM,学习Vue.js时请先抛开手动操作DOM的思维,因为Vue.js是数据驱动的,你无需手动操作DOM