实体类简单映射

在前面章节已经介绍了 JPA 大部分的注解,以及注解的用法。接下来我们将利用这些注解去实现实体类和数据表之间的简单映射。

什么是映射?

这里的映射也称对象关系映射。对象关系映射(英语:Object Relational Mapping,简称 ORM,或 O/RM,或 O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。

从效果上说,它其实是创建了一个可在编程语言里使用的 “虚拟对象数据库”。使用者不需要直接去操作数据库,直接操作对象即可。ORM 框架会自动帮我们把对对象的操作应用到数据库中。

什么是对象数据库?

对象数据库是一种以对象形式表示信息的数据库。对象数据库的数据库管理系统被称为 ODBMS 或 OODBMS。

两个主要原因让用户使用对象数据库技术。

首先,关系数据库在管理复杂数据时显得笨重。

其次,被应用软件操作的数据一般是用面向对象的编程语言如 C++, Java, Delphi 和 C# 写成,而那些用来转化数据表示和关系数据库元组的代码很冗繁,执行时也有不少耗时。

对象关系映射分类

从方向分

  • 单向:从A可以到导航到B,B不能导航到A。例如:以老师和学生为例,老师知道自己有那些学生,而学生却不知道他的老师。如下:

public class Teacher {
    //...省略...
    private List<Student> studentList;
}

public class Student {
    //...省略...
}

上面代码中,在 Teacher 类中能够访问 Student,然而 Student 不能访问 Teacher,因此为单向。

  • 双向:从A可以导航到B,B也能导航到A。例如:以老师和学生为例,老师知道自己有那些学生,学生也知道他的老师是谁。如下:

public class Teacher {
    //...省略...
    private List<Student> studentList;
}

public class Student {
    //...省略...
    private Teacher teacher;
}

上面代码中,在 Teacher 类中能够访问 Student,并且 Student 中也能访问 Teacher,所以是双向的。

从关系分

  • 一对一:比如说一个班级有很多学生,他们分别有不同的学号。一个学生对应一个学号,一个学号对应一个学生;通过学号能找到学生,通过学生也能得到学号,不会重复。这里学生和学号的关系就是一对一。要实现一对一关系,需要在主表中添加一个外键。

  • 一对多:比如说一个班级有很多学生,可是这个班级只有一个班主任。在这个班级中随便找一个人,就会知道他们的班主任是谁;知道了这个班主任就会知道有哪几个学生。这里班主任和学生的关系就是一对多。要实现一对多需要在多的一方的表里面添加外键。

  • 多对一:比如说一个班级有很多学生,可是这个班级只有一个班主任。在这个班级中随便找一个人,就会知道他们的班主任是谁;知道了这个班主任就会知道有哪几个学生。这里学生和班主任的关系就是多对一。要实现多对一需要在多的一方的表里面添加外键。

  • 多对多:比如说一个班级有很多学生,他们有语文课、数学课、英语课等很多课。一门课有很多人上,一个人上很多门课。这里学生和课程的关系就是多对多。多对多关系必须要通过中间表表来表示它们之间的关系。

下面仅仅介绍怎样使用 JPA 映射单张表,关于一对一、一对多和多对多将在后续章节逐一展开。

简单的实例

假如我们有一张简单的 user 用户表,现在使用 JPA 提供的注解将它映射到 User 实体。如下:

数据表SQL

CREATE TABLE `user` (
    `id`  int NOT NULL AUTO_INCREMENT ,
    `name`  varchar(20) NULL ,
    `sn`  varchar(50) NOT NULL ,
    `hiredate`  datetime NULL ,
    PRIMARY KEY (`id`)
);

Java 实体

@Entity
// 根据需求,对类和表做相关映射 (如:表名)
@Table(name="user")
public class User {
    // 标识该字段为主键列对应的字段
    @Id
    // 指定主键的生成策略
    @GeneratedValue(strategy = GenerationType.AUTO)
    // 为当前字段和对应的列做映射(如:列名,列的长度等)
    @Column(name = "id")
    private Long id;

    @Column(name = "name",length = 20)
    private String name;

    @Column(name = "sn",nullable = false)
    private String sn;

    // 对日期类型做映射
    @Temporal(TemporalType.DATE)
    private Date hiredate;
}

上述实例中,JPA 会扫描到拥有 @Entity 注解的类,将其作为需要持久化的类,由 JPA 管理它的持久化。其中:

  • @Table 注解定义该实体对应哪张数据表,如果没有为实体类指定 @Table 注解,则实体类将使用默认值表名。

  • @Id 表示该字段为主键字段。如果不指定该注解,IDEA 会提示错误信息 “Persistent entity 'User' should have primary key”;但是,依然可以正确执行;

  • @GeneratedValue 注解用来指定主键生成策略,如:自增长、序列、数据表(JPA 通过一张表来维护主键值,性能稍差)

关于更多定义实体的注解,可以参考前一大章节。

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号