JPA总结

1. JPA简介

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

2. 配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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:监听实体变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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接口与常用方法

1
2
3
4
5
6
7
8
9
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. 分组与复杂查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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. 参考资料