hibernate annotation映射关系详解

在hibernate中处理关系映射的方法有两种。一种是使用传统的xml来处理它们的映射关系,另一种是基于annotation的注解方式。我个人非常喜欢使用annotation,觉得这种方式显得更加的简洁,大大减少工作量。在hibernate4中annotation包无需再引入,因为已经集成了annotation包。

 

在讲hibernate annotation之前,我们先回想一下。在数据库创建表的时候有几个关键点是必须的。表名、字段名、字段类型、约束条件。从这些点出发我们来看看一个hibernate实体模型的实体类如何使用annotation来表示出我们想要的几个关键点。

@Entity 
@Table(name = "tbl_user") //--->table指定数据库中表的名字
public class User {
    private UUID userID;
    private String userName;
    private String name;
    private String passWord;
    private Date workTime;
    private Role role;
    public enum Role {
        服务员,店主,厨师
    }
    
    @Id  
    @GenericGenerator(name = "generator", strategy = "uuid")  //--->表示主键自动生成,策略是生成guid
    @GeneratedValue(generator = "generator")  
    @Column(name = "userID", length=20)  //--->column指定数据库中表列属性的名字
    public UUID getUserID() {
        return userID;
    }
    public void setUserID(UUID userID) {
        this.userID = userID;
    }
    
    @Column(name="userName",length=16,nullable=false)
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    @Column(name="name",length=10,nullable=false) 
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    @Column(name="passWord",length=16,nullable=false)
    public String getPassWord() {
        return passWord;
    }
    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }
    
    @Column(name="workTime",nullable=false)
    public Date getWorkTime() {
        return workTime;
    }
    public void setWorkTime(Date workTime) {
        this.workTime = workTime;
    }
    
    @Enumerated(EnumType.STRING)  //--->则使用@Enumerated注解。该注解可以让你选择枚举类型的同时,把枚举类型转化为String插入数据库
    @Column(name="role",columnDefinition="varchar(20) default ‘服务员‘")//--->columnDefinition对字段的属性的约束进行设置
    public Role getRole() {
        return role;
    }
    public void setRole(Role role) {
        this.role = role;
    }
}

 

在建映射的时候我们往往感觉思路非常的乱,这是因为你一边要考虑数据库问题,一边觉得它是实体类应该如何处理。其实你可以这样想,有些annotation是用来生成数据库的这些annotation并不是很多,在建模的时候应该先把它们写上去。然后去处理它们的映射关系。

常用的数据库annotation有:(站在数据库角度)

@Table       --处理表

@Column     --处理字段

@JoinColumn    --处理外键

 

这里讲个食物(Food)、食物类别(FoodType)的关系(站在实体类的角度)

很明显一个Food只能对应一个类别(不考虑特殊情况),那么如果我们要用一个Food得到一个FoodType的数据。我们可以在该类中添加一个FoodType。

一个FoodType下可以有多个Food,那么我们可以在该类中添加一个Set<Food>。

@Entity
@Table(name = "tbl_foodType")
public class FoodType {

    private UUID foodTypeID;
    private String name;

    @Id  
    @GenericGenerator(name = "generator", strategy = "uuid")  
    @GeneratedValue(generator = "generator")  
    @Column(name = "foodTypeID", length=20)  
    public UUID getFoodTypeID() {
        return foodTypeID;
    }

    public void setFoodTypeID(UUID foodTypeID) {
        this.foodTypeID = foodTypeID;
    }

    @Column(name = "name", length=20,nullable=false)  
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private Set<Food> foodList;
    
    @OneToMany(mappedBy="foodType")// 建立一对多的关系,foodType是Food类中的属性 
    public Set<Food> getFoodList() {
        return foodList;
    }

    public void setFoodList(Set<Food> foodList) {
        this.foodList = foodList;
    }
    
}

 

@Entity
@Table(name = "tbl_food")
public class Food {

    private UUID foodID;
    private String url;
    private Double price;
    private String name;
    private Deleted isDeleted;

    @Id
    @GenericGenerator(name = "generator", strategy = "uuid")
    @GeneratedValue(generator = "generator")
    @Column(name = "foodID", length = 20)
    public UUID getFoodID() {
        return foodID;
    }

    public void setFoodID(UUID foodID) {
        this.foodID = foodID;
    }

    @Column(name = "url", length = 100)
    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Column(name = "price", columnDefinition = "float default 0")
    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Column(name = "name", nullable = false)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Enumerated(EnumType.STRING)
    @Column(name = "isDeleted", columnDefinition = "varchar(20) default ‘NO‘", nullable = false)
    public Deleted getIsDeleted() {
        return isDeleted;
    }

    public void setIsDeleted(Deleted isDeleted) {
        this.isDeleted = isDeleted;
    }

    private FoodType foodType;
    @ManyToOne
    @JoinColumn(name="foodTypeID")  //--->指定数据库外键的名字
    public FoodType getFoodType() {
        return foodType;
    }

    public void setFoodType(FoodType foodType) {
        this.foodType = foodType;
    }
    
}

 

善于观察的你会发现上面是一种一对多、多对一的情况。在hibernate映射关系中还有多对多、一对一等。

一对一与一对多、多对一本质是一模一样的,无非就是把一的一方的Set<Object>改成Object。

至于多对多通常在建模的时候把它们看成两组一对多、多对一的模型。所以你只要学会上面这种情况,关系映射你就学会了80%。

 

现在映射差不多已经完成了,现在还有一个问题就是数据的加载()

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。