Java for Web学习笔记(一二七)映射(3)OneToOne

OneToOne

EntityA和EntityB是一对一的关联关系。这在实际中较少使用到。如果某个Entity具有上百个属性,我们可能会将某些属性分别放入子entity中另外存放。有点似列式数据库(如HBase)。用于属性很多,属性可以归类,很可能会有新增属性的情况。

小例子

CREATE TABLE Book (
  Id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
  BookName VARCHAR(50) NOT NULL
) ENGINE = InnoDB;

-- 下面注意,我们没有另外弄一流水号id做为主键,而直接就用外键Book_Id,有点似HBase中的row key。
--  one to one对应没有必要使用其他的主键。当然也可以提供,但要保证Book_Id至少是UNIQUE KEY,这才是一对一
CREATE TABLE Book_Price (
  Book_Id BIGINT UNSIGNED NOT NULL,
  Price FLOAT UNSIGNED NOT NULL,
  PRIMARY KEY (`Book_Id`),
  CONSTRAINT BOOK_BOOK_PRICE FOREIGN KEY (Book_Id) REFERENCES Book (Id) ON DELETE CASCADE
) ENGINE = InnoDB;

这里有几个特点:

  • Book中没有提供Book_Price的索引
  • 以此类推,我们可以提供Book_XXX表来扩展Book的属性。

单向索引

单向索引只是双向索引的热身,通过外键,获取相关信息。Book和普通的没有任何区别。重点看看BookPrice。

@Entity(name = "Book_Price")
public class BookPrice {
    private long id;
    private float price;
    private Book book;

    /* 我们仍提供了@Id,这样可以使用Spring Data中的CrudRepository<BookPrice, Long>接口 */
    @Id
    @Column(name = "Book_Id")
    public long getId() { ...}
    public void setId(long id) { ...}
     
    public float getPrice() { ... }
    public void setPrice(float price) { ... }

    /* 1)提供@OneToOne指出Entity之间的是一对一的关系。
     *   fetch有两个值:
     *       - EAGER :获取entity的时候就获取该属性
     *       - LAZY:只有在访问该属性的时候采取获取该值。这个值在某些业务流程中并没被使用,以此减少数据库的操作。
     * 2)通过@JoinColumn指出外键所在的列名 */
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="Book_Id")
    public Book getBook() { ... }
    public void setBook(Book book) { ... }
}

双向索引

我们更希望的是在Book中获取BookPrice的信息,这就是双向索引。在双向所以中BookPrice的代码和单向索引一样,不再重复,重点看看Book。

@Entity
public class Book {
    private long id;
    private String bookName;	
    private BookPrice bookPrice;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public long getId() { ... }
    public void setId(long id) { ... }

    public String getBookName() { ... }
    public void setBookName(String bookName) { ... }
    
    /* 提供@OneToOne指出Entity之间的是一对一的关系:
     * mappedBy:指出OneToOne关系的另一头(BookPrice)中哪个属性和本entity对应,本例为BookPrice.book,填book
     * cascade:DETACH, MERGE,PERSIST, REFRESH, and REMOVE ,ALL表示全部。
     * orphanRemoval:如果为true,当设bookprice为null,则相关的在bookprice表格的内容也会删除。
     * optional : false表明对方必须存在,应为非null值。true为缺省值。
     *            但在测试中,optional = false:仍可将值设为null,联动删除bookPrice的相关行。 
     * */
    @OneToOne(mappedBy="book",fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
    public BookPrice getBookPrice() { ... }	
    public void setBookPrice(BookPrice bookPrice) { ... }
}

相关链接:我的Professional Java for Web Applications相关文章

猜你喜欢

转载自blog.csdn.net/flowingflying/article/details/81282569