JPA和Spirng Data JPA概述

在讲之前,我们需要先知道这几个概念

  • JPA
  • Hibernate
  • Spring Data
  • Spring Data JPA

JPA
JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据。
JPA是一种规范和标准,也就是类似于Java中的接口,由Sun公司官方定义,但是并没有指定谁来实现.
现在几个主要的JPA实现技术有Hibernate、EclipseLink、OpenJPA等Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的ORM框架。Hibernate可以自动生成SQL语句、自动执行,从而使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库.
实际上,JPA规范制定过程中就是借鉴了Hibernate等这些开源的持久框架,也就是说Hibernate的出现比JPA还要早些。
在Hibernate中使用的注解就是JPA注解,Hibernate实现了JPA规范。Spring Data
Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得数据库的访问变得方便快捷, 并支持map-reduce框架和云计算数据服务。Spring Data本身就是一个开源的框架.Spring Data JPA
上面说过Spring Data是一个开源框架,在这个框架中Spring Data JPA只是这个框架中的一个模块,查看官方文档,我们可以看到Spring Data中还有很多诸如SpringDataRedis、SpringDataMongoDB、SpringDataJDBC等等。
它可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。

如何在SpringBoot中使用Spring Data JPA

1. 在pom.xml中添加依赖

<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>

2. yml配置文件中加入jpa配置( 数据库连接的配置跟之前的相同不变)

spring:
jpa:
show-sql: true # 默认false,在日志里显示执行的sql语句
database: mysql
    hibernate.ddl-auto: update #指定为update,每次启动项目检测表结构有变化的时候会新增字段,表不存在时会新建,如果指定create,则每次启动项目都会清空数据并删除表,再新建
    properties.hibernate.dialect: org.hibernate.dialect.MySQL5Dialect
database-platform: org.hibernate.dialect.MySQL5Dialect
hibernate:
naming:
implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl #指定jpa的自动表生成策略,驼峰自动映射为下划线格式
        #physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

3. 在model层创建一个实体类SysAdminUser.java

package com.zhlab.demo.model;

import javax.persistence.*;
import java.util.Date;

@Entity // @Entity: 实体类, 必须
@Table(name="sys_admin_user") //指定表名称
public class SysAdminUser {

    @Id // @Id: 指明id列, 必须
    @GeneratedValue(strategy = GenerationType.IDENTITY) // @GeneratedValue:表明是否自动生成, 必须, strategy也是必写, 指明主键生成策略, 默认是Oracle
private Long adminUserId;

    @Column(name = "user_name", nullable = false)
private String userName;

    @Column(name = "password", nullable = false)
private String password;

    @Column(name = "nick_name", nullable = false)
private String nickName;

    @Column(name = "dept_id")
private Long deptId;

private String phone;

private String email;

private String avatar;

private Boolean status;

private Boolean deletedFlag;

private String loginIp;

private Date loginTime;

private Date createdAt;

private Date updatedAt;

private Date deletedAt;

private Long createdBy;

private Long updatedBy;

private Long deletedBy;

private String remark;

// 省略getter、setter
}

4. 在DAO层创建SysAdminUserRepository.java并继承JpaRepository接口

package com.zhlab.demo.dao;

import com.zhlab.demo.model.SysAdminUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.CrudRepository;

import java.io.Serializable;

public interface SysAdminUserRepository extends JpaRepository<SysAdminUser,Long>, Serializable {
// 就这么简单?
// 对,就这么简单,什么都不用写,这是Spring Data JPA 默认帮我们实现了基本的数据库操作
// 如果需要扩展,可以自定义符合Spring Data JPA规则的查询方法,由框架将其自动解析为SQL
}

可以查看JpaRepository接口,它继承了PagingAndSortingRepository接口

@NoRepositoryBean
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> {
//...省略
}

继续查看PagingAndSortingRepository接口,它又继承了CrudRepository接口

@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable<T> findAll(Sort var1);

Page<T> findAll(Pageable var1);
}

查看CrudRepository接口

package org.springframework.data.repository;

import java.util.Optional;

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
<S extends T> S save(S var1);

<S extends T> Iterable<S> saveAll(Iterable<S> var1);

Optional<T> findById(ID var1);

boolean existsById(ID var1);

Iterable<T> findAll();

Iterable<T> findAllById(Iterable<ID> var1);

long count();

void deleteById(ID var1);

void delete(T var1);

void deleteAll(Iterable<? extends T> var1);

void deleteAll();
}

可以看到CrudRepository已经帮我们做了一些基础的CRUD操作,它是顶层CURD接口。

如果有自定义写查询方法的需求,可以参考Spring Data JPA 命名规范

Spring Data jpa 空值忽略 spring data jpa hibernate_JPA

Spring Data JPA 命名规范

5. 在Service层创建一个SysAdminUserService.java

package com.zhlab.demo.service;

import com.zhlab.demo.dao.SysAdminUserRepository;
import com.zhlab.demo.model.SysAdminUser;
import com.zhlab.demo.utils.PageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @ClassName SysAdminUserService
 * @Description //SysAdminUserService
/
@Service
public class SysAdminUserService {

@Autowired
    SysAdminUserRepository sysAdminUserRepository;

/**
     * 新增用户
     * */
public void addUser(SysAdminUser user) {
        sysAdminUserRepository.save(user);
}

/**
     * 查询所有用户
     * */
public List<SysAdminUser> findAll(){
return sysAdminUserRepository.findAll(Sort.by("adminUserId").descending());
}

/**
     * 分页方法1
     * */
public Object findPage(PageVo pageVo){
return sysAdminUserRepository.findAll(PageRequest.of(pageVo.getPageNum(),pageVo.getPageSize()));
}

/**
     * 分页方法2
     * */
public Page<SysAdminUser> findPageable(PageVo pageVo){
        Pageable pageable = PageRequest.of(pageVo.getPageNum(), pageVo.getPageSize());

return sysAdminUserRepository.findAll(pageable);
}

}

6. 在接口层创建UserController.java

package com.zhlab.demo.controller;

import com.zhlab.demo.model.SysAdminUser;
import com.zhlab.demo.service.SysAdminUserService;
import com.zhlab.demo.utils.PageVo;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @ClassName UserController
 * @Description //用户接口层
@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
    SysAdminUserService sysAdminUserService;

/* 方法注解 */
@ApiOperation(value = "方法名:用户列表", notes = "获取用户列表")
@GetMapping("/list")
public List<SysAdminUser> list(){
        List<SysAdminUser> list = sysAdminUserService.findAll();
return list;
}

/* 方法注解 */
@ApiOperation(value = "方法名:用户列表分页", notes = "分页获取用户列表")
@PostMapping("/listForPage")
public Object listPage(@RequestBody PageVo pageVo){
        Object list = sysAdminUserService.findPage(pageVo);
return list;
}

/* 方法注解 */
@ApiOperation(value = "方法名:用户列表分页2", notes = "分页获取用户列表2")
@PostMapping("/listForPageable")
public Page<SysAdminUser> listPageable(@RequestBody PageVo pageVo){
        Page<SysAdminUser> list = sysAdminUserService.findPageable(pageVo);
return list;
}

@ApiOperation(value = "方法名:新增用户", notes = "新增用户")
@PostMapping("/add")
public void add(@RequestBody SysAdminUser user){
        sysAdminUserService.addUser(user);
}
}

创建一个分页请求参数类PageVo.java

private int pageNum;
private int pageSize;

public int getPageNum() {
return pageNum;
}

public void setPageNum(int pageNum) {
this.pageNum = pageNum;
}

public int getPageSize() {
return pageSize;
}

public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}

7. 好了,走完上述的步骤,启动项目就可以调试了打开http://localhost:8080/swagger-ui.html查看接口

Spring Data jpa 空值忽略 spring data jpa hibernate_JPA_02

新增用户:/user/add

Spring Data jpa 空值忽略 spring data jpa hibernate_spring_03

Spring Data jpa 空值忽略 spring data jpa hibernate_springdatajpa命名规则_04

查询所有用户:/user/list

Spring Data jpa 空值忽略 spring data jpa hibernate_spring_05

分页查询1:/user/listForPage、分页查询2:/user/listForPageable

Spring Data jpa 空值忽略 spring data jpa hibernate_springdatajpa命名规则_06

Spring Data jpa 空值忽略 spring data jpa hibernate_springdatajpa命名规则_07

总结

好了,以上就是对Spring Data JPA的简单应用,今后在项目中它应用地比较广泛,必须掌握这个技能。

项目地址

https://gitee.com/kaixinshow/springboot-note