繁体   English   中英

在JPA中坚持非原始数据

[英]Persist non-primitive data in JPA

我正在创建一个需要与数据库交互的程序。 这是一个准系统的库存管理系统,因此实体为“项目”和“赞助人”。

编辑:这是使用Spring启动和Spring数据JPA的Vaadin应用程序

首先,我将从我的两个班级开始,为简洁起见,将省略getters / setter方法。

@Table(name="item")
@Entity 
public class Item implements Serializable, Cloneable {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long barcode;
    @NotNull
    private String name, type;
    @NotNull
    private boolean isAvailable;
    @Nullable
    private boolean isLate;
    @Nullable
    private String notes;
    @Nullable
    private Patron currentPatron;
    @Nullable
    private Patron[] history;
    @Nullable
    private Date checkOutDate, dueDate;

    public Item() {}

    public Item(long barcode, String name, String type, boolean isAvailable) {
        this.barcode = barcode;
        this.name = name;
        this.type = type;
        this.isAvailable = isAvailable;
    }

    public Item(long barcode, String name, String type, String notes, boolean isAvailable) {
        this.barcode = barcode;
        this.name = name;
        this.type = type;
        this.notes = notes;
        this.isAvailable = isAvailable;
    }

    public Item(long barcode, String name, String type, String notes, boolean isAvailable, Date checkOutDate, Date dueDate, boolean isLate, Patron currentPatron, Patron[] history) {
        this.barcode = barcode;
        this.name = name;
        this.type = type;
        this.notes = notes;
        this.isAvailable = isAvailable;
        this.checkOutDate = checkOutDate;
        this.dueDate = dueDate;
        this.isLate = isLate;
        this.currentPatron = currentPatron;
        this.history = history;
    }
}

@Entity
@Table(name="patron")
public class Patron {
    @Id
    private long id;
    @NotNull
    private String name, email;
    @Nullable
    private Item[] checkedOutItems;
    @Nullable
    private List<Item> itemHistory;
    @Nullable
    private boolean owesFines;
    @Nullable
    private int finesOwed;

    public Patron() {}

    public Patron(long id, String name, String email, boolean owesFines) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.owesFines = owesFines;
    }

    public Patron(long id, String name, String email, Item[] checkedOutItems, List<Item> itemHistory, boolean owesFines, int finesOwed) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.checkedOutItems = checkedOutItems;
        this.itemHistory = itemHistory;
        this.owesFines = owesFines;
        this.finesOwed = finesOwed;
    }

在实践中,通过使用MSR扫描其校园ID来实例化赞助者对象。 然后,该数据将填充顾客类的名称,电子邮件和ID字段。

签出物品时,顾客将首先使用MSR刷卡(系统会确认它们在数据库中,否则将其添加)。 扫描他们的磁条后,将扫描他们想要的物品的QR码,以便我们将该物品绑定到他们。

将项目签出给顾客时,我们需要从顾客表中获取其ID名称电子邮件 ,然后填充其其余变量: check_out_datedue_date等。

顾客可以检出很多物品,但是只有一个物品可以检出给顾客。 这会建立OneToMany关系吗? 顾客->物品(

我的思考过程如下:

对于赞助人,对象具有一组项目,用于存储其当前拥有的项目的条形码。 有一个项目的数组List<Item> history来存储有关顾客的信息以及List<Item> history ,这样代码就和history.addToFront(something)一样简单history.addToFront(something)

对于项目对象,有一个赞助人对象,以查看谁拥有它的顾客,并有一个顾客数组列表,以查看所有被检出的时间

问题1:将数组和列表作为两个类的实例数据是否多余?

Q1.2:对于这样的场景,对象数组和对象列表是否甚至是合适的数据结构?

Q1.3:使用javax.persistence.*;是否有所不同javax.persistence.*; org.springframework.data.annotation.*; 对于诸如ID之类的东西, import javax.validation.constraints.NotNull;之间是否有区别import javax.validation.constraints.NotNull; import org.springframework.lang.NonNull;

问题2:这是否在顾客和物品之间产生了OneToMany关系?

Q3:为了实现这一点,我相信我的数据库中需要一些其他表。 我在想这样的事情:(而且我意识到在实现新模式时,我需要包括适当的spring注释)

项目表

create table item(barcode int(10) primary key, name varchar(64) not null, type varchar(64) not null, availability boolean, is_late boolean, note varchar(255), check_out_date Datetime, due_date Datetime); #foreign keys for currentPatron and Patron History

顾客桌

create table patron(id int(10) primary key, name varchar(64) not null, email varchar(64) not null, owes_fines boolean, fines_owed int); #foreign key to item table?

Patron_Item_History表 :这会从patron表中提取ID,名称,电子邮件 ,然后从项目表中提取ID,check_out_date,due_date吗?

Item_Patron_History表 :与上类似的结构吗?

先感谢您。

好的,去吧,

我假设您正在使用Spring Boot,Hibernate作为您的ORM以及可能是某种关系数据库(MySQL)来构建应用程序。

关于数据库设计:

是的,这里的Patreon对象​​是拥有与Item实体具有OneToMany关系的拥有实体(因为一个Patreon可能具有N个对象)。 您的Patreon实体可以进行以下兑换:

1)尝试对表键(long id-> Long id)使用非原始类型。

2)丢失checkedOutItems数组以及itemHistory列表。 首先,应该使用集合而不是数组来建立关系模型。 其次,您不需要这两个。 您将永远不会以这种方式存储checkedOutItems或itemHistory。 而是创建一个List<Item> items ,该项目将在描述关系时存储Patreon项目(以下是一些示例: http : //www.baeldung.com/hibernate-one-to-many

3)同样,您需要使用Item实体丢失历史记录数组。 您唯一需要的是对拥有实体的引用(在本例中为Patreon),从而完成了关系的ManyToOne方面。

4)请注意,日期字段应使用@Temporal进行注释,并提供正确的类型(您可以阅读更多内容)。

5)一般而言,物品类应该重新设计。

5)完成上述所有操作并假设您使用的是Spring之后,您可以创建一个存储库,您可以使用该存储库查询Patreon对象​​,从而检索对象及其相关实体(项目)。

关于您的问题:

问题1:是的。 有关更多信息,请参见上文。

Q1.2:没有数组不是。 列表或更好的集合更适合。

Q1.3:是的。 第一个是关系数据库中使用的JPA批注,而第二个是非此类型(关系)或未定义标准持久性API(如JPA)的数据库和框架使用的Spring Data特定注释。 因为NonNull和NotNull与第一个大致相同,而后者实际上是对后者的超集(通常会这样做)。 我看到的唯一区别是目标。 您可以在这里阅读更多信息: https : //docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/lang/NonNull.html https://docs.oracle.com/javaee/ 7 / api / javax / validation / constraints / NotNull.html

Q2:是的。 往上看。

Q3:有点聪明的想法,我看不到需要更多,但是,嘿,如果您觉得这会有所帮助,为什么不呢。 只是不要过度设计,这很复杂

昨天我花了很长时间才想到解决方案。 我对两个课程都做了您提到的更改。 Long是一个对象,而long是一个基元,您可以序列化Long,这就是为什么您建议我改用它吗?

我一直在摆弄小提琴,以测试自己的想法,这就是我的想法。 它可以按我想要的方式工作,但是随后我需要在我的存储库中实现它。诸如repo.checkout(item,patron)之类的东西就足够了吗? 至于其他所有内容,例如填充供客户端查看的列表,主要是从现在开始的Java逻辑吗?

无论如何,这是我的解决方案!

create table item (
    barcode bigint not null auto_increment primary key,
    name varchar(20) not null,
    type varchar(20) not null,
    is_available boolean not null,
    is_late boolean null,
    notes varchar(255) null,
    check_out_date datetime null,
    due_date datetime null
    #create index idx_barcode (barcode));

create table patron (
    trinity_id bigint not null primary key,
    name varchar(30) not null,
    email varchar(20) not null,
    owes_fines boolean not null,
    fines_owed int null
    #create index idx_trinity_id (trinity_id));

create table checked_out_items (
    ref_id bigint primary key auto_increment not null,
    patron_id bigint not null,
    item_id bigint not null,
    item_available boolean not null,
    item_check_out_date datetime null,
    item_due_date datetime null);

alter table checked_out_items
    add constraint fk_patron_id
    foreign key (patron_id) references patron(trinity_id),
    add constraint fk_item_id
    foreign key (item_id) references item(barcode)
    #add constraint fk_item_available
    #add constraint fk_check_out_date
    #add constraint fk_due_date
    #foreign key (item_available references item(is_available)
    #foreign key (item_check_out_date) references item(check_out_date)
    #foreign key (item_due_date) references item(due_date)
    on update cascade
    on delete cascade;     


insert into patron values(0000000,'Test Erino','test@erino.edu',0,null);
insert into item values(1,'Chromebook','Laptop',0,null,null,null,null);

insert into  checked_out_items(patron_id,item_id,item_available,item_check_out_date,item_due_date)
select patron.trinity_id,item.barcode,item.is_available,item.check_out_date,item.due_date
from patron
inner join item;

最后:

select * from item;
select * from patron;
select * from checked_out_items;

架构设定

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM