JPA学习笔记-EJB-04JPA关联映射总结--6

TeamVO

package mangerTeam.vo;

 

import java.io.Serializable;

import java.util.Set;

 

import javax.persistence.CascadeType;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.FetchType;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.OneToMany;

import javax.persistence.Table;

 

/**

 * 俱乐部实体

 * @author 刘岩

 */

@Entity

@Table(name = "team")

public class TeamVO implements Serializable {

        

         @Id

         @GeneratedValue(strategy = GenerationType.AUTO)

         @Column(name = "id", unique = true, nullable = false)

         private Integer id;

        

         @Column(name = "teamName")

         private String teamName;

        

         @OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "teamVO")

         private Set<PlayersVO> players;

 

         public Integer getId() {

                   return id;

         }

 

         public void setId(Integer id) {

                   this.id = id;

         }

 

         public String getTeamName() {

                   return teamName;

         }

 

         public void setTeamName(String teamName) {

                   this.teamName = teamName;

         }

 

         public Set<PlayersVO> getPlayers() {

                   return players;

         }

 

         public void setPlayers(Set<PlayersVO> players) {

                   this.players = players;

         }

        

}

在此类中注意如下片段

@OneToMany(cascade = CascadeType.REFRESH, fetch = FetchType.LAZY, mappedBy = "teamVO")

         private Set<PlayersVO> players;

 

即是声明和运动员一对多的关系

cascade = CascadeType.REFRESH:级联更新,当俱乐部信息更新的时候相应俱乐部中的运动员也更新,当俱乐部被删除的时候,不能把运动员也从数据库中删除了吧,所以这里只是REFRESH的时候才会级练到运动员,其他的操作不必理睬运动员。

mappedBy = "teamVO":表示teamVO在双方关系中属于被维护的一方,那么PlayersVO就是维护方,那么造成一个后果就是只能PlayersVO去更新外键,PlayersVOTeamVO之间的外键关联关系是PlayersVO说了算的。结合实际就是,“宁教老子负公司,休教公司负老子”,老子不爽了可以走人、你公司不爽老子还得继续忍着吧……

具体业务代码和N VS M的差不多,在此不再赘述。

1.       1 VS 1映射总结

一对一的映射模型如下描述:

一个商品实体VS 此商品的详细信息实体。

每一个商品都唯一对应一个详细信息的描述,商品实体可以没有详细信息实体。

此处我们只给出代码片段

Products(商品实体)

 

/**

 * Products

 */

@Entity

@Table(name = "products", catalog = "tgweb")

public class Products implements java.io.Serializable {

 

    @Id

    @GeneratedValue(strategy = IDENTITY)

    @Column(name = "id", unique = true, nullable = false)

    private Long id;

 

 

    /**

     * 详细信息

     * */

    @OneToOne(optional = true, cascade = CascadeType.ALL)

    @JoinColumn(name = "productsMessageInfo_ID")

    private ProductsMessageInfo productsMessageInfo;

 

    /** default constructor */

    public Products() {

    }

 

…………………省略…………………

 

    public ProductsMessageInfo getProductsMessageInfo() {

       return productsMessageInfo;

    }

 

    public void setProductsMessageInfo(ProductsMessageInfo productsMessageInfo) {

       this.productsMessageInfo = productsMessageInfo;

    }

 

}

说明:

    @OneToOne(optional = true, cascade = CascadeType.ALL)

表示和商品详细信息是一对一的关系,级联操作是当商品所有的持久化操作都会关联到详细信息的操作,详细信息可以为空。

    @JoinColumn(name = "productsMessageInfo_ID")

在商品表中建立一个外键用于维护和商品详细信息的关系。字段名称为productsMessageInfo_ID

注意:因为在商品中所有的操作都会影响到商品详细信息,所以更新商品的时候应该先将详细信息查询出来后再保存,和1 VS N一样的道理。

总结:

1.  感觉在做实体操作(尤其是更新的时候),往往都需要将原始体的关联实体临时保存到一个地方,之后还得原封不同的赋值给新实体,之后再保存。这就是级联操作的影响。要不将所有的实体属性全部加载到展示层上,View的压力比较大。

2.  在做建模设计的时候,尤其以多对多映射最为复杂、查询效率也是最低的,偶尔为了解决一个比较复杂的业务,可能要借助中间模型来做N VS M的桥梁。

3.  有效地利用Java集合映射属性,ListSetMap等不同特点来建模。在未确定使用Set或者List的时候可以使用他们的父类CollectionSet里面的元素不能重复,这个可以通过Setequalhashcode方法区分是否是同一条实体记录。List是有顺序的、并且里面元素可以重复。

4.  一般都是1 VS NN VS 1N VS M的需求比较多,而1 VS 1相对于前几者相对来说业务需求比较少。

5.  建模、设计领域模型、类关系思考需要的时间肯定远远大于编程的时间。

6.  级联策略完全由系统的业务需求而定,没绝对的正确,也没有绝对的错误,级联策略的选择是在一个折中的情况下而制定的,有可能业务层需要多些几行代码,有可能在视图层多写一些代码来维护原有的关联关系,这个完全取决于业务。

7.  在笔者的这份经验总结中只是关联映射的一部分实现而已,像双向一对一、单向一对多、单向多对一并没有总结在这份文档中,因为暂时并无此业务需求,每每发现做单向关联设计的时候,还是双向的比较好,双方都能找到对方。以后有机会一定补上。

如果有什么不正确的希望不吝指正。

你可能感兴趣的:(编程,ejb,jpa,领域模型)