我正在创建一个需要与数据库交互的程序。它是一个简单的库存管理系统,所以实体是'项目'和' Patron'。
编辑:这是一个使用Spring启动和弹簧数据JPA的Vaadin应用程序
首先,我将从我的2个课程开始,为了简洁省略了getter / 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来实例化Patron对象。然后该数据填充顾客类的名称,电子邮件和ID字段。
当签出物品时,顾客首先用MSR刷卡(系统会确认它们在DB中,如果没有则添加它们)。 扫描磁条后,扫描所需物品的二维码,以便我们将该物品与它们绑在一起。
当商品被签出给顾客时,我们需要从Patron表中获取 id ,名称和电子邮件,然后填充其余变量:check_out_date
,due_date
等
顾客可以查看许多物品,但只能向顾客签出一件物品。这会建立OneToMany
关系吗?赞助人 - &gt;项(
我的思考过程如下:
对于赞助人对象
有一个项目数组来存储他们目前拥有的项目的条形码。
有一个项目的arraylist来存储有关顾客拥有它的信息以及何时List<Item> history
,这样代码就像history.addToFront(something)
一样简单
对于物品对象 有一个赞助人对象,看谁有它 有一个顾客的arraylist看到它被检查的所有时间
Q1:将数组和列表作为两个类的实例数据是否是多余的?
Q1.2:对象数组和对象列表是否适用于这样的场景的适当数据结构?
Q1.3:对于像ID这样的内容使用javax.persistence.*;
和org.springframework.data.annotation.*;
是否存在差异,import javax.validation.constraints.NotNull;
和import org.springframework.lang.NonNull;
Q2:这是否会在Patron和Items之间产生OneToMany
关系?
问题3:为了实现这一目标,我相信我的数据库中还需要一些额外的表。我在想这样的事情:(并且我意识到在实现新模式时我需要包含适当的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表 :这会从顾客表中提取 ID,姓名,电子邮件,然后从商品表中提取 id,check_out_date,due_date ?
Item_Patron_History表:与上表类似的结构?
提前谢谢。
答案 0 :(得分:2)
好的,
我假设您使用Spring Boot构建应用程序,将Hibernate构建为ORM,可能还有某种类型或关系数据库(MySQL)。
关于数据库设计:
是的,这里的Patreon对象是拥有与Item实体的OneToMany关系的拥有实体(因为一个Patreon可能有N个对象)。 您的Patreon实体可以执行以下重新设计:
1)尝试使用非基本类型,尤其是表键(long id - &gt; 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对象,从而检索对象及其相关实体(Items)。
关于你的问题:
Q1:是的,它看到了。请参阅上文了解更多信息。
Q1.2:没有阵列。列表或更好的集合更适合。
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
Q2:是的。见上文。
第三季:有点聪明的设计,我认为不需要更多,但是 嘿如果你觉得它会帮助你,为什么不呢。只是不要过度杀戮 desingn和它的复杂性答案 1 :(得分:0)
昨天我花了很长时间才想到解决方案。 我对两个班级做了你提到的改动。 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;