JPA总结

1. JPA简介

JPA(Java Persistence API)是Java官方提出的ORM(对象关系映射)规范,主要用于简化Java应用中的数据持久化开发。常见实现有Hibernate、EclipseLink等。Spring Data JPA对JPA进行了进一步封装,极大简化了数据库操作。

2. 配置示例

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: admin123
  jpa:
    database-platform: org.hibernate.dialect.MySQL8Dialect
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    show-sql: true
@SpringBootApplication
@MapperScan(basePackages = {"com.dao"})
@EntityScan(basePackages = "com.entity") // 指定实体类所在包
@EnableJpaRepositories(basePackages = "com.dao") // 指定仓库接口所在包
@EnableJpaAuditing
public class SpringbootSchemaApplication extends SpringBootServletInitializer{
    public static void main(String[] args) {
        SpringApplication.run(SpringbootSchemaApplication.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder) {
        return applicationBuilder.sources(SpringbootSchemaApplication.class);
    }
}

3. 常用JPA注解说明

  • @Entity:标记为实体类
  • @Table:指定表名
  • @Id:主键
  • @GeneratedValue:主键生成策略
  • @Column:字段映射
  • @Lob/@Basic:大字段及懒加载
  • @CreatedDate/@LastModifiedDate:自动填充创建/更新时间
  • @EntityListeners:监听实体变化
package com.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.*;
import java.time.LocalDateTime;

/**
 * Author reisen7
 * Date 2025/4/22 12:30
 * Description
 */

@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
@DynamicUpdate
@Table(name = "user_evaluation")
@Entity
@EntityListeners(value = AuditingEntityListener.class)
public class UserEvaluation extends Profile{

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Lob
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "evaluation" , columnDefinition = "text")
    private String evaluation;

    @Column(name = "user_id")
    private Long userId;

    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    @LastModifiedDate
    @Column(name = "update_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

}

4. Repository接口与常用方法

import com.entity.UserEvaluation;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface UserEvaluationRepository extends JpaRepository<UserEvaluation, Long> {
    // 按用户ID查询
    List<UserEvaluation> getUserEvaluationByUserId(Long userId);
    // 还可以自定义更多方法,如:
    // List<UserEvaluation> findByEvaluationContaining(String keyword);
}
  • save(entity) 保存或更新
  • findById(id) 按ID查找
  • findAll() 查询全部
  • deleteById(id) 按ID删除
  • count() 统计数量

5. 分组与复杂查询

public List<GoodsPlatformPrice> getPriceByGoodsId(Long goodsId) {
    Specification<GoodsPlatformPrice> specification = (root, query, criteriaBuilder) -> {
        // 1. 构建查询:选择平台名称和最低价格
        query.multiselect(
            root.get("platformName"),
            criteriaBuilder.min(root.get("price"))
        );
        // 2. 添加商品ID条件
        Predicate goodsPredicate = criteriaBuilder.equal(root.get("goodsId"), goodsId);
        // 3. 添加分组条件
        query.groupBy(root.get("platformName"));
        // 4. 添加排序条件(可选)
        query.orderBy(criteriaBuilder.asc(root.get("platformName")));
        return goodsPredicate;
    };
    return repository.findAll(specification);
}

说明:上述代码通过JPA的Specification实现分组、聚合、排序等复杂查询,适用于动态条件场景。

6. 常见问题与优化建议

  • 实体类必须有无参构造方法,否则JPA无法实例化。
  • @EntityScan/@EnableJpaRepositories 路径要配置正确,否则扫描不到实体或仓库接口。
  • 懒加载异常:建议在Service层处理数据,避免在Controller层直接访问懒加载属性。
  • 批量操作优化:可用@Modifying@Query自定义SQL实现批量更新/删除。
  • 分页查询:可用Pageable参数,返回Page<T>类型。

7. 参考资料

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐