当前位置: 首页 > news >正文

JPA 的说明和使用

JPA 的说明和使用

JPA(Java Persistence API)是Java的ORM规范,用面向对象的方式操作数据库,不用写繁琐的SQL。

核心思想:对象即数据

// 操作对象 = 操作数据库
User user = new User("张三", "zhangsan@email.com");
userRepository.save(user);  // 自动生成 INSERT SQLList<User> users = userRepository.findByName("张三"); // 自动生成 SELECT SQL

一、JPA详细使用
1.实体类定义

@Entity
@Table(name = "users")  // 对应数据库表
public class User {// 写法一:主键自增@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;// 写法二:主键uuid@Id@GeneratedValue(generator = "system-uuid")@GenericGenerator(name = "system-uuid", strategy = "uuid")@Column(name = "ID", length = 50, nullable = false)private String id;@Column(name = "user_name", length = 50, unique = true, nullable = false)private String username;private String email;private Integer age;@Enumerated(EnumType.STRING)  // 枚举存储为字符串private UserStatus status;@CreationTimestamp  // 自动设置创建时间private LocalDateTime createTime;@UpdateTimestamp    // 自动更新修改时间private LocalDateTime updateTime;// 必须有无参构造器public User() {}// 有参构造器public User(String username, String email) {this.username = username;this.email = email;}// getter/setter 省略...
}enum UserStatus {ACTIVE, INACTIVE, DELETED
}

2.关联关系配置

// 一对多关系
@Entity
public class User {@Idprivate Long id;// 一个用户有多个订单@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)private List<Order> orders = new ArrayList<>();
}@Entity
public class Order {@Idprivate Long id;// 多个订单属于一个用户@ManyToOne@JoinColumn(name = "user_id")  // 外键private User user;private BigDecimal amount;
}

二、JPA常用方法大全
1.基础CRUD方法

public interface UserRepository extends JpaRepository<User, Long> {// === 增删改 ===// 保存(新增或更新)User save(User user);List<User> saveAll(List<User> users);// 删除void delete(User user);void deleteById(Long id);void deleteAll();void deleteAll(List<User> users);// === 查询 ===// 根据ID查询Optional<User> findById(Long id);boolean existsById(Long id);// 查询所有List<User> findAll();List<User> findAllById(List<Long> ids);// 计数long count();
}

2.方法名派生查询(最强大!)

public interface UserRepository extends JpaRepository<User, Long> {// === 基本查询 ===List<User> findByUsername(String username);User findFirstByUsername(String username);  // 查询第一条Optional<User> findOneByUsername(String username);// === 条件查询 ===List<User> findByAgeGreaterThan(Integer age);           // 大于List<User> findByAgeLessThanEqual(Integer age);         // 小于等于List<User> findByAgeBetween(Integer start, Integer end); // 区间List<User> findByUsernameLike(String pattern);          // 模糊查询List<User> findByEmailContaining(String keyword);       // 包含List<User> findByUsernameStartingWith(String prefix);   // 开头匹配List<User> findByUsernameEndingWith(String suffix);     // 结尾匹配// === 多条件查询 ===List<User> findByUsernameAndAge(String username, Integer age);List<User> findByUsernameOrEmail(String username, String email);List<User> findByAgeGreaterThanAndStatus(Integer age, UserStatus status);// === 空值检查 ===List<User> findByEmailIsNull();List<User> findByEmailIsNotNull();// === IN 查询 ===List<User> findByStatusIn(List<UserStatus> statusList);List<User> findByAgeIn(Integer[] ages);// === 排序 ===List<User> findByStatusOrderByCreateTimeDesc(UserStatus status);List<User> findByAgeGreaterThanOrderByAgeAscCreateTimeDesc(Integer age);// === 分页 ===Page<User> findByStatus(UserStatus status, Pageable pageable);Slice<User> findByAgeGreaterThan(Integer age, Pageable pageable);// === 限制数量 ===List<User> findFirst10ByStatus(UserStatus status);List<User> findTop5ByAgeGreaterThanOrderByAgeDesc(Integer age);
}

3.自定义查询

public interface UserRepository extends JpaRepository<User, Long> {// === @Query 注解查询 ===// JPQL 查询(面向对象)@Query("SELECT u FROM User u WHERE u.age > :age AND u.status = :status")List<User> findAdultUsers(@Param("age") Integer age, @Param("status") UserStatus status);// 原生 SQL 查询@Query(value = "SELECT * FROM users u WHERE u.create_time > :date", nativeQuery = true)List<User> findUsersAfterDate(@Param("date") LocalDateTime date);// 投影查询(只返回部分字段)@Query("SELECT u.username, u.email FROM User u WHERE u.status = 'ACTIVE'")List<Object[]> findActiveUserInfo();// DTO 投影查询@Query("SELECT new com.example.UserDTO(u.username, u.email) FROM User u")List<UserDTO> findUserDTOs();// === 修改操作 ===@Modifying@Query("UPDATE User u SET u.status = :status WHERE u.id = :id")int updateUserStatus(@Param("id") Long id, @Param("status") UserStatus status);@Modifying@Query("DELETE FROM User u WHERE u.status = :status")int deleteByStatus(@Param("status") UserStatus status);
}

4.复杂查询示例

public interface UserRepository extends JpaRepository<User, Long> {// 复杂分页查询@Query("SELECT u FROM User u WHERE " +"(:username IS NULL OR u.username LIKE %:username%) AND " +"(:minAge IS NULL OR u.age >= :minAge) AND " +"(:maxAge IS NULL OR u.age <= :maxAge)")Page<User> searchUsers(@Param("username") String username,@Param("minAge") Integer minAge,@Param("maxAge") Integer maxAge,Pageable pageable);// 统计查询@Query("SELECT COUNT(u) FROM User u WHERE u.status = :status")long countByStatus(@Param("status") UserStatus status);@Query("SELECT u.status, COUNT(u) FROM User u GROUP BY u.status")List<Object[]> countUsersByStatus();
}

5.服务层使用实例

@Service
@Transactional
public class UserService {@Autowiredprivate UserRepository userRepository;public void demoUsage() {// 1. 新增User user = new User("李四", "lisi@email.com");user.setAge(25);userRepository.save(user);// 2. 查询List<User> youngUsers = userRepository.findByAgeLessThanEqual(30);Optional<User> userOpt = userRepository.findByUsername("李四");// 3. 分页查询Page<User> userPage = userRepository.findByStatus(UserStatus.ACTIVE, PageRequest.of(0, 10, Sort.by("createTime").descending()));// 4. 更新user.setEmail("new_email@example.com");userRepository.save(user);  // 自动更新// 5. 删除userRepository.delete(user);}
}

三、JPA vs Mybatis详细对比
1.开发模式对比

方面JPAMybatis
思维模式面向对象面向SQL
查询方式方法名/JPQLXML/注解SQL
数据库变更影响较小影响较大
学习曲线较陡峭较平缓

2.代码对比实例
JPA方式

// Repository 接口
List<User> findByAgeBetweenAndStatusOrderByCreateTimeDesc(Integer minAge, Integer maxAge, UserStatus status);// 使用
List<User> users = userRepository.findByAgeBetweenAndStatusOrderByCreateTimeDesc(18, 30, UserStatus.ACTIVE);

Mybatis方式

<!-- Mapper XML -->
<select id="selectUsersByCondition" resultType="User">SELECT * FROM users WHERE age BETWEEN #{minAge} AND #{maxAge} AND status = #{status}ORDER BY create_time DESC
</select>
// Mapper 接口
List<User> selectUsersByCondition(@Param("minAge") Integer minAge,@Param("maxAge") Integer maxAge,@Param("status") String status);

3.性能对比

场景JPAMybatis
简单CRUD效率极高需要写SQL
复杂查询JPQL可能性能差SQL可精细优化
关联查询容易N+1问题可手动优化JOIN
批量操作需要配置直接批量SQL

4.适用场景总结
选择JPA

1.业务模型复杂,对象关系多 
2.需要快速开发标准CRUD
3.团队熟悉面向对象设计 
4.可能更换数据库

选择Mybatis

1.复杂SQL、存储过程需求多 
2.需要精细控制SQL性能 
3.遗留数据库表结构复杂 
4.团队SQL能力强

四、实际建议
1.新项目推荐

# 微服务架构选择:
用户服务: JPA          # 业务复杂,对象关系多
订单服务: JPA          # 事务要求高
报表服务: MyBatis      # 复杂查询,需要SQL优化

2.混合使用策略

// JPA 处理标准业务
public interface UserRepository extends JpaRepository<User, Long> {// 标准CRUD
}// MyBatis 处理复杂查询  
public interface UserReportMapper {// 复杂报表查询List<UserReportDTO> getUserComplexReport(ReportQuery query);
}

总结
JPA核心优势:

1.开发效率:方法名即查询,减少80%的SQL编写 
2.维护性:对象变更自动同步到数据库 
3.类型安全:编译时检查,减少运行时错误
4.标准化:代码更规范,易于团队协作

使用建议:

1.掌握方法名规则:解决大部分查询需求
2.合理使用关联:避免N+1查询问题 
3.复杂查询用@Query:保持代码清晰 
4.注意事务管理:保证数据一致性
http://www.dtcms.com/a/592983.html

相关文章:

  • MyBatis使用LocalDateTime会报错
  • web网页开发,在线财务管理系统,基于Idea,html,css,jQuery,java,ssm,mysql。
  • 2025汉化idea创建JSP项目
  • 如何高效处理日常 PDF 文档?
  • LeetCode 2342.数位和相等数对的最大和
  • 企业网站建设需了解什么软文投放平台有哪些?
  • pink老师html5+css3day07
  • 各个手机芯片型号
  • [Qt学习笔记]Qt5.15.2版本安装及调整组件
  • C语言--文件读写函数的使用,对文件读写知识有了更深的了解。
  • WEBweb前端OPPO手机商城网站项目
  • 虚拟技术 云手机是指什么?
  • 传播易网站开发方案饿了么网站做生鲜吗
  • 制作网站的网站fullpage网站怎么做
  • 【element-plus】element-plus升级到v2.11.7,el-tree文字不显示问题
  • 服务器接收用户注册信息教程
  • 【Linux系统编程】进程概念(四)进程优先级、进程切换、环境变量和程序地址空间
  • 数据结构(18)
  • 网站页面制作自己做的网站能卖么
  • 大型省级政务平台采用金仓数据库(KingbaseES)
  • K8s 中创建一个 Deployment 的完整流程
  • 想做网站制作运营注册什么公司核实国内网站建设推荐
  • 操作系统?进程地址空间!!!
  • 进阶指南:API 批量调用优化方案(并发控制 + 重试机制 + 限流策略)
  • C++---强类型枚举(scoped enumeration)enum class
  • FFmepg--20-合成H.264视频和AAC音频和时间基转化
  • 深入理解MQTT内核和实现实时通信实战:物联网消息推送的秘密武器
  • 乐云seo模板网站建设主流网站开发技术
  • 第二届数证杯物联网取证+网络流量取证
  • 宁夏住房和城乡建设厅网站首页公司主页和公司网站