快速开始
JPA 是 Sun 对 ORM 框架定义的一组标准规范,类似于 JDBC 之于各种数据库。
创建一个空的 Maven 项目,添加如下依赖:
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-core</artifactId>
<version>7.1.2.Final</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.4.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.42</version>
</dependency>
添加 JPA 的配置文件src/main/resources/META-INF/persistence.xml
:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="jpa-demo" transaction-type="RESOURCE_LOCAL">
<!-- 指定ORM框架实现了 PersistenceProvider 接口的实现类 -->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>cn.icexmoon.entity.Customer</class>
<properties>
<!-- 数据库连接设置 -->
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="mysql" />
<!-- ORM 框架设置 -->
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
这里的<class>cn.icexmoon.entity.Customer</class>
是之后定义的实体类,如果没有在这里添加,就会报错表示实体类不属于这个persistence-unit
。
添加实体类src/main/java/cn/icexmoon/entity/Customer.java
:
name = "customer")
(
public class Customer {
strategy = GenerationType.IDENTITY)
( private Long id;
name = "last_name", length = 10, nullable = false)
( private String lastName;
private Integer age;
}
主要涉及以下注解:
-
@Entity,定义 JPA 实体
-
@Table,如果实体名称与表名不同,需要使用 @Table 标记对应的数据库表
-
@Id,标记用于表主键的字段
-
@GeneratedValue,主键生成策略,分为以下几种:
-
AUTO:JPA 自动选择合适策略,默认选项
-
IDENTITY:采用数据库自增方式生成主键,Oracle 不支持
-
SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySQL 不支持
-
TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库迁移
-
-
@Column,定义列的相关设置,比如列名、长度、是否为空、是否唯一约束等。
添加入口类src/main/java/cn/icexmoon/Main.java
:
public class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("jpa-demo");
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
Customer customer = new Customer();
customer.setLastName("icexmoon");
customer.setAge(18);
entityManager.persist(customer);
transaction.commit();
entityManager.close();
entityManagerFactory.close();
}
}
注解
@Transient
JPA 实体中默认所有具备 Getter 和 Setter 的属性都是表字段的映射,如果有属性不是表字段的映射,就需要使用@Transient
注解标记:
name = "customer")
(
public class Customer {
strategy = GenerationType.IDENTITY)
( private Long id;
name = "last_name", length = 10, nullable = false)
( private String lastName;
private Integer age;
private Integer score;
}
这里的score
属性就不会作为表字段保存和读取。
@Temporal
如果实体类的字段是Date
类型:
name = "customer")
(
public class Customer {
// ...
private Date birth;
private Date createTime;
}
JPA 自动生成的数据库字段都会是datetime
类型。在这里,birth
字段使用date
类型的数据库字段存储更为合适。
可以使用@Temporal
注解显式为 Date 类型字段指定数据库字段的类型:
name = "customer")
(
public class Customer {
// ...
TemporalType.DATE)
( private Date birth;
private Date createTime;
}
此时数据库中的birth
字段会使用date
类型而非datetime
类型。
在高版本的 JPA 中
@Temporal
虽然依然有效,但已经被标记为废弃,高版本的 JPA 中建议直接使用LocalDate
和LocalDateTime
定义时间类型的实体字段。
使用表生成主键
创建用于生成主键的表:
create table id_generator
(
id bigint unsigned auto_increment
primary key,
table_name varchar(255) not null,
value bigint null
);
修改实体类,使用表生成主键:
name = "customer")
(
public class Customer {
( name = "customer_id_generator",
table = "id_generator",
pkColumnName = "table_name",
valueColumnName = "value",
pkColumnValue = "customer",
allocationSize = 1)
strategy = GenerationType.TABLE, generator = "customer_id_generator")
( private Long id;
// ...
}
@TableGenerator
的table
属性说明使用id_generator
表生成主键,生成主键的数据通过pkColumnName
、pkColumnValue
、valueColumnName
三个属性进行定位,即pkColumnName
的值所在的列的值为pkColumnValue
的值,游标存放在valueColumnName
值对应的列。allocationSize
属性决定了下一个生成的主键值的步进。
本文的完整示例代码可以从获取。
文章评论