JPA、Hibernate和Spring Data JPA关系
JPA
JPA全称是Java Persistence API,即java持久化API,是sun公司推出的一套基于ORM的规范,内部由一系列的接口和抽象类构成。JPA仅仅是一种规范
Hibernate
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate实现了JPA规范
spring data jpa
spirng data jpa是spring提供的一套简化JPA开发的框架,按照约定好的【方法命名规则】写dao层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。同时提供了很多除了CRUD之外的功能,如分页、排序、复杂查询等等。Spring Data JPA是对JPA进行更高级的封装
总结
在SpringData中,提供了一套统一的接口来实现对数据访问层的操作,就是Repository接口。在接口中提供了基本的CRUD,查询,排序和分页的相关操作。
SpringData Jpa的默认实现就是Hibernate。简单来说就是:SpringData Jpa 实现了 SpringData,Hibernate 又实现了 SpringData Jpa。所以最终干活的实际上是 Hibernate。
SpringBoot中Jpa的基本使用
1.创建项目 导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
2.编写配置文件
#通用数据源配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_jpa?charset=utf8mb4&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
# JPA 相关配置
# 将默认的存储引擎切换为 InnoDB
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
# 控制是否打印运行时的SQL语句与参数信息
spring.jpa.show-sql=true
# 控制是否可以基于程序中Entity的定义自动创建或者修改DB中表结构
spring.jpa.hibernate.ddl-auto=update
3.建立数据实体类
@Data //lombok 注解 生成get set 等
@Entity //告诉JPA这是一个实体类(一个和数据表映射的类)
@Table(name = "t_user") //配置当前实体类和哪张表对应;可以省略不写,如果省略默认表名和实体的名称保持一致。
@EntityListeners(value = AuditingEntityListener.class) //开启自动审计
public class UserEntity {
@Id //代表这是主键
@GeneratedValue(strategy = GenerationType.IDENTITY) //主键生成规则 IDENTITY 自增
private Long id;
@Column(length = 32) //声明了字符字段的长度。如果不这么声明,则系统会采用 255 作为该字段的长度
private String name;
private String password;
@CreatedDate
private Date createTime;
@LastModifiedDate
private Date updateTime;
}
基本常用注解使用见上面的注释,其他注解可以用到再查询
4.实现一个持久类
在 Spring Data JPA 的世界里,实现一个持久层的服务是一个非常简单的事情。以上面的 UserDO 实体对象为例,我们要实现一个增加、删除、修改、查询功能的持久层服务,那么我只需要声明一个接口,这个接口继承org.springframework.data.repository.Repository 接口或者他的子接口就行,其中 T 是数据库实体类,ID 是数据库实体类的主键。 然后再简单的在这个接口上增加一个 @Repository 注解就结束了。
@Repository
public interface UserDao extends JpaRepository<UserDO, Long> {
}
一行代码也不用写。那么针对 UserDO 这个实体类,我们已经拥有常规的增删改查的功能
userRepository.findAll();
userRepository.findOne(1l);
userRepository.save(user);
userRepository.delete(user);
userRepository.count();
userRepository.exists(1l);
5.启动类增加自动审计注解,实现自动填充功能(可选)
@EnableJpaAuditing //利用jpa可以给MySQL列属性自动赋值,例如一些创建时间,修改时间
@SpringBootApplication
public class AuthorityCenterApplication {
public static void main(String[] args) {
SpringApplication.run(AuthorityCenterApplication.class, args);
}
}
6.单元测试
第一个是插入,第二个是查询,执行完第一个可以到数据库刷新下看是否有数据插入
@SpringBootTest
class SpringJpaApplicationTests {
@Autowired
private UserRepository userRepository;
@Test
void contextLoads() {
}
/**
* 新增操作
*/
@Test
void testSave() {
UserEntity user = new UserEntity();
user.setName("王五");
user.setPassword("123456");
userRepository.save(user);
}
/**
* 更新操作
*/
@Test
void testUpdate() {
Optional<UserEntity> optional=userRepository.findById(1L);
if (optional.isPresent()){
UserEntity user = optional.get();
user.setName("李四");
userRepository.save(user);
}
}
/**
* 删除操作
*/
@Test
void testDelete() {
UserEntity user = new UserEntity();
user.setId(1L);
userRepository.delete(user);
}
/**
* 获取所有用户列表
*/
@Test
void testFindAll() {
List<UserEntity> userEntities = userRepository.findAll();
System.out.println(userEntities);
}
}
扩展查询
当你继承JpaRepository后,自带的查询方法无法满足的时候,jpa还为我们提供了下面几种查询方式
根据属性查询
//自定义简单查询 主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBy, getXXBy后面跟属性名称:
List<UserEntity> findByName(String name);
//也使用一些加一些关键字And 、 Or
UserEntity findByNameOrPassword(String name, String age);
//修改、删除、统计也是类似语法
void deleteById(Long id);
Long countByName(String userName);
//基本上 SQL 体系中的关键词都可以使用,例如: LIKE 、 IgnoreCase、 OrderBy。
List<UserEntity> findByNameLike(String email);
UserEntity findByNameIgnoreCase(String userName);
List<UserEntity> findByNameOrderByNameDesc(String name);
自定义查询
@Query(nativeQuery = true, value = "SELECT * FROM t_user WHERE name = :name1 OR name = :name2 ") List<UserDO> findSQL(@Param("name1") String name1, @Param("name2") String name2);
分页查询
分页需要设置分页参数类Pageable,初始化主要是有两个参数:第一个是查询的页码(下标从0开始),第二个是每页查询的条数
查询方式如下
@Test
public void testPageQuery() throws Exception {
//设置分页参数
Pageable pageable = PageRequest.of(0,1);
System.out.println(userRepository.findAll(pageable).getContent());
}
Page接口是封装为Spring Data Jpa 内部的page bean,它的常用方法如下:
//获取总页数
int getTotalPages();
//获取总记录数
long getTotalElements();
//获取列表数据
List<T> getContent();
总结
可以看到,我们所做的全部事情仅仅是在 SpingBoot 工程里面增加数据库配置信息,声明一个 UserDO 的数据库实体对象,然后声明了一个持久层的接口,改接口继承自 org.springframework.data.jpa.repository.JpaRepository 接口。然后,系统就自动拥有了丰富的增加、删除、修改、查询功能。查询功能甚至还拥有了排序和分页的功能。