Spring Data JPA

发布于:2025-02-11 ⋅ 阅读:(57) ⋅ 点赞:(0)

JPA是一套规范,内部是有接口和抽象类组成的。

hibernate是一套成熟的ORM框架,而且Hibernate实现了JPA规范,所以也可以称 hibernate 为 JPA 的一种实现方式

Spring Data JPA 是 Spring 提供的一套对JPA操作更加高级的封装。

在这里插入图片描述

1.编写ORM实体类

@Entity(name = "t_comment")
public class Discuss {
    @Id    
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    @Column(name = "a_id")
    private Integer aId;
}

注解:

@Entity
    作用:标注在类上,表示与数据表具有映射关系的实体类,同时默认对应表名为类名的首字母小写形式
@Table
    作用:指定实体类和表之间的对应关系。
    属性:
        name:指定数据库表的名称
@Id
    作用:指定当前字段是主键。
@GeneratedValue
    作用:指定主键的生成方式。。
    属性:
        strategy :指定主键生成策略。
        	- TABLE(使用一个特定的数据库表格来保存主键)
        	- SEQUENCE(不支持主键自增长的数据库主键生成策略)
        	- IDENTITY(主键自增)
        	- AUTOJPA自主选择前面3种合适的策略,是默认选项)
@Column
    作用:指定实体类属性和数据库表之间的对应关系,如果类属性与表字段名相同,则可以省略。
    属性:
        name:指定数据库表的列名称。
        unique:是否唯一  
        nullable:是否可以为空  
        inserttable:是否可以插入  
        updateable:是否可以更新  
        columnDefinition: 定义建表时创建此列的DDL  
        secondaryTable: 从表名。如果此列不建在主表上(默认建在主表),该属性定义该列所在从表的名字搭建开发环境[重点]

2.编写Repository接口

使用 Spring Data JPA,只需要按照框架的规范提供dao接口,不需要实现类就可以完成数据库的增删改查、分页查询等方法。

// 继承XXRepository<T, ID>接口,其中的T代表要操作的实体类,ID代表实体类主键数据类型
public interface DiscussRepository extends JpaRepository<Discuss,Integer> {
    // 上方没有任何注解,属于JPA支持的方法名关键字查询方式
    public List<Discuss> findByAuthorNotNull();  
    
    @Query("SELECT c FROM t_comment c WHERE c.aId = ?1")
    public List<Discuss> getDiscussPaged(Integer aid,Pageable pageable);  
	
    @Query(value = "SELECT * FROM t_comment  WHERE  a_Id = ?1",nativeQuery = true)
    public List<Discuss> getDiscussPaged2(Integer aid,Pageable pageable); 
    
    @Transactional,业务层Service类上已经添加了@Transactional注解进行事务管理,那么Repository接口文件中就可以省略
    @Modifying,注解表示数据的变更操作
    @Query("UPDATE t_comment c SET c.author = ?1 WHERE c.id = ?2")
    public int updateDiscuss(String author,Integer id);  
    
    @Transactional
    @Modifying
    @Query("DELETE t_comment c WHERE c.id = ?1")
    public int deleteDiscuss(Integer id);  
}

在这里插入图片描述

findOne(id) :根据id查询
save(customer):保存或者更新(依据:传递的实体类对象中,是否包含 id 属性)
delete(id) :根据id删除
findAll() : 查询全部

更新字段

https://blog.csdn.net/san_qilang/article/details/119720035

为什么数据库字段设置了默认值,使用springdatajpa的save之后默认值没有生效https://blog.51cto.com/u_12715480/3645964

复杂查询:https://blog.csdn.net/qq_33371766/article/details/111083064

示例:

public PageResponse<StoryBo> PageStory(PageSceneParam param) {
        Sort sort = Sort.unsorted();
        if (StrUtil.isNotBlank(param.getSortBy())) {
            Sort.Direction direction = "desc".equals(param.getSortOrder()) ? Sort.Direction.DESC : Sort.Direction.ASC;
            sort = Sort.by(direction, param.getSortBy());
        }

        Specification<StoryPo> spec = Specification.where(null);

        Specification<StoryPo> commonQuerySpec = (Root<StoryPo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();

            predicates.add(criteriaBuilder.equal(root.get("spaceId"), param.getSpaceId()));
            predicates.add(criteriaBuilder.equal(root.get("tenantId"), param.getTenantId()));
            // 根据不为空的参数构建查询条件
            if (!CollectionUtils.isEmpty(param.getNames())){
                predicates.add(criteriaBuilder.in(root.get("name")).value(param.getNames()));
            }
            if (!CollectionUtils.isEmpty(param.getIds())) {
                predicates.add(criteriaBuilder.in(root.get("id")).value(param.getIds()));
            }
            if (StringUtils.hasText(param.getName())) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%"+param.getName()+"%"));
            }

            if (StringUtils.hasText(param.getCreatedBy())){
                predicates.add(criteriaBuilder.equal(root.get("createdBy"), param.getCreatedBy()));
            }
            if (StringUtils.hasText(param.getStartTime()) && StringUtils.hasText(param.getEndTime())){
                Date startDate = new Date(Long.parseLong(param.getStartTime()));
                Date endDate = new Date(Long.parseLong(param.getEndTime()));
                predicates.add(criteriaBuilder.between(root.get("createdAt"), startDate, endDate));
            }
            if (StringUtils.hasText(param.getQuery())) {
                List<Predicate> orPredicates = new ArrayList<>();
                orPredicates.add(criteriaBuilder.like(root.get("name"), "%"+param.getQuery()+"%"));
                orPredicates.add(criteriaBuilder.like(root.get("desc"), "%"+param.getQuery()+"%"));
                if (NumberUtils.isCreatable(param.getQuery())) {
                    orPredicates.add(criteriaBuilder.equal(root.get("id"), Integer.parseInt(param.getQuery())));
                }
                Predicate orPredicate = criteriaBuilder.or(orPredicates.toArray(new Predicate[0]));   // query是多个条件的或查询
                Predicate andPredicate = criteriaBuilder.and(predicates.toArray(new Predicate[0]));   // 联立其他指定字段的与查询
                return criteriaBuilder.and(orPredicate, andPredicate);
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
        };
        spec = spec.and(commonQuerySpec);

        if (!CollectionUtils.isEmpty(param.getContainTagKeys())) {
            for (String tagKey: param.getContainTagKeys()){
                if (param.getTagKeysRelation().equals("and")){
                    tagKeysSpec = tagKeysSpec.and(hasTagKey(tagKey));
                } else if (param.getTagKeysRelation().equals("or")) {
                    tagKeysSpec = tagKeysSpec.or(hasTagKey(tagKey));
                }else {
                    throw new RuntimeException("not support relation except 'and' and 'or'");
                }
            }
            spec = spec.and(tagKeysSpec);
        }

        Pageable pageable = PageRequest.of(param.getPage() - 1, param.getSize(), sort);
        Page<StoryPo> page = sceneRepo.findAll(spec, pageable);
        List<StoryBo> bos = page.getContent().stream().map(StoryBo::fromPoV2).collect(Collectors.toList());
        return PageResponse.list(bos, page.getTotalElements());
    }

网站公告

今日签到

点亮在社区的每一天
去签到