红茶的个人站点

  • 首页
  • 专栏
  • 开发工具
  • 其它
  • 隐私政策
Awalon
Talk is cheap,show me the code.
  1. 首页
  2. 专栏
  3. Spring Boot 学习笔记
  4. 正文

JPA 学习笔记 1:开始

2025年10月3日 25点热度 0人点赞 0条评论

快速开始

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:

@Entity
@Table(name = "customer")
@Data
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(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注解标记:

@Entity
@Table(name = "customer")
@Data
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "last_name", length = 10, nullable = false)
    private String lastName;
    private Integer age;
    @Transient
    private Integer score;
}

这里的score属性就不会作为表字段保存和读取。

@Temporal

如果实体类的字段是Date类型:

@Entity
@Table(name = "customer")
@Data
public class Customer {
    // ...
    private Date birth;
    private Date createTime;
}

JPA 自动生成的数据库字段都会是datetime类型。在这里,birth字段使用date类型的数据库字段存储更为合适。

可以使用@Temporal注解显式为 Date 类型字段指定数据库字段的类型:

@Entity
@Table(name = "customer")
@Data
public class Customer {
    // ...
    @Temporal(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
);

修改实体类,使用表生成主键:

@Entity
@Table(name = "customer")
@Data
public class Customer {
    @Id
    @TableGenerator(
            name = "customer_id_generator",
            table = "id_generator",
            pkColumnName = "table_name",
            valueColumnName = "value",
            pkColumnValue = "customer",
            allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.TABLE, generator = "customer_id_generator")
    private Long id;
    // ...
}

@TableGenerator的table属性说明使用id_generator表生成主键,生成主键的数据通过pkColumnName、pkColumnValue、valueColumnName三个属性进行定位,即pkColumnName的值所在的列的值为pkColumnValue的值,游标存放在valueColumnName值对应的列。allocationSize属性决定了下一个生成的主键值的步进。

本文的完整示例代码可以从这里获取。

参考资料

  • 尚硅谷jpa开发教程全套完整版

  • 集成JPA - Java教程 - 廖雪峰的官方网站

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: jpa
最后更新:2025年10月3日

魔芋红茶

加一点PHP,加一点Go,加一点Python......

点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

COPYRIGHT © 2021 icexmoon.cn. ALL RIGHTS RESERVED.
本网站由提供CDN加速/云存储服务

Theme Kratos Made By Seaton Jiang

宁ICP备2021001508号

宁公网安备64040202000141号