在JPA中坚持非原始数据 [英] Persist non-primitive data in JPA

查看:108
本文介绍了在JPA中坚持非原始数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个需要与数据库交互的程序.这是一个简单的库存管理系统,因此实体是商品"和赞助人".

I am creating a program that needs to interact with a database. It's a bare-bones inventory management system, so the entities are 'Item' and 'Patron'.

这是一个使用Spring引导和spring数据JPA的Vaadin应用程序

This is a Vaadin application using Spring boot and spring data JPA

首先,我将从我的2个课程开始,为简洁起见,将省略getters/setter方法.

First I will start with my 2 classes and omit getters/setters for brevity.

@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字段.

In practice the Patron Object is instantiated by scanning their campus ID with a MSR. Then that data populates the name, email and ID fields of the patron class.

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

When checking out an item, the patron would first swipe their card with the MSR (the system would confirm they are in the DB, add them if not). After their magnetic strip is scanned, the QR code for the item they want is scanned so we can tie that item to them.

将商品签出给顾客时,我们需要从顾客表中获取他们的 id 名称电子邮件,然后填充其其余变量:check_out_datedue_date

When an item is checked out to a patron, we need to get their id, name and email from the Patron table and then populate the rest of its variables: check_out_date, due_date, etc.

一个顾客可以检出很多物品,但是只有一个物品可以检出给顾客.这是否建立OneToMany关系?赞助人->物品(

A patron can check out many items, but only one item can be checked out to a patron. Does This establish a OneToMany relationship? Patron -> Item(

我的思考过程如下:

对于赞助人对象 有一组Items来存储他们当前拥有的商品的条形码. 有一个项目的数组列表来存储有关顾客的信息以及何时List<Item> history的信息,这样代码就像history.addToFront(something)

For Patron Objects have an array of Items to store the barcode of the items they currently have. have an arraylist of items to store info about what patron had it and when List<Item> history, that way the code is as simple as history.addToFront(something)

对于项目对象 有一个顾客对象来看看谁拥有它 有一个顾客列表,可以查看所有退房时间

For Item Objects have a Patron object to see who has it have an arraylist of patrons to see all the times it was checked out

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

Q1: Is it redundant to have an array and a list as instance data for both classes?

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

Q1.2: Are an array of objects and a list of objects even appropriate data structures for a scenario like this?

Q1.3:使用javax.persistence.*;org.springframework.data.annotation.*;处理ID等是否有所不同,并且import javax.validation.constraints.NotNull;import org.springframework.lang.NonNull;

Q1.3: Is there a difference in using javax.persistence.*; and org.springframework.data.annotation.*; for something like ID and is there a difference between import javax.validation.constraints.NotNull; and import org.springframework.lang.NonNull;

Q2:这会在顾客和物品之间产生OneToMany关系吗?

Q2: Does this produce a OneToMany relationship between Patron and Items?

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

Q3: In order to achieve this, I believe I need some additional tables in my database. I was thinking something like this: (And I realize I will need to include the appropriate spring annotations when implementing the new schema)

项目表

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表 :这会从顾客表中提取 id,名称,电子邮件,然后从项目表中提取 id,check_out_date,due_date ?

Patron_Item_History table : This would pull id, name, email from the patron table, and then id, check_out_date, due_date from the item table?

Item_Patron_History表:与上面的表类似吗?

Item_Patron_History table: Similar structure to the above table?

谢谢.

推荐答案

可以了,

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

I am assuming you're building you application with Spring Boot, Hibernate as your ORM and probably some kind or relational database (MySQL).

关于数据库设计:

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

Yes the Patreon object here is the owning entity with a OneToMany relation to the Item entity (since one Patreon may have N objects). Your Patreon entity could do with the following redesing:

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

1) Try to use non-primitive types especially for table keys (long id -> Long id).

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

2) Lose the array of checkedOutItems as well as the itemHistory list. First of all relations should be modelled using collections and not arrays. Secondly you don't need those two. You'll never store the checkedOutItems nor the itemHistory this way. Instead create a List<Item> items that will store the Patreon items while describing the relation (here are some examples: http://www.baeldung.com/hibernate-one-to-many)

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

3) Again with the Item entity you need to lose the array of history. The only thing you need there is a reference to the owning entity (Patreon in this case) thus completing the ManyToOne side of the relation.

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

4) Note that Date fields should be annotated with @Temporal also providing the correct type (you can read up for more).

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

5) Item class in general should do with a redesign.

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

5) After all the above are in place and assuming you're using Spring, you can create a Repository with which you can query a Patreon object thus retrieving an object along with it's related entities (Items).

关于您的问题:

Q1:是的,看到了.有关更多信息,请参见上文.

Q1: Yes it see. See above for more.

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

Q1.2: No arrays are not. Lists or better yet Sets are more suited.

Q1.3:是的.第一个是在关系中使用的JPA批注 数据库,而第二个是特定于Spring Data的注释 由非此类型的数据库和框架使用 (关系)或没有定义标准的持久性API(例如 JPA).因为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

Q1.3: Yes there is. The first one a JPA annotation used in relational databases while the second one is Spring Data specific annotation used by databases and frameworks that are not of this type (relational) or do not have a standard persistence API defined (like JPA). For the NonNull and NotNull are roughly the same with the first one actually supersetting the latter one (something that is done often). The only difference I see is the target. You can read for more here: 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:是的.见上文.

Q2: Yes there is. See above.

Q3:通过一些巧妙的设计,我看不到需要更多,但是 嘿,如果您认为这会对您有所帮助,为什么不呢.只是不要过度杀伤 设计及其复杂性

Q3: With a bit of clever desing I do not see the need for more, but hey If you feel it'll help you, why not. Just don't overkill the desingn and it's complexity

这篇关于在JPA中坚持非原始数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆