• hibernate多对多映射拆成2个一对多映射(注解)


    hibernate的many to many确实很是方便我们处理实体和集合间的关系,并可以通过级联的方法处理集合,但有的时候many to many不能满足我们的需要,比如 用户<--->选课,典型的多对多关系,一般情况下,会生成

    course_user(course_id,user_id);

    但用户选课的时候最好加入审核功能,所以我们希望在中间自动生成的表中加入一个boolean字段,类似这种结构:

    course_user(course_id,user_id,accessable);

    这个时候我们可以把many to many拆分成2个many to one ,自己手动添加个中间表,这样扩展就好很多了。

    代码如下:

    @Embeddable
    public class CourseUserPK implements Serializable{
        private static final long serialVersionUID = 1L;
        private Course course;
        private User user;

        @ManyToOne
        @JoinColumn(name = "course_id", nullable = false)
        public Course getCourse() {
            return course;
        }

        public void setCourse(Course course) {
            this.course = course;
        }
        @ManyToOne
        @JoinColumn(name = "user_id", nullable = false)
        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

        public boolean equals(Object object) {
            if (this == object)
                return true;
            if (!(object instanceof CourseUserPK))
                return false;
            final CourseUserPK other = (CourseUserPK) object;
            if (this.course != null && other.getCourse() != null) {
                if(course.getId() == other.course.getId()) {
                    if(user!=null&&other.getUser()!=null&&user.getId()==other.getUser().getId()) {
                        return true;
                    } else {
                        return false;
                    }
                } else {
                    return true;
                }
            } else
                return false;
        }

        public int hashCode() {
            return super.hashCode()+
                    (course!=null?course.hashCode():0)+
                    (user!=null?user.hashCode():0);
        }
    }

    @Entity
    @IdClass(CourseUserPK.class)
    public class CourseTeacher {

        private Course course;
        private User user;
        private Boolean accessable;//true user is in course, otherwise not
       
        public CourseTeacher(Course course, User user, Boolean accessable) {
            this.course = course;
            this.user = user;
            this.accessable = accessable;
        }
        @Id
        public Course getCourse() {
            return course;
        }
        public void setCourse(Course course) {
            this.course = course;
        }
        @Id
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        public Boolean getAccessable() {
            return accessable;
        }
        public void setAccessable(Boolean accessable) {
            this.accessable = accessable;
        }
    }

    @Entity
    @IdClass(CourseUserPK.class)
    public class CourseStudent {

        private Course course;
        private User user;
        private Boolean accessable;//true user is in course, otherwise not
       
       
        public CourseStudent(Course course, User user, Boolean accessable) {
            this.course = course;
            this.user = user;
            this.accessable = accessable;
        }
        @Id
        public Course getCourse() {
            return course;
        }
        public void setCourse(Course course) {
            this.course = course;
        }
        @Id
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        public Boolean getAccessable() {
            return accessable;
        }
        public void setAccessable(Boolean accessable) {
            this.accessable = accessable;
        }
    }

    @Entity
    public class Course extends BaseEntity {
        private static final long serialVersionUID = 8768227695335084711L;
        private Set<CourseTeacher> teachers;
        private Set<CourseStudent> students;
       
        @OneToMany(mappedBy="course",cascade=CascadeType.ALL)
        public Set<CourseTeacher> getTeachers() {
            return teachers;
        }
        public void setTeachers(Set<CourseTeacher> teachers) {
            this.teachers = teachers;
        }
        @OneToMany(mappedBy="course")
        public Set<CourseStudent> getStudents() {
            return students;
        }
        public void setStudents(Set<CourseStudent> students) {
            this.students = students;
        }
    }

    image

    image

    参考文章:http://www.4ucode.com/Study/Topic/1070774

    Hibernate可以通过*.hbm.xml配置文件能很好地把多对多关系拆分成两个一对多的关系,但Hibernate Annotation的文档中没有说到这个点上来。下面通过实例说明用注解来实现多对多拆分成两个一对多。

    下面以商品Product和订单Order之间的多对多关系来说明。

          Product的属性包括:

    • id
    • name
    • price

    Order的属性包括:

    • id
    • date(下订单的时间)
    为什么要把多对多关系拆分成两个一对多?

    因为多对多关系不能保存两个实体之间共有的属性。比如,如何记录订单A中购买的商品B的数量呢?如果以多对多映射就不能实现了。

    中间实体----用来记录两个多对多实体之间共有关系

    在Product和Order之间的关系中,可以用一个OrderItem实体来表示两者多对多中的众多关系中的一个关系。即Product与OrderItem,Order与OrderItem之间的关系为一对多的关系。

    OrderItem的属性包括:

    • product(假如当前记录的是商品C)
    • order(假如当前记录的是订单D)
    • quantity(这里记录的是订单D中商品C的数量)
    实例代码(省略了类包引用):
    复合主键类:
    @Embeddable
    public class OrderItemPK implements Serializable{
        private Product product;
        private Order order;
    
        @ManyToOne
        @JoinColumn(name="product_id",referencedColumnName="id")
        public Product getProduct(){
            return product;
        }
        public void setProduct(Product product){
            this.product=product;
        }
    
        @ManyToOne
        @JoinColumn(name="order_id",referencedColumnName="id")
        public Order getOrder(){
            return order;
        }
        public void setOrder(Order order){
            this.order=order;
        }
        public boolean equals(Object object){...}
        public int hashCode(){...}
    }
    OrderItem类:
    @Entity
    @org.hibernate.annotation.Entity(dynamicInsert=true,dynamicUpdate=true)
    @Table(name="order_item")
    @IdClass(OrderItemPK.class)
    public class OrderItem implements Serializable{
        
        private Product product;
        private Order order;
        private int quantity;
    
        @Id
        public Product getProduct(){
            return product;
        }
        public void setProduct(Product product){
            this.product=product;
        }
        @Id
        public Order getOrder(){
            return order;
        }
        public void setOrder(Order order){
            this.order=order;
        }
    
        @Column(name="quantity")
        public int getQuantity(){
            return quantity;
        }
        public void setQuantity(int quantity){
            this.quantity=quantity;
        }
    }
    Product类:
    @Entity
    @org.hibernate.annotation.Entity(dynamicInsert=true,dynamicUpdate=true)
    @Table(name="product")
    public class Product implements Serializable{
        private int id;
        private String name;
        private double price;
        private Set<OrderItem> orderItems;
    
        @Id
        @GenericGenerator(name="g_id",strategy="increment")
        @GeneratedValue(generator="g_id")
        public int getId(){
             return id;
        }
        public void setId(int id){
             this.id=id;
        }
        public String getName(){
             return name;
        }
        public void setName(String name){
             this.name=name;
        }
        public double getPrice(){
             return price;
        }
        public void setPrice(double price){
             this.price=price;
        }
        
        @OneToMany(mappedBy="product")
        public Set<OrderItem> getOrderItems(){
             return orderItems;
        }
        public void setOrderItems(Set<OrderItem> orderItems){
             this.orderItems=orderItems;
        }
    }
    Order类:
    @Entity
    @org.hibernate.annotation.Entity(dynamicInsert=true,dynamicUpdate=true)
    @Table(name="tbl_order")
    public class Order implements Serializable{
        private int id;
        private Calendar date;
        private Set<OrderItem> orderItems;
    
        @Id
        @GenericGenerator(name="g_id",strategy="increment")
        @GeneratedValue(generator="g_id")
        public int getId(){
            return id;
        }
        public void setId(int id){
            this.id=id;
        }
        public Calendar getDate(){
            return date;
        }
        public void setDate(Calendar date){
            this.date=date;
        }
    
        @OneToMany(mappedBy="order")
        public Set<OrderItem> getOrderItems(){
            return orderItems;
        }
        public void setOrderItems(Set<OrderItem> orderItems){
            this.orderItems=orderItems;
        }
    }
  • 相关阅读:
    struts2 <s:iterator> 遍历方法
    JSP 基础之 JSTL <c:forEach>用法
    struts2 中 Session的使用简介
    Struts2 工作流程
    Aandroid Error之 新导入工程报Unable to resolve target 'android-18'和R cannot be resolved
    纯Html+Ajax和JSP两者对比的个人理解
    移动互联网App兼容性测试
    【转】【Mac】invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library
    【转】Mac使用apt-get
    有趣网址之家 – 收藏全球最有趣的网站
  • 原文地址:https://www.cnblogs.com/syxchina/p/2439280.html
Copyright © 2020-2023  润新知