黑马程序员技术交流社区

标题: 【济南校区】Hibernate中多表关联的映射配置之1对多和多对多 [打印本页]

作者: 大山哥哥    时间: 2018-6-3 20:47
标题: 【济南校区】Hibernate中多表关联的映射配置之1对多和多对多
表关联之1对多

主表:Customer
        一个客户对应多个订单,需要先通过一对多和订单建立连接,同时将用户对应信息保存到Order中的mCustomer里,外键由Order去管理
       
从表:Order
        多个订单绑定一个用户,需要通过多对一将每个订单和用户先对应起来,并且将该用户的对应订单保存到Customer中


第一步:定义Customer实体类,配置注解一对多

[Java] 纯文本查看 复制代码
        @Entity
        @Table(name="t_customer",catalog="db_hibernate_study")
        public class Customer {

                @Id
                @GeneratedValue
                private Integer id; // 主键
                private String name; // 姓名

                /*
                 * targetEntity相当于<one-to-many class="">
                 * mappedBy相当于inverse=true
                 */
                @OneToMany(targetEntity=Order.class,mappedBy="mCustomer",orphanRemoval=true)
                @Cascade(CascadeType.SAVE_UPDATE)
                private Set<Order> orders = new HashSet<Order>();//当前用户对应的所有订单
               
                //省略get/set方法
                ......
               
        }


第二步:定义Order实体类,配置注解多对一

[Java] 纯文本查看 复制代码
        @Entity
        @Table(name="t_order",catalog="db_hibernate_study")
        public class Order {

                @Id
                @GeneratedValue
                private Integer id;

                private Double money;

                private String receiverInfo; // 收货地址
               
               
                // 订单与客户关联
                @ManyToOne(targetEntity = Customer.class)
                @JoinColumn(name = "c_customer_id") // 指定外键列
                @Cascade(CascadeType.SAVE_UPDATE)
                private Customer mCustomer; // 描述订单属于某一个客户
                       
                //省略get/set方法
                ......
        }


第三步:在配置文件中hibernate.cfg.xml中的mapping中引入映射

[Java] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

        <session-factory>
                ...
                <property name="hibernate.hbm2ddl.auto">update</property>
                -----------------------------------------
                <mapping class="com.b3a4a.one2more.Order"/>
                <mapping class="com.b3a4a.one2more.Customer"/>
                -----------------------------------------
        </session-factory>

</hibernate-configuration>


第四步:测试用例

[Java] 纯文本查看 复制代码
        @Test
        public void test() {
                Session mSession = new Configuration().configure()
                                                                                        .buildSessionFactory()
                                                                                        .openSession();
                mSession.beginTransaction();

                // 1.创始一个客户
                Customer c = new Customer();
                c.setName("b3a4a");

                // 2创始两个订单
                Order o1 = new Order();
                o1.setMoney(100d);
                o1.setReceiverInfo("北京");
                Order o2 = new Order();
                o2.setMoney(2000d);
                o2.setReceiverInfo("上海");

                // 3.建立关系
                //--------------重要①----------------
                // 原因:是为了维护外键
                o1.setC(c);
                o2.setC(c);
                //----------------------------------
                // 原因:是为了进行级联操作
                c.getOrders().add(o1);
                c.getOrders().add(o2);

                // 4.保存客户,并级联保存订单
                mSession.save(c);
                mSession.getTransaction().commit();
                mSession.close();

        }

       
重要①解释说明:

如果1那里不将订单和客户绑定的话,那在从表(t_order)中外键c_customer_id值为null,因为我们在主表中设置mappedBy="mCustomer"外键是由Order中的mCustomer来进行管理


表关联之多对多


学生(t_student)
        一个学生有多个老师

老师(t_teacher)
        一个老师有多个学生
       
中间表(t_s)

注意事项:
使用@ManyToMany来配置多对多,只需要在一端配置中间表,另一端使用mappedBy表示放弃外键维护权。



第一步:定义Student实体类,配置注解多对多

[Java] 纯文本查看 复制代码
@Entity
@Table(name="t_studnet",catalog="db_hibernate_study")
public class Student {
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer sid;
        private String sname;
        //----------------------------------------------------------
        @ManyToMany(targetEntity=Teacher.class)
        @JoinTable(name="t_s",
                joinColumns= {
                        @JoinColumn(name = "c_sid",referencedColumnName = "sid")
                },
                inverseJoinColumns= {
                        @JoinColumn(name = "c_tid",referencedColumnName = "tid")               
                })
        @Cascade(CascadeType.ALL)
        private List<Teacher> teachers = new ArrayList<Teacher>();
        //----------------------------------------------------------
       
        //省略get/set方法
        ......
}




第二步:定义Teacher实体类,配置注解多对多

[Java] 纯文本查看 复制代码
@Entity
@Table(name="t_teacher",catalog="db_hibernate_study")
public class Teacher {
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer tid;
        private String tname;
        //----------------------------------------------------------
        @ManyToMany(targetEntity=Student.class,mappedBy="teachers")
        @Cascade(CascadeType.ALL)
        private List<Student> students = new ArrayList<Student>();
        //----------------------------------------------------------       
        //省略get/set方法
        ......
}



第三步:在配置文件中hibernate.cfg.xml中的mapping中引入映射

[Java] 纯文本查看 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

        <session-factory>
                ......
                <property name="hibernate.hbm2ddl.auto">update</property>
                -----------------------------------------
                <mapping class="com.b3a4a.many2many.Student"/>
                <mapping class="com.b3a4a.many2many.Teacher"/>
                -----------------------------------------
        </session-factory>

</hibernate-configuration>       


第四步:测试用例

[Java] 纯文本查看 复制代码
        @Test
        public void testMany2Many() {
                Session mSession = new Configuration().configure()
                                                                                        .buildSessionFactory()
                                                                                        .openSession();
                mSession.beginTransaction();
               
                Teacher t1 =new Teacher();
                t1.setTname("苍老师");
                Teacher t2 =new Teacher();
                t2.setTname("波多老师");
                Student s1 = new Student();
                s1.setSname("张三");
                Student s2 = new Student();
                s2.setSname("李四");
               
                //关系
                s1.getTeachers().add(t1);
                s1.getTeachers().add(t2);
                s2.getTeachers().add(t1);
                s2.getTeachers().add(t2);
               
               
                mSession.save(s1);
                mSession.save(s2);
               
                mSession.getTransaction().commit();
                mSession.close();
        }




作者: zha0826    时间: 2018-6-4 09:33
厉害厉害




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2