• Spring Data JPA


    定义

    • JPA:Java Persistence API, 一套规范, 用于对象持久化的API. 内部由接口和抽象类组成 (通过 JDK 5.0 注解描述对象和表的映射关系),底层需要 Hibernate 作为其实现类完成数据持久化工作.
    • Hibernate是一套成熟的 ORM 开放源代码的对象关系映射框架,将 POJO 与数据库表建立映射关系,而且 Hibernate 实现了 JPA 规范,所以也可以称 Hibernate 为 JPA的一种实现方式,我们使用 JPA 的 API 编程,意味着站在更高的角度上看待问题(面向接口编程)。Hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库
    • Spring Data JPA是 Spring 提供的一套对 JPA 操作更加高级的封装,是在 JPA 规范下的专门用来进行数据持久化的解决方案

    使用

    • 扫描
      Entity 类、Repository 类会被自动扫描到并注册到 Spring 容器, 此时无需额外配置. 当不在同一包或不在子包下时, 需要分别通过在启动类上加注解 @EntityScan(basePackages = {“xxx.xxx”}) 允许多处有交集、@EnableJpaRepositories(basePackages = {“xxx.xxx”}) 允许多处不能交集 来分别指定 Entity、Repository 类的包名

    • JPA 不用 @Repository

      • Spring 通过扩展 Repository 接口来识别存储库, 接口仅仅是一个标识, 表明任何继承它的均为仓库接口类
      • @NoRepositoryBean 注释是为了防止 Spring 将 Repository 扩展接口(如 CrudRepository) 视为存储库
      • 最好搭配 @Resource 注解注入

    spring 有两种方式识别dao层,一种是注解的 @Repository,一种是继承 Repository 接口.
    然而, 大多数框架都有自己的一套扫描规则, 实际不用使用 @Repository, 如 Mybatis 有@MapperScanner 扫描后自动注入

    实体类注解

    • @Entity:指定当前类为实体类
    • @Table:指定实体类与数据库表映射关系
      • schema:数据库名
      • name:数据库表名
        以上两个可以简写为: @Entity(“table_name”)

    实体类属性

    • @Id:当前主键字段
    • @GeneratedValue:
      • strategy:主键生成策略
        • GenerationType.AUTO:auto_increment
        • GenerationType.IDENTITY:表自增长,不支持Oracle
        • GenerationType.SEQUENCE:序列生成主键,不支持MySQL
        • GenerationType.TABLE:数据库表生成主键,框架借由表模拟序列生成主键
    • @Column:建立实体类属性与数据库表字段映射关系,无此字段也会将字段映射到表列。当实体的属性与其映射的数据库表的列不同名时需要使用 @Column 标注说明
      • name:指定映射的数据库表字段
      • unique:是否唯一
      • nullable:是否为空
      • insertable:是否可插入
      • updatable:是否可更新
    • @Convert(converter = UserStatus.class):Entity中将任意对象映射为一个数据库字段
      在这里插入图片描述

    JPA命名查询原理

    • 方法名解析原理:方法名中除了保留字(findBy、top、within等)外的部分以 and 为分隔符提取出条件单词,然后解析条件获取各个单词并看是否和 Entity 中的属性对应(不区分大小写进行比较)

    get/find 与 by之间的字段会被忽略:getNameById == getById,会根据 id 查出整个Entity而不会只查 name 字段

    JPA的 select 操作

    Repository 中 @Query

    JPA的 update 操作

    Repository 中 @Modifying + @Query

    JpaRepository

    findOne()与getOne():findOne立即加载;getOne延迟加载

    表关系

    • 一对一:@OneToOne
    • 一对多:@OneToMany
    @OneToMany(targetEntity = LinkMan.class)
    @JoinColumn(name = "外键名称" referencedColumnName = "cust_id")
    private Set<LinkMan> linkMans = new HashSet<>();
    
    • 1
    • 2
    • 3
    • 多对一:@ManyToOne
    @ManyToOne(targetEntity = Customer.class)
    @JoinColumn(name = "外键名称" referencedColumnName = "cust_id")
    private Customer customer;
    
    • 1
    • 2
    • 3

    @JoinColumn/@PrimaryKeyJoinColumn、@MapsId

    • @JoinColumn用来指定外键,其name属性指定该注解所在Entity对应的表的一个列名

    • 外键属性不是主键的场景(第一种),用 @OneToOne/@ManyToOne + @JoinColumn 即可,为了简洁推荐不用@MapIds,示例见上面的school_id关联school id设置

    • 外键属性是主键的场景(第二种),用 @OneToOne + @JoinColumn + @MapsId ,示例见上面的student id关联user id设置

    • 在一对多或一对一的关系映射中,如果不表明mappedBy属性,默认是由本方维护外键。

    • 将维护权交给多的一方. 在一的一方配置上 mappedBy 属性,将维护权交给多的一方来维护

    在这里插入图片描述

    条件查询

    • 模糊查询

    对于单字段的可以直接在方法名加Containing

    @Query("select s from SchoolEntity s where s.customerId=?1 and (?2 is null or s.name like %?2% or s.bz like %?2%  ) ")
    List<User> getByUserId(String userId, Pageable pageable);
    
    • 1
    • 2
    • In查询
    @Query( "select * from student where id in ?1", nativeQuery=true)
    //@Query( "select s from StudentEntity s where s.id in ?1")
    List<StudentEntity> myGetByIdIn(Collection<String> studentIds );//复杂查询,自定义查询逻辑
    
    List<StudentEntity> getByIdIn( Collection<String> studentIds );//简单查询,声明语句即可
    
    • 1
    • 2
    • 3
    • 4
    • 5

    级联操作

    用于有依赖关系的实体间(@OneToMany、@ManyToOne、@OneToOne)的级联操作:当对一个实体进行某种操作时,若该实体加了与该操作相关的级联标记,则该操作会传播到与该实体关联的实体(即对被级联标记的实体施加某种与级联标记对应的操作时,与该实体相关联的其他实体也会被施加该操作)。包括:

    @OneToMany(targetEntity = LinkMan.class, cascade = CascadeType.ALL)
    @JoinColumn(name = "外键名称" referencedColumnName = "cust_id")
    private Set<LinkMan> linkMans = new HashSet<>();
    
    • 1
    • 2
    • 3
    • CascadeType.PERSIST:持久化,即保存
    • CascadeType.REMOVE:删除当前实体时,关联实体也将被删除
    • CascadeType.MERGE:更新或查询
    • CascadeType.REFRESH:级联刷新,即在保存前先更新别人的修改:如Order、Item被用户A、B同时读出做修改且B的先保存了,在A保存时会先更新Order、Item的信息再保存。
    • CascadeType.DETACH:级联脱离,如果你要删除一个实体,但是它有外键无法删除,你就需要这个级联权限了。它会撤销所有相关的外键关联
    • CascadeType.ALL:上述所有

    注:级联应该标记在One的一方 。如对于 @OneToMany的Person 和 @ManyToOne的Phone,若将- CascadeType.REMOVE标记在Phone则删除Phone也会删除Person,显然是错的。慎用CascadeType.ALL,应该根据业务需求选择所需的级联关系,否则可能酿成大祸

  • 相关阅读:
    python公司员工考勤工资管理系统django662
    基于Simulink的风电机组变桨距控制系统仿真研究
    开源模型应用落地-FastAPI-助力模型交互-WebSocket篇(三)
    《vtk9 book》 官方web版 第3章 - 计算机图形基础 (3 / 5)
    传奇单机架设教程及游戏GM设置方法
    Vue学习(二十)vuex
    Dify快速接入微信
    全网最全系统MySQL5.7.17安装教程配置(配详细的图文解释)
    JavaEE初阶——Linux(基础指令)
    高清实拍类型视频素材去哪里找?高清实拍素材网站分享
  • 原文地址:https://blog.csdn.net/howeres/article/details/125405465