文章目录
JPA介绍
ORM映射元数据
JPA的API
JPA、Hibernate、Mybatis的关系
JPA
Hibernate
MyBatis
关系
JPA对象的四种状态和缓存
SpringDataJPA的基础CRUD
添加
修改
删除
查询
SpringDataJPA实现分页
SpringDataJPA实现排序
硬编码形式实现
方法引用形式实现
总结
JPA介绍
JPA(Java Persistence API)是一种用于管理Java应用程序中对象与关系型数据库之间映射的规范。它定义了一组接口和注解,通过这些接口和注解,开发人员可以将Java对象持久化到数据库中,以及从数据库中检索和操作数据。JPA提供了一种统一的编程模型,使得开发人员可以脱离特定的数据库实现,更加关注业务逻辑的实现。
JPA规范为我们提供了:
ORM映射元数据
JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架根据实体对象持久化到数据库中;如:@Entity,@Table,@Id,@Column;
JPA的API
用来操作实体对象,执行CURD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来;
注意:JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的!!!
JPA、Hibernate、Mybatis的关系
JPA(Java Persistence API)、Hibernate和MyBatis是在Java开发中常用的三种数据持久化框架,它们之间存在以下关系:
JPA
一种用于管理Java应用程序中对象与关系型数据库之间映射的规范。它定义了一组接口和注解,通过这些接口和注解,开发人员可以将Java对象持久化到数据库中,以及从数据库中检索和操作数据。JPA提供了一种统一的编程模型,使得开发人员可以脱离特定的数据库实现,更加关注业务逻辑的实现。
Hibernate
一个开源的对象关系映射(ORM)框架,它实现了JPA规范,并扩展了JPA的功能。Hibernate提供了强大的对象关系映射和查询功能,可以将Java对象映射到数据库表中,并提供了丰富的查询语言(HQL和Criteria API)以及缓存机制。在Hibernate中,开发人员可以使用JPA的注解或者Hibernate特有的注解来进行对象和表之间的映射配置。
MyBatis
另一个常用的数据持久化框架,它与JPA和Hibernate有所不同。MyBatis是一个半自动的ORM框架,它通过SQL映射文件将Java对象和数据库表进行映射。开发人员需要手动编写SQL语句,通过配置映射文件来指定对象和表之间的映射关系。MyBatis提供了强大的灵活性和可控性,适用于对SQL语句有较高要求的场景。
关系
可以说Hibernate是JPA的实现之一,它实现了JPA规范并提供了更丰富的功能和特性。开发人员可以选择直接使用Hibernate来进行数据持久化操作,或者使用基于JPA的框架(如Spring Data JPA)来利用Hibernate作为JPA的实现。
相比之下,MyBatis与JPA和Hibernate的关系较为独立。它不是基于JPA规范的实现,而是通过自定义的SQL映射文件来实现对象和表之间的映射。开发人员可以根据具体需求选择使用JPA(包括Hibernate)还是MyBatis来进行数据持久化操作。
JPA对象的四种状态和缓存
在JPA中,持久化实体对象存在四种状态:托管(Managed)、游离(Detached)、新建(New)、删除(Removed)。托管状态表示实体对象受到JPA管理,对其进行的修改会自动同步到数据库;游离状态表示实体对象脱离了JPA管理,对其进行的修改不会同步到数据库;新建状态表示实体对象是在JPA中新创建的,但尚未持久化到数据库;删除状态表示实体对象已经被标记为删除,待下次同步到数据库时将被删除。
JPA还提供了一级缓存(一般是通过Session实现),它缓存了查询过的实体对象,可以提高查询性能。但需要注意的是,一级缓存是在一个事务范围内有效的,当事务提交或回滚后,一级缓存将被清空。
SpringDataJPA的基础CRUD
Spring Data JPA简化了基本的CRUD(Create、Read、Update、Delete)操作。通过使用一组简洁的接口和方法命名规则,可以自动生成常见的数据库操作。例如,定义一个继承自JpaRepository的接口,然后根据方法名的命名规则,即可实现对实体对象的增删改查操作,无需编写具体的实现代码。
public interface CrudRepository<T, ID> extends Repository<T, ID> { <S extends T> S save(S var1); <S extends T> Iterable<S> saveAll(Iterable<S> var1); Optional<T> findById(ID var1); boolean existsById(ID var1); Iterable<T> findAll(); Iterable<T> findAllById(Iterable<ID> var1); long count(); void deleteById(ID var1); void delete(T var1); void deleteAll(Iterable<? extends T> var1); void deleteAll(); }
下面来看一组基本的增删改查实现:
添加
public void addUser(User user){ User userInfo = userRepository.save(user); }
修改
修改和添加可以使用同一个方法,当我们传入的User实体有主键时即为修改,没有主键的时候即为添加
//save————插入和修改,有主键就是修改,没有主键就是插入 public void addUser(User user){ User userInfo = userRepository.save(user); }
删除
//根据传入的实体进行删除 public void delete(User user){ userRepository.delete(user); } //根据主键id进行删除 public void deleteById(String id){ userRepository.deleteById(id); }
查询
//findAll————查询所有实体 public void findAll(){ userRepository.findAll(); } //findAllById————根据id查询所有实体 public void findAllById(){ //这里可以传入多个id,查询出多个id的数据 userRepository.findAllById(Arrays.asList("1","2","3")); } //findById————通过主键查询实体 public void findById(String id){ userRepository.findById(id); }
SpringDataJPA实现分页
Spring Data JPA提供了分页查询的支持。想要实现分页效果,就需要让持久层接口实现PagingAndSortingRepository接口,其中包含了分页以及排序的实现;
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort var1); Page<T> findAll(Pageable var1); }
下面来看一个示例:
//入参:需要传入第几页以及每页的大小 public List<User> page(int page, int size){ Page<User> userRepositoryAll = userRepository.findAll(PageRequest.of(page, size)); //共多少页 System.out.println(userRepositoryAll.getTotalPages()); //共有几条数据 System.out.println(userRepositoryAll.getTotalElements()); return userRepositoryAll.getContent(); }
SpringDataJPA实现排序
除了分页查询,Spring Data JPA还提供了排序查询的支持。通过Sort对象,可以对查询结果按照指定的属性进行排序。在查询方法中,只需将Sort对象作为方法参数,并在查询语句中指定排序的属性,Spring Data JPA会自动处理排序查询并返回排序后的结果。这里有两种形式实现:
硬编码形式实现
一种是通过传入一个表中的字段名来实现,这种方式有一定的缺点,当我们表名改变的时候,这里也需要相应的去做出调整;
public void sort(){ Sort sort = Sort.by("id").descending(); Iterable<User> all = userRepository.findAll(sort); System.out.println(all); }
方法引用形式实现
相对比传字符串来说,这种获取方法引用的形式就更加灵活了;
public void sortType(){ Sort.TypedSort<User> typedSort = Sort.sort(User.class); //User::getId为获取getId这个方法的引用 Sort sort = typedSort.by(User::getId).descending(); Iterable<User> all = userRepository.findAll(sort); System.out.println(all); }
总结
Spring Data JPA是一个强大的数据访问层框架,它简化了数据库操作和持久化实体管理的方式。掌握Spring Data JPA的基础CRUD操作、分页和排序的实现方式,可以更加高效地开发和维护数据库相关的功能。