目录
JpaRepository 接口常用 API
org.springframework.data.jpa.repository.JpaRepository 接口常用 API | |
List<T> findAll() | 查询所有数据。如果表中无数据,则返回一个空的 list。默认升序。 |
Optional<T> findById(ID var1) | 通过主键id查询,如果数据不存在,则 Optional.isPresent() 返回 false |
List<T> findAll(Sort sort) | 查询所有数据,同时指定排序字段。如 Sort.by(Sort.Direction.DESC, "tvId") 以 tvId 倒序查询。 |
T getOne(ID id) | 根据主键id查询。如果id对应的数据不存在,则抛异常:EntityNotFoundException。慎用 |
<S extends T> Optional<S> findOne(Example<S> example) | 条件查询单条数据。以实体中非null字段为条件,如果所有字段都为null,表示查询所有。结果多余1条时,抛出异常:NonUniqueResultException。慎用 |
<S extends T> List<S> findAll(Example<S> example) | 条件查询。通过 Example 中的指定的实体中的非 null 字段作为调节进行查询。不存在时,返回一个空list。如果实体的所有字段都为null,则默认查询所有。 |
<S extends T> List<S> findAll(Example<S> example, Sort sort) | 条件查询的同时加上排序。值不存在时,返回一个空列表。 |
Page<T> findAll(Pageable pageable) | 分页查询。Pageable 可以设置查询的页码以及每页的大小,同时还可以指定 Sort 排序。无数据时不影响,不会出现空指针异常。 |
<S extends T> Page<S> findAll(Example<S> example, Pageable pageable) | 条件查询 加 分页,Pageable 可以设置排序字段。 |
<S extends T> S save(S var1) | 添加与修改。如果实体的主键为null,直接新增数据;如果id不为null,则查询数据库是否有此id,有则修改,没果则新增(主键以主键生成策略进行生成) |
<S extends T> List<S> saveAll(Iterable<S> entities) | 同时 save 多条数据 |
S saveAndFlush(S entity) | 保存实体并立即刷新更改。返回保持的实体对象,数据库中自增的主键也会返回到实体中,可以直接取。 |
void deleteById(ID var1) | 根据主键id删除数据。如果id不存在,则抛异常:EmptyResultDataAccessException |
void delete(T entity) | 根据实体的主键id删除数据(主键以外的属性无效)。实体对应的主键不存在时,不会抛异常。 |
void deleteAll(Iterable<? extends T> entities) | 根据多个实体的主键同时删除多条数据。值不存在时,不影响。 |
void deleteInBatch(Iterable<T> entities) | 根据实体主键id批量删除。值不存在时,不影响。 |
void deleteAllInBatch() | 批量删除表中所有数据。表中无数据时,不影响。 |
void deleteAll() | 删除表中所有数据。表中无数据时,也不会有影响 |
boolean existsById(ID var1) | 判断某个主键是否存在 |
long count() | 查询表中记录条数。表中无数据时,返回0 |
环境准备 与 配置
1、下面以 Spring boot 2.1.4 + Spring Data JPA 操作 h2 数据库为例进行说明,准备环境如下:
2、pom.xml 文件内容如下(https://gitee.com/wangmx1993/h2-smil/blob/master/pom.xml):
<!-- Spring Data JPA 内部依赖会 jdbc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--h2 内存数据库,不用安装即可使用的数据库-->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
3、application.yml 配置文件内容如下(在线源码):
spring:
#数据源配置
datasource:
username: nasa
password: 123456
url: jdbc:h2:~/test1 #数据库默认在当前用户目录下,数据库不存在时会自动新建
driver-class-name: org.h2.Driver
#JPA配置
jpa:
show-sql: true
hibernate:
ddl-auto: update
实体 Entity 与 持久化层
1、实体类在线源码:https://gitee.com/wangmx1993/h2-smil/blob/master/src/main/java/com/wmx/entity/Tv.java
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.util.Date;
/**
* Created by Administrator on 2019/2/27 0027.
* 1、电视机实体。应用启动时自动,配置文件中配置 ddl-auto: update:如果数据库不存在,则自动新建,否则不再新建。
* 2、javax.persistence.Entity、javax.persistence.Id 注解必须要写,否则启动报错!
*/
@Entity
public class TV {
@Id//标识为主键
@GeneratedValue(strategy = GenerationType.AUTO)//指定主键生成的方式,AUTO 指定 H2 数据库主键自动增长
private Integer tvId;//电视id,主键
/**
* 下面没标识的属性都会以默认值和数据库表的字段进行映射对应
* 如果修改默认值,又不属性的,可以参考:https://blog.csdn.net/wangmx1993328/article/details/82048775
* 中的 "domain Area" 部分
*/
private String tvName;//电视名称
private Float tvPrice;//电视价格
private Date dateOfProduction;//生产日期
//省略 getter、setter 方法未粘贴
}
2、持久化层接口继承 JpaRepository(在线源码):
import com.wmx.entity.TV;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* 继承 JpaRepository 即可,即可以获得其所有的 CRUD 方法,包括分页,排序等方法
*/
public interface TVRepository extends JpaRepository<TV, Integer> {
}
Service 层接口与实现
1、业务层接口在线源码:https://gitee.com/wangmx1993/h2-smil/blob/master/src/main/java/com/wmx/service/TvService.java
2、业务层实现在线源码:https://gitee.com/wangmx1993/h2-smil/blob/master/src/main/java/com/wmx/service/impl/TvServiceImpl.java
3、其中包含了平时需要用到的常用 CRUD 方法。
控制器层 Controller 接口
1、在线源码: https://gitee.com/wangmx1993/h2-smil/blob/master/src/main/java/com/wmx/controller/TvController.java
映射关系
1、JPA定义了 one-to-one、one-to-many、many-to-one、many-to-many 4种关系。可使用joinColumns来标注外键、使用 @Version来实现乐观锁。
2、关联关系还可以定制延迟加载和级联操作的行为。
3、通过设置fetch=FetchType.LAZY 或 fetch=FetchType.EAGER 来决定关联对象是延迟加载或立即加载。
4、通过设置cascade={options}可以设置级联操作的行为。其中options可以是以下组合:
CascadeType.MERGE 级联更新
CascadeType.PERSIST 级联保存
CascadeType.REFRESH 级联刷新
CascadeType.REMOVE 级联删除
CascadeType.ALL 级联上述4种操作
JPA One to One
1、Jpa 中使用 @OneToOne 注解配置一对一关系,需要在哪方设置外键,则将其定义在哪方,下面以 学生(Student)与餐卡(MealCard)为例进行演示,一个学生一张餐卡。
2、实际生产中很少会有人使用 JPA 配置来自动建表,所以像里面的级联操作等配置其实并不需要太关心,只能配出关联关系即可。(完整源码)
/**
* 学生餐卡实体类
* 与 {@link Student} 是一对一关系,一个学生一张餐卡
* <p>
* * @Entity :告诉 JPA 本类是一个与数据库表进行映射的实体类,而不是普通的 Java Bean
* * 1、当实体类名称是驼峰命名,且没有使用 @Table 指定表名,则默认表名为 meal_card
*
* @author wangMaoXiong
* @version 1.0
* @date 2021/5/16 15:55
*/
@Entity
public class MealCard {
//定义主键及主键生成规则
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private String mid;//参考卡号
private Date createTime;//制卡日期
//省略 getter、setter 方法等未粘贴
}
/**
* 学生实体类
* * @Entity :告诉 JPA 本类是一个与数据库表进行映射的实体类,而不是普通的 Java Bean
*
* @author wangMaoXiong
* @version 1.0
* @date 2021/5/16 15:50
*/
@Entity
public class Student {
//定义主键及生成规则
@Id
@GeneratedValue(strategy = GenerationType.TABLE)
private String sid;//学生ID
@Column(nullable = false, length = 64)
private String name;//姓名
private Date birthday;//出生日期
private Integer sexCode;//性别:1是男,0是女
/**
* 1、需要在哪一方建外键,则在哪一方设置 @OneToOne 注解
* 2、cascade 属性表示级联操作选项,经过实测,这个属性似乎并没有生效,不过没有关系,可以自动手动去数据库修改即可。
*
* @JoinColumn 表示关联字段,属性用途如下:
* A)name:指定【meal_card】表中外键的名称,默认为"关联表名称_关联表字段名称",即默认为 "student_sid"
* B)referencedColumnName:指定关联【student】表中的什么字段,默认为对方主键,即默认为 "sid"
* C)nullable:外键值是否可以为空,默认为 true
* D)@JoinColumn 注解可以省略不写,则默认会在【student】表中新建外键 meal_card_mid 并关联【MealCard】表的主键 mid
*/
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "meal_card_mid", referencedColumnName = "mid", nullable = true)
private MealCard meal_card;
//省略 getter、setter 方法等未粘贴
}