美文网首页
JPA-常用功能

JPA-常用功能

作者: 矢量演说 | 来源:发表于2020-05-14 00:02 被阅读0次
    • 关于级联(级联删除)

    我始终没研究清楚cascade=CascadeType.PERSIST之类的,有时间待补。
    级联删除cascade写在比较“一”的那边,比如在角色和权限的关系里,写在了角色class里;在部门和角色的关系里写在了部门里。这样操作1的方法时,多的那边就会被带动。

        @JsonBackReference
        @ManyToMany(targetEntity = Permission.class, cascade = CascadeType.ALL, fetch=FetchType.EAGER)
        @JoinTable(name = "employee_role_pms",
                joinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")},
                inverseJoinColumns = {@JoinColumn(name = "pms_id", referencedColumnName = "id")}
        )
        private Set<Permission> permissions = new HashSet<>();
    
    //    // 放弃维护关系
    //    @JsonBackReference
    //    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL)
    //    private Set<Role> roles = new HashSet<>();
    

    放弃维护关系mappedBy写在比较“多”的那边,比如员工和角色的多对多关系中,放弃维护关系的@ManyToMany(mappedBy = "roles")写在角色class里。

        // 放弃维护关系
        @JsonBackReference
        @ManyToMany(mappedBy = "roles")
        private Set<Employee> employees = new HashSet<>();
    
    

    建议逻辑删除,不要物理删除
    在service层写逻辑删除,事务标记。不要全交给jpa自动,性能有影响,还不可控。

    下面这篇没看懂,不过可能会有参考价值
    spring jpa 如何给外键赋值

    • 外键关联查询

    这个时不时会参考一下
    Spring Data Jpa:基础、关联外键查询
    尤其这个好有用:
    After findByStartDateAfter … where x.startDate > ?
    Before findByStartDateBefore … where x.startDate < ?

    基础、关联外键查询
    • Specification复杂查询

    参考黑马JPA的教程,讲得不错
    Spring Data Jpa(2019_idea版)

    • JPA多属性排序查询

    Spring data jpa sort多属性排序问题
    把这三个装有排序条件的order放到list里面,然后把list放到sort里面。这里要注意,添加到list中的先后次序直接关联着排序的优先级。

    • JPA审计功能

    JPA EnableJpaAuditing 审计功能
    Jpa配置实体类创建时间更新时间自动赋值,@CreateDate,@LastModifiedDate

    1. 实体类上添加 @EntityListeners(AuditingEntityListener.class)
    2. 在需要的字段上加上 @CreatedDate、@CreatedBy、@LastModifiedDate、@LastModifiedBy 等注解。(经过测试如果你的实体类上面的多个字段使用了 @CreatedBy 这样的注解,只会有一个生效,也就是说在一次请求中,只会被调用一次)
    3. 在Xxx Application 启动类上添加 @EnableJpaAuditing
    4. 实现 AuditorAware 接口来返回你需要插入的值。重点!
      ————————————————
      版权声明:本文为CSDN博主「niceyoo」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
      原文链接:https://blog.csdn.net/niceyoo/article/details/90452669

    一下是第四步的工作,我把它放在了config文件夹下。

    @Configuration
    @Slf4j
    public class UserAuditor implements AuditorAware<String> {
        /**
         * 获取当前创建或修改的用户
         * @return
         */
        @Override
        public Optional<String> getCurrentAuditor() {
            UserDetails user;
            try {
                user = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
                return Optional.ofNullable(user.getUsername());
            }catch (Exception e){
                return Optional.empty();
            }
        }
    }
    
    • JPA外键关系

    @OneToMany时“一”的那一方放弃维护权
    建议别放弃了,删了吧,经常内存溢出死循环,但是有时候又会要从一的那一方获取多的list或者set,又挺方便的,以后试试写着然后放弃维护权

    OneToMany
    @OneToOne时添加unique=true
    OneToOne
    @ManyToMany时中断序列化
    JPA的多对多映射

    JPA中使用@ManyToMany来注解多对多的关系,由一个关联表来维护。这个关联表的表名默认是:主表名+下划线+从表名。(主表是指关系维护端对应的表,从表指关系被维护端对应的表)。这个关联表只有两个外键字段,分别指向主表ID和从表ID。字段的名称默认为:主表名+下划线+主表中的主键列名,从表名+下划线+从表中的主键列名。
    需要注意的:
      1、多对多关系中一般不设置级联保存、级联删除、级联更新等操作。
      2、可以随意指定一方为关系维护端,在这个例子中,我指定Player为关系维护端,所以生成的关联表名称为: player_game,关联表的字段为:player_id和game_id。
      3、多对多关系的绑定由关系维护端来完成,即由Player.setGames(games)来绑定多对多的关系。关系被维护端不能绑定关系,即Game不能绑定关系。
      4、多对多关系的解除由关系维护端来完成,即由Player.getGames().remove(game)来解除多对多的关系。关系被维护端不能解除关系,即Game不能解除关系。
      5、如果Player和Game已经绑定了多对多的关系,那么不能直接删除Game,需要由Player解除关系后,才能删除Game。但是可以直接删除Player,因为Player是关系维护端,删除Player时,会先解除Player和Game的关系,再删除Player。

    多对多关系中的删除必须从维护端进行删除操作。
    Spring-data-jpa多对多双向关联时出现死循环,内存溢出
    解决方法:中断循环即可,首先这不是jpa的问题,是序列化的问题,我们只要中断序列化就可以了,在user类中使用jackson的注解@JsonIgnoreProperties(value = {"users"})

            @JsonIgnoreProperties(value = {"users"})
        @ManyToMany(fetch=FetchType.EAGER)
        @JoinTable(name="SysUserRole", 
                    joinColumns= {@JoinColumn(name="uid", referencedColumnName="uid")}, 
                    inverseJoinColumns= {@JoinColumn(name="roleId", referencedColumnName="id")})
        private List<SysRole> roleList;
    
    • JPA使用原生Query语句

    更新操作:
    @query
    @modifying
    +dao层


    Query语句[图片上传中...(Image.png-c4766a-1589522779500-0)]
    测试该dao语句
    • JPA实现分页

    Spring Boot2.0 JPA 实现分页(简单查询分页、复杂查询分页)

    • JPA查询结果为Optional类型

    关于springboot中引用jpa默认查询单个语句时返回值Optional转换的问题
    简而言之就是对optional对象进行.get()操作。

    • JPA查询结果为Page类型

    JPA的分页返回的是Page类型,但layui前端需要的Results里要包含的是List而不能是Page,同时又要拿到给pageable的offset和limit。
    Spring boot 使用jpa分页查询,不需要写SQL语句, 正确使用 Pageable,以及 Page转换为List

    Pageable pageable = PageRequest.of(Integer.parseInt(page), Integer.parseInt(limit));
    Page<PicInfo> allPicturesPage = picDao.findAll(pageable);
    List<PicInfo> allPictures = allPicturesPage.getContent();
    
    • JPA无法删除或更新parent row

    报错:JPA Cannot delete or update a parent row: a foreign key constraint fails
    JPA Cannot delete or update a parent row: a foreign key constraint fails
    通常是因为要删的数据是别的数据的外键,所以删不了,应该先处理外键关系,再进行删除或更新。

    • JPA创建外键后,数据库中只保存了索引,未保存外键

    解决SpringJPA不能保存外键,只保存索引的问题

    #在数据库中自动生成外键,加上之前只有索引
    spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
    

    相关文章

      网友评论

          本文标题:JPA-常用功能

          本文链接:https://www.haomeiwen.com/subject/wxganhtx.html