双向一对多外联关系(外键)

来源:互联网 发布:ios6不越狱安装软件 编辑:程序博客网 时间:2024/05/16 00:43

首先是两个Bean类,Customer用户类,Order订单类,其中Order订单中添加了外键,引用Customer的字段

Customer类

//用户public  class Customer {    //用户ID    private Integer customerId;    //用户名    private String customerName;    /**     * 1:声明集合类型时,需使用接口类型,因为Hibernate在获取     * 集合类型时,返回的是Hibernate内置的集合类型,而不是Java SE一个标准的     * 集合实现     * 2:需要把集合初始化,防止空指针异常     */    private Set<Order> orders = new HashSet<Order>();    public Set<Order> getOrders() {        return orders;    }    public void setOrders(Set<Order> orders) {        this.orders = orders;    }    public Customer() {        super();    }    public Customer(Integer customerId, String customerName) {        super();        this.customerId = customerId;        this.customerName = customerName;    }    public Integer getCustomerId() {        return customerId;    }    public void setCustomerId(Integer customerId) {        this.customerId = customerId;    }    public String getCustomerName() {        return customerName;    }    public void setCustomerName(String customerName) {        this.customerName = customerName;    }    @Override    public String toString() {        return "Customer [customerId=" + customerId + ", customerName="                + customerName + "]";    }}

Order类

//订单类public class Order {    //订单ID    private Integer orderId;    //订单名    private String orderName;    //外键,引用Customer    private Customer customer;    public Order() {        super();    }    public Order(Integer orderId, String orderName, Customer customer) {        super();        this.orderId = orderId;        this.orderName = orderName;        this.customer = customer;    }    public Integer getOrderId() {        return orderId;    }    public void setOrderId(Integer orderId) {        this.orderId = orderId;    }    public String getOrderName() {        return orderName;    }    public void setOrderName(String orderName) {        this.orderName = orderName;    }    public Customer getCustomer() {        return customer;    }    public void setCustomer(Customer customer) {        this.customer = customer;    }    @Override    public String toString() {        return "Order [orderId=" + orderId + ", orderName=" + orderName                + ", customer=" + customer + "]";    }}

然后是XML配置文件

Customer.hbm.xml

<?xml version="1.0"?>      <!DOCTYPE hibernate-mapping PUBLIC         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" ><hibernate-mapping package="entity2">    <class name="Customer" table="customer">        <!-- id:表中的主键,name:类中的属性名 -->        <id name="customerId" type="java.lang.Integer">            <!-- name:表中的序列名 -->            <column name="customer_id"/>            <!-- 指定主键的生成方式,native:使用数据库本地的方式 -->            <generator class="native"/>        </id>        <!-- property一般字段 -->        <property name="customerName" type="java.lang.String">            <column name="customer_name"/>        </property>        <!--             table:与Order的表名对应            key的column:与Order的外键字段名对应            inverse:true,Customer放弃维护Order的外键引用                    可以减少UPDATE语句         -->        <set name="orders" table="orders" inverse="true">            <key column="customer_id"></key>            <one-to-many class="Order"/>        </set>    </class></hibernate-mapping>

Order.hbm.xml

<?xml version="1.0"?>      <!DOCTYPE hibernate-mapping PUBLIC         "-//Hibernate/Hibernate Mapping DTD 3.0//EN"         "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" ><hibernate-mapping package="entity2">    <class name="Order" table="orders">        <!-- id:表中的主键,name:类中的属性名 -->        <id name="orderId" type="java.lang.Integer">            <!-- name:表中的序列名 -->            <column name="order_id"/>            <!-- 指定主键的生成方式,native:使用数据库本地的方式 -->            <generator class="native"/>        </id>        <!-- property一般字段 -->        <property name="orderName" type="java.lang.String">            <column name="order_name"/>        </property>        <!-- 映射多对一的关联关系 -->        <many-to-one name="customer" class="Customer" column="customer_id"></many-to-one>    </class></hibernate-mapping>

hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?>      <!DOCTYPE hibernate-configuration PUBLIC         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory>        <!-- 配置连接数据库的基本信息 -->        <property name="connection.username">root</property>        <property name="connection.password">1234</property>        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property>        <!-- 配置Hibernate的基本信息 -->        <!-- Hibernate所使用的数据库方言 -->        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>        <!-- 执行操作时是否在控制台打印SQL -->        <property name="show_sql">true</property>        <!-- 是否对SQL进行格式化 -->        <property name="format_sql">true</property>        <!-- 指定自动生成数据表的策略 -->        <property name="hbm2ddl.auto">update</property>        <!-- 指定   关联的关系/映射   文件,引入Bean的xml文件 -->        <!-- 注:不是打.  用/ -->        <!-- <mapping resource="entity1/Customer.hbm.xml"/>        <mapping resource="entity1/Order.hbm.xml"/> -->        <mapping resource="entity2/Customer.hbm.xml"/>        <mapping resource="entity2/Order.hbm.xml"/>    </session-factory></hibernate-configuration> 

HibernateTest测试类

public class HibernateTest {    private SessionFactory sessionFactory;    private Session session;    private Transaction transaction;    @Before    public void init() {        // 1.创建一个SessionFactory 对象        sessionFactory = null;            // 1.创建Configuration对象:对应Hibernate的基本配置信息和对象关系映射信息            // configure();读取配置文件,无参默认读取hibernate.cfg.xml            Configuration configuration = new Configuration().configure();            /**             * new Configuration 的几个方法             *              * 读取的是hibernate.properties配置文件             * 1:Configuration configuration = new Configuration();             *              * 读取配置文件,无参默认读取hibernate.cfg.xml             * 2:Configuration configuration = new Configuration().configure();             *              * 读取配置文件,读取指定xml,传入一个File             * 3:Configuration configuration = new Configuration().configure(file);             */            // 2.创建一个ServiceRegistry对象            // Hibernate 的任何配置和服务都需要在该对象中注册后才有效            ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()                .applySettings(configuration.getProperties())                .buildServiceRegistry();            // 3.创建一个SessionFactory            sessionFactory = configuration.buildSessionFactory(serviceRegistry);        // 2.创建一个Session对象        session = sessionFactory.openSession();        // 3.开启事物        transaction = session.beginTransaction();    }    @After    public void distroy() {        // 5.提交事物        transaction.commit();        // 6.关闭Session对象        session.close();        // 7.关闭SessionFactory对象        sessionFactory.close();    }    @Test     public void test1(){        Customer customer = new Customer();        customer.setCustomerName("1");        Order order1 = new Order();        Order order2 = new Order();        order1.setOrderName("1");        order2.setOrderName("2");        //设置外键关系        order1.setCustomer(customer);        order2.setCustomer(customer);        //在customer中添加引用该外键的Order订单        customer.getOrders().add(order1);        customer.getOrders().add(order2);        /**         * 先插入Customer,在插入Order         * 3条INSERT,2条UPDATE         * 因为Customer和Order都维护关联关系,所以         * Order插入后,Customer会更新(UPDATE)Order的外键         *          * 可以在Customer的配置文件Set中指定节点inverse="true"         * 放弃维护Order的外键引用,会只有3条INSERT         */        session.save(customer);        session.save(order1);        session.save(order2);        /**         * 先插入Order,在插入Customer         * 3条INSERT,4条UPDATE         * 因为Customer和Order都维护关联关系         *          * 可以在Customer的配置文件Set中指定节点inverse="true"         *  放弃维护Order的外键引用,会只有3条INSERT,2条UPDATE         */        //Order负责更新order1记录        session.save(order1);        //Order负责更新order2记录        session.save(order2);        //Customer负责更新order1,order2记录        session.save(customer);    }    //查    @Test    public void test2(){        /**         * 对customer里的orders List集合使用延迟加载         * 如果不使用orders的List集合,则不发生SQL查询Order语句         */        Customer customer = (Customer) session.get(Customer.class,1);        /**         * 返回的集合为Hibernate内置的集合类型         * 该类型具有延迟加载和存放代理对象的功能         */        Set<Order> orders = customer.getOrders();    }    //查    @Test    public void test3(){        Customer customer = (Customer) session.get(Customer.class,1);        /**         * 可能会抛出LazyInitializationException异常         * 如果customer还没有使用orders集合         * 且session.close()         * 则抛异常         */        session.close();        System.out.println(customer.getOrders().size());    }    //改    @Test    public void test4(){        //可以利用customer里的orders Set集合更改order        Customer customer = (Customer) session.get(Customer.class,1);        //但是更改的哪个order是不确定的,因为Set集合特性:无序        customer.getOrders().iterator().next().setOrderName("GGG");    }    //删    @Test    public void test5(){        /**         * 在不设置级联关系的情况下,并且被引用的外键(Customer用户表)         * 有被Order(订单表)引用外键,不能直接删除customer         */        Customer customer = (Customer) session.get(Customer.class,1);        session.delete(customer);    }}
1 0
原创粉丝点击