1. 什么是JPA
JPA (Java Prsitene AP) 是Sun官方提出的Java 持久化规范。它为Java开发人员提供了一种对象 / 关系映射工具来管理Java 应用中的关系数据。它的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate、TopLink、 JDO等ORM框架各自为营的局面。
值得注意的是,JPA 是在充分吸收了现有的Hibernate、 TopLink、 JDO等ORM框架的基础上发展而来的,具有易于使用、伸缩性强等优点。从目前的开发社区的反应上看,JPA 受到了极大的支持和赞扬,其中就包括了Spring 与EJB 3.0的开发团队。
注意: JPA 是一套规范,不是一套产品,那么像Hibernate、TopLink、 JDO它们是一套产品,如果说这些产品实现了这个JPA规范,那么我们就可以称他们为JPA的实现产品。
2. Spring Data JPA
Spring Data 是 Spring 的一个子项目,用于简化数据库访问,包括 NoSQL非关系型数据库,另外还包括对关系型数据库的访问支持。Spring Data 使我们可以快速简单地使用普通的数据访问技术及新的数据访问技术,Spring Data会让数据的访问变得更加方便。
Soring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA 应用大可以让开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增、删、改、查等任内的常用功能,且易于扩展,学习并使用 Sring Data JPA 可以极大提高开发效率。Spring Data JPA其实就是Spring 基于Hibernate 之上构建的 JPA 使用解决方案,方便在 Spring Boot 项目中使用JPA 技术。
Spring Data JPA 让我们解脱了 DAO 层的操作,基本上所有 CRUD 都可以依赖于它实现。
3. 使用方法
-
创建项目
注意: 项目需要的依赖Spring Data JPA、MySQL Driver
不会构建的同学这里戳一戳 ☞ ☞ 教你如何构建一个Spring Boot项目 -
application.properties 添加配置信息:
#配置数据源相关信息
#MySQL5.x版本的驱动
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/crm?useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
#配置JPA(Hibernate)相关信息
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
hibernate.dialect 参数:主要是指定数据库方言(数据库类型)
show-sql 参数:是否在日志中打印出自动生成的SQL, 方便调试的时候查看
format_ sql 参数:是否格式化SQL
- 数据库 user 表
4.编写实体类: User.java
package com.aiweiyi.pojo;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@Data
@Entity
@Table(name = "user")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
@Column(name = "user_name")
private String userName;
@Column(name = "user_password")
private String userPassword;
@Column(name = "user_role_id")
private Long userRoleId;
@Column(name = "user_flag")
private Integer userFlag;
@Column(name = "creation_date")
private Date creation_date;
}
@Data注解: 可以为类提供读写功能,从而不用写get、set方法.
使用@Data需要安装lombok插件
JPA注解说明如下:
● @Entity(name=“EntityName”) 必须,用来标注一个数据库 表对应的实体,数据库中创建的表名默认和类名一致。其中,name 为可选,对应数据库中一个表,使用此注解标记 Pojo 是一一个JPA实体。
● @Table(name=", catalog=", schema=") 可选,用来标注一个数据库标对应的实体,数据库中创建的表名默认和类名一致。通常和@Entity 配合使用,只能标注在实体的class 定义处,表示实体对应的数据库表的信息。
● @ld必须,@ld定义了映射到数据库表的主键的属性,一个实体只能有一个属性被映射为主键。
● @GeneratedValue(strategy=GenerationType, generator=") 可选,strategy: 表示主键生成策略,有AUTO、 IDENTITY、 SEQUENCE和TABLE4 种,分别表示让ORM框架自动选择合适的策略,ID 自增长,序列产生主键,表产生主键; generator: 表示主键生成器的名称。
● @Column(name= “usr_ id”, nullable = false,length=32) 可选,@Column 描述了数据库表中该字段的详细定义,这对于根据JPA注解生成数据库表结构的工具。name:表示数据库表中该字段的名称,默认情形属性名称一致; nullable: 表示该字段是否允许为null, 默认为true; unique: 表示该字段是否是唯标识,默认为false: length: 表示该字段的大小,仅对String 类型的字段有效。
● @Transient可选,@Transient 表示该属性并非一个到数据库表的字段的映射,ORM框架将忽略该属性。
● @Enumerated 可选,使用枚举的时候,我们希望数据库中存储的是枚举对应的String类型,而不是枚举的索引值,需要在属性上面添加
@Enumerated(EnumType STRING)注解。
- 编写Repository
在 com.hxy.aiweiyi.repository 包下创建 UserServiceImpl
public interface UserRepository extends JpaRepository<User,Long> {
}
- 编写测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class Ch02ApplicationTests {
@Resource
private UserRepository userRepository;
@Test
public void testAdd() {//测试新增
User user = new User();
user.setUserName("小民");
user.setUserPassword("111111");
user.setUserRoleId(1L);
user.setUserFlag(2);
user.setCreation_date(new Date());
userRepository.save(user);
}
@Test
public void testFindById(){//测试根据主键id查询
User user = userRepository.findById(1L).get();
System.out.println(user);
}
@Test
public void testDeleteById(){//测试根据主键id删除
userRepository.deleteById(5L);
}
}
执行结果:
4. 核心功能
自定义查询
Spring Data JPA 还可以根据接口方法名来实现数据库操作,主要的语法是findXBy、readXBy queryXXBY、countXXBy、 getXXBy 后面跟属性名称,利用这个功能仅需要在定义的 Repository 中添加对应的方法名即可,使用时Spring Boot会自动帮我们实现
public interface UserRepository extends JpaRepository<User,Long> {
//根据用户名查询
public List<User> findByUserName(String userName);
//也可以加一些关键字 And、Or
public List<user> findByUserNameAndUserPassword(String userName,String userPassword);
//修改、删除、统计也是类似语法
public Long countByUserName(String userName);
//基本上SQL体系中的关键词都可以使用,如 Like、lgnoreCase、OrderBy
public List<User> findByUserNameLike(String userName);
}
测试:
@Test
public void testFindByUserNameLike(){
List<User> list = userRepository.findByUserNameLike("%小%");
if(list!=null){
list.forEach(u -> System.out.println(u));
}
}
执行结果:
可以根据查询需求不断添加和拼接, Spring Boot 都可以正确解析和执行, 其他使用示例可参考下图:
自定义 QL 查询
在 Repository 的查询方法上使用 @Query 注解, 在注解内写 HQL 来查询内容
public interface UserRepository extends JpaRepository<User,Long> {
@Query("select u from User u where u.userName=?1 and u.userPassword=?2 ")
public List<User> findUserByUserNameAndUserPassword(String userName,String userPassword);
//如果涉及到删除和修改需要加上 @Modifying , 也可以根据需要添加 @Transactional 对事务的支持、操作超时设置等
@Transactional(timeout = 10)
@Modifying
@Query("update User u set u.userName=:userName where u.userId=:userId")
public int modifyingNameById(@Param("userName") String userName,@Param("userId") Long userId);
public Page<User> findPageByUserNameLike(String userName, Pageable page);
}
注意: HQL面向实体类和属性, 语句中不能写表名和字段
测试:
@Test
public void testModifyingNameById(){
int num = userRepository.modifyingNameById("小闵",3L);
System.out.println(num);
}
执行结果: