JPA(Java Persistence API)是Java的持久化API,用于对象的持久化。它是一个强大的ORM持久化的解决方案,免去了使用JDBCTemplate开发的编写脚本工作。JPA通过简单约定好接口方法的规则自动生成相应的JPQL语句,然后映射成POJO对象。
JPA是一个规范化接口,封装了Hibernate的操作作为默认实现,让用户不通过任何配置即可完成数据库的操作。
JPA创建实体和JDBC Template创建实体的区别:
通过JPA创建实体
@Data
@Entity
public class User{
@Id
//id的自增由数据库自动管理
private int id;
@GeneratedValue(stratety=GenerationType.IDENTITY)
private String username;
private String password;
}
通过JDBC Template 创建实体
@Data
public class User implements RowMapper<User> {
private int id;
private String username;
private String password;
//必须重写mapRow方法
@Override
public User mapRow(ResultSet resultSet,int i) throws SQLException{
User user=new User();
user.setId(resultSet.getInt("id"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}
}
对比JPA和JDBC Template创建实体的方式可以看出:JPA的实现方式简单明了,不需要重写映射(支持自定义映射),只需要设置好属性即可。id的自增由数据库自动管理,也可以由程序管理,其他的工作JPA自动处理好了。
了解JPA注解和属性
JPA常用注解
注解 | 说明 |
---|---|
@Entity | 声明类为实体 |
@Table | 声明表名,@Entity和@Table注解一般一起使用,如果表名和实体类名相同,那么@Table可以省略 |
@Basic | 指定非约束明确的各个字段 |
@Embedded | |
@Id | 指定的类的属性,一个表中的主键 |
@GeneratedValue | 指定如何标识属性可以被初始化 |
@Transient | 表明该属性并非一个数据库表的字段的映射,ORM框架将忽略该属性。如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,即它不是持久的,为虚拟字段 |
@Column | 指定持久属性,即字段名。如果字段名和列名相同,则可以省略。 |
@SequenceGenerator | |
@TableGenerator | 在数据库生成一张表来管理主键生成策略 |
@AccessType | 用于设置访问类型。如果设置@AccessType(FIELD),则可以直接访问变量,并且不需要使用Getter和Setter方法,但必须为public属性。如果设置@AccessType(PROPERTY),则通过Getter和Setter方法访问Entity的变量 |
@UniqueConstraint | 指定的字段和用于主要或辅助表的唯一约束 |
@ColumnResult | 可以参考使用select子句的sql查询中的列名 |
@NamedQueries | 指定命名查询的列表 |
@NamedQuery | 指定使用静态名称的查询 |
@Basic | 指定实体属性的加载方式,如@Basic(fetch=FetchType.LAZY) |
@JsonIgnore | 作用是JSON序列化时将Java Bean中的一些属性忽略掉,序列化和反序列化都受影响 |
2.映射关系注解
注解 | 说明 |
---|---|
@JoinColumn | 指定一个实体组织或实体集合。用在多对一和一对多的关联中 |
@OnetoOne | 定义表之间的一对一的关系 |
@OneToMany | 定义表之间一对多的关系 |
@ManyToOne | 定义表之间多对一的关系 |
@ManyToMany | 定义表之间多对多的关系 |
3.映射关系的属性
属性名 | 说明 |
---|---|
targetEntity | 表示默认关联的实体类型,默认为当前标注的实体类 |
cascade | 表示与此实体一对一关联的级联样式类型,以及当对实体进行操作时的策略 |
fetch | 该实体的加载方式,包含LAZY和EAGER |
optional | 表示关联的实体是否能够存在null值。默认为true,表示可以存在null值。如果为false,则要同时配合使用@JoinColumn标记 |
mappedBy | 双向关联实体时使用,标注在不保存关系的实体中 |
JoinColumn | 关联指定列。该属性值可接收多个@JoinColumn。用于配置连接表中外键列的信息。@JoinColumn配置的外键列参照当前实体对应表的主键列 |
JoinTable | 两张表通过中间的关联表建立联系时使用,即多对多关系 |
PrimaryKeyJoinColumn | 主键关联。在关联的两个实体中直接使用注解@PrimaryKeyJoinColumn注释。 |
懒加载LAZY和实时加载EAGER的目的是:实现关联数据的选择性加载。
- 懒加载时在属性被引用时才生成查询语句,抽取相关联数据。
- 实时加载则是执行完主查询后,不管是否被引用,都会马上执行后续的关联数据查询。
使用懒加载来调用关联数据,必须要保证主查询的Session(数据库连接会话)的生命周期没有结束,否则时无法抽取到数据的。
JPA接口
JPA提供了操作数据库的接口。在开发过程中继承和使用这些接口,可简化现有的持久化开发工作。可以使用Spring找到自定义接口,并生成代理类,后续可以把自定义接口注入Spring容器中进行管理。在自定义接口过程中,可以不写相关的SQL操作,由代理类自动生成。
JPA接口JpaRepository
JpaReposity继承自PagingAndSortingRepository.该接口提供了JPA的相关实用功能,以及通过Example进行查询的功能。Example对象是JPA提供用来构造查询条件的对象。该接口的关键代码如下
public interface JpaRepository<T,ID> extends PagingAndSortingRepository<T,ID>,
QueryByExampleExecutor<T>{}
在上述代码中,T表示实体对象,ID代表主键。ID必须实现序列化。