Hibernate中的单项n 到 1说明

Customer.java:

package hibernate.sessiondemo;

public class Customer {
	private Integer customerId;
	private String 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.java

package hibernate.sessiondemo;

public class Order {
    private Integer orderId;
    private String orderName;

    private 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 + "]";
    }

}

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">
<!-- Generated Feb 20, 2016 5:38:35 PM by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="hibernate.sessiondemo.Customer" table="CUSTOMERS">
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
        <property name="customerName" type="java.lang.String">
            <column name="CUSTOMER_NAME" />
        </property>
    </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">
<!-- Generated Feb 20, 2016 5:38:35 PM by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping package="hibernate.sessiondemo">
    <class name="Order" table="ORDERS">
        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>

        <!--
                                     在这个例子中,每个单子值能属于一个客户,而一个客户可以拥有多个单子,所以这个是一个n-1的关系 order是n, customer是1
                                     映射多对一的关联关系, 使用many-to-one 来映射多对一的关联关系
            name: 多这一端关联的一的那一端的属性的名字
            column: 一那一端在多的一端对应的数据表中的外键的名字
         -->
        <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://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
     <!-- 配置链接数据库的基本信息 -->
    <property name="connection.username">root</property>
    <property name="connection.password">86915310</property>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="connection.url">jdbc:mysql://localhost:3306/user</property>

    <!-- 配置hibernate的基本信息 -->
    <!-- hibernate所使用的数据库方言 -->
    <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

    <!-- 是否在控制台打印SQL -->
    <property name="show_sql">true</property>

    <!-- 是否对SQL进行格式化 -->
    <property name="format_sql">true</property>

    <!-- 指定自动生成数据表的策略 -->
    <property name="hbm2ddl.auto">update</property>

    <!-- 设置hibernate的事务隔离级别 -->
    <property name="connection.isolation">2</property>

    <!-- 在执行完delete后可以把OID 设置为空 -->
    <!--  <property name="use_identifier_rollback">true</property>  -->

    <!-- 指定关联的.hbm.xml文件 -->
    <mapping resource="hibernate/sessiondemo/Order.hbm.xml"/>
    <mapping resource="hibernate/sessiondemo/Customer.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

HibernateTest.java

package hibernate.sessiondemo;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Date;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.jdbc.Work;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class HibernateTest {

    private SessionFactory sessionFactory;
    private Session session;
    private Transaction transaction;

    @Before
    public void init(){
        // 1. 创建一个 SessionFactory 对象
        StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder()
                .configure("hibernate.cfg.xml").build();

        Metadata metadata = new MetadataSources(standardServiceRegistry).addAnnotatedClass(Customer.class)
                .addAnnotatedClassName("hibernate.sessiondemo.Customer").addResource("/hibernate/sessiondemo/Customer.hbm.xml")
                .getMetadataBuilder().applyImplicitNamingStrategy(ImplicitNamingStrategyJpaCompliantImpl.INSTANCE)
                .build();

        sessionFactory = metadata.getSessionFactoryBuilder().build();

        // 2. 创建一个 Session对象
        session = sessionFactory.openSession();
        System.out.println(session);

        // 3. 开启事务
        transaction = session.beginTransaction();
    }

    @After
    public void destroy(){
        // 5. 提交事务
        transaction.commit();

        // 6. 关闭session
        session.close();

        // 7. 关闭sessionFactory对象
        sessionFactory.close();
    }
    @Test
    public void testDelete(){
        //在不设定级联关系的情况下,且1  这一端的对象有 n端的引用, 不能直接删除1 这一端的对象
        Customer customer = session.get(Customer.class, 5);
        session.delete(customer);
    }

    @Test
    public void testUpdate(){
/*        Hibernate:
            select
                order0_.ORDER_ID as ORDER_ID1_1_0_,
                order0_.ORDER_NAME as ORDER_NA2_1_0_,
                order0_.CUSTOMER_ID as CUSTOMER3_1_0_
            from
                ORDERS order0_
            where
                order0_.ORDER_ID=?
        Hibernate:
            select
                customer0_.CUSTOMER_ID as CUSTOMER1_0_0_,
                customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_
            from
                CUSTOMERS customer0_
            where
                customer0_.CUSTOMER_ID=?
        Hibernate:
            update
                CUSTOMERS
            set
                CUSTOMER_NAME=?
            where
                CUSTOMER_ID=?    */
        Order order = (Order) session.get(Order.class, 1);
        order.getCustomer().setCustomerName("Liang Yongqi");
    }

    @Test
    public void testManyToOneGet(){
/*        Hibernate:
            select
                order0_.ORDER_ID as ORDER_ID1_1_0_,
                order0_.ORDER_NAME as ORDER_NA2_1_0_,
                order0_.CUSTOMER_ID as CUSTOMER3_1_0_
            from
                ORDERS order0_
            where
                order0_.ORDER_ID=?
        Hibernate:
            select
                customer0_.CUSTOMER_ID as CUSTOMER1_0_0_,
                customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_
            from
                CUSTOMERS customer0_
            where
                customer0_.CUSTOMER_ID=?
        Order [orderId=1, orderName=ORDER_1, customer=Customer [customerId=5, customerName=Zhang Xueyou]]    */    

    /*    Order order = session.get(Order.class, 1);
        System.out.println(order);*/

        //1. 若查询多的一端的一个对象,则默认情况下,只查询了多的一端的对象,而没有查询关联的那一端的对象
        Order order = (Order) session.load(Order.class, 1);
        System.out.println(order.getOrderName());

        //2. 在需要使用到关联的对象时,才会发送对应的SQL 语句。
        Customer customer = order.getCustomer();
        System.out.println(customer.getCustomerName());
        System.out.println(order.getCustomer().getClass().getName());

        //3. 再查询Customer 对象时, 由多的一端导航到1的一端时候,
        // 若此时session 已被关闭, 则默认情况下,会发生懒加载异常

        //4. 获取Order 对象时, 默认情况下, 其关联的Customer 对象是一个代理对象!
    }

    /**
Hibernate:
    create table CUSTOMERS (
        CUSTOMER_ID integer not null auto_increment,
        CUSTOMER_NAME varchar(255),
        primary key (CUSTOMER_ID)
    ) ENGINE=InnoDB

Hibernate:
    create table ORDERS (        ORDER_ID integer not null auto_increment,
        ORDER_NAME varchar(255),
        CUSTOMER_ID integer,
        primary key (ORDER_ID)
    ) ENGINE=InnoDB

Hibernate:
    alter table ORDERS
        add constraint FKflgddyesjyik2ro2p501yys8r
        foreign key (CUSTOMER_ID)
        references CUSTOMERS (CUSTOMER_ID)
     */
    @Test
    public void testManyToOneSaveFirstSave1(){
//若先插入customer 再插入order, 会直接执行3条INSERT 语句
/*Hibernate:
        insert
        into
            CUSTOMERS
            (CUSTOMER_NAME)
        values
            (?)
  Hibernate:
        insert
        into
            ORDERS
            (ORDER_NAME, CUSTOMER_ID)
        values
            (?, ?)
  Hibernate:
        insert
        into
            ORDERS
            (ORDER_NAME, CUSTOMER_ID)
        values
            (?, ?)*/
        Customer customer = new Customer();
        customer.setCustomerName("Zhang Xueyou");

        Order order1 = new Order();
        order1.setOrderName("ORDER_1");
        order1.setCustomer(customer);

        Order order2 = new Order();
        order2.setOrderName("ORDER_2");
        order2.setCustomer(customer);

        session.save(customer);
        session.save(customer);
        session.save(customer);
        session.save(customer);
        session.save(order1);
        session.save(order2);
    }

    @Test
    public void testManyToOneSaveFirstSaveN(){
//若先插入order 再插入customer, 会先执行3条INSERT 语句,再执行2条UPADTE 语句, 因为在CUSTOMER执行保存以前, CUSTOMER_ID是一个空值,还没办法确定外键值。
/*Hibernate:
            insert
            into
                ORDERS
                (ORDER_NAME, CUSTOMER_ID)
            values
                (?, ?)
  Hibernate:
            insert
            into
                ORDERS
                (ORDER_NAME, CUSTOMER_ID)
            values
                (?, ?)
  Hibernate:
            insert
            into
                CUSTOMERS
                (CUSTOMER_NAME)
            values
                (?)

  Hibernate:
            update
                ORDERS
            set
                ORDER_NAME=?,
                CUSTOMER_ID=?
            where
                ORDER_ID=?
  Hibernate:
            update
                ORDERS
            set
                ORDER_NAME=?,
                CUSTOMER_ID=?
            where
                ORDER_ID=?*/
        Customer customer = new Customer();
        customer.setCustomerName("Zhang Xinzhe");

        Order order3 = new Order();
        order3.setOrderName("ORDER_3");
        order3.setCustomer(customer);

        Order order4 = new Order();
        order4.setOrderName("ORDER_4");
        order4.setCustomer(customer);

        session.save(order3);
        session.save(order4);
        session.save(customer);
    }
}
时间: 2024-10-20 02:30:09

Hibernate中的单项n 到 1说明的相关文章

(转)收集:Hibernate中常见问题 No row with the given identifier exists问题的原因及解决

Hibernate中No row with the given identifier exists问题的原因及解决 产生此问题的原因: 有两张表,table1和table2.产生此问题的原因就是table1里做了关联<one-to-one>或者<many-to-one unique="true">(特殊的多对一映射,实际就是一对一)来关联table2.当hibernate查找的时候,table2里的数据没有与table1相匹配的,这样就会报No row with

Hibernate-ORM:11.Hibernate中的关联查询

------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客将讲述Hibernate中的关联查询,及其级联(cascade)操作,以及指定哪一方维护关联关系的(inverse) 一,讲述目录如下: 1.单向一对多:(增加一个区县及其它以下的对应街道) 2.单项一对多:(查询一个区县,以及它下面所有的对应街道) 3.单项多对一:(查询一个指定的街道,并同时展示出其对应的区县) 4.双向一对多(多对一):(值得注意:toString()套路不对容易引发错误Err

Hibernate中的映射关系(一对多)

在数据库中表和表之间的关系有几种,下面就详细说一下在Hibernate中怎样映射一对多的关系 Hibernate映射一对多的关系,其实就是持久类之间的映射,那如何把持久类关联起来呢??那就用到.hbm.xml文件的<many-to-one>标签了 具体做法如下: 新建一个customer类: package com.jeremy.hibernate.app.example; public class Customer { private Integer customerId; private

hibernate中懒加载急加载的区别,get方法和load方的区别法

懒加载是hibernate中的关联关系对象的默认方式,懒加载也会先去查询对象然后获取对象的id, 当正真要对数据进行使用时才会正真写sql语句. 懒加载的有效加载期是在session打开的时候,所以在我们要使用到懒加载的时候必须要保持session的开启. 急加载就是直接用sql语句去访问数据库,但速度相对于懒加载更快. get()方法在执行时会立刻向数据库发出sql语句. load()方法和懒加载类似也是只有当真正使用该实体的属性时才会发出sql语句: 还有就是当数据库中查询不到东西时,方法会

Hibernate 中对表的操作

Hibernate CRUD testing Hibernate 中对表的操作, add,load,update,delete,list,pager(分页) package org.test.test; import java.text.SimpleDateFormat; import java.util.List; import org.hibernate.Session; import org.junit.Test; import org.zttc.itat.model.User; impo

Hibernate中,基于Annotation的简单树形结构的实现

在系统设计中,经常用到递归性质的树形结果,比如菜单.多级分类等,一般是在同一个表中定义父子关系实现这种结构. 下面是在Hibernate中,基于Annotation的简单树形结构的实现: 第一步:创建Entity类,并添加注解实现关联关系    ps: 主要是利用@ManyToOne 和 @OneToMany 配置在同一个Entity类中实现树形递归的结构.hibernate注解形式比在xml配置更加简洁 TreeNode.java 1 package com.hfut.hibernate; 2

Hibernate中Session的get和load

hibernate中Session接口提供的get()和load()方法都是用来获取一个实体对象,在使用方式和查询性能上有一些区别.测试版本:hibernate 4.2.0. get Session接口提供了4个重载的get方法,分别通过“持久类+主键”和“全类名+主键”以及“锁选项”来获取实体对象. public Object get(Class clazz, Serializable id); public Object get(Class clazz, Serializable id, L

。。。Hibernate中mappedBy属性。。。

今天在学习Hibernate中,感觉这个mappedBy这个注解属性有点小难度.不过理解之后,还是阔以的! 首先,mappedBy这个注解只能够用在@OntToOne,@OneToMany,@manyToMany中,不能够用在@manyToOne中: 第二,这个注解看网上的意思可以简单地理解为:这个注解用在主表的一方,就是被引用的一方: 第三,这个注解是与@JoinColumn这个注解是互斥的,因为@JoinColumn这个注解使用在拥有外键的表的一方,就是从表的一方. 第四,这个注解的属性值是

关于hibernate中对象的三种状态分析

一,首先hibernate中对象的状态有三种:瞬态.游离态和持久态,三种状态转化的方法都是通过session来调用,瞬态到持久态的方法有save().saveOrUpdate().get().load():持久态到瞬态的方法有delete():游离态到持久态的方法有update().saveOrUpdate().lock():持久态到游离态的方法有:session.close().session.evict().session.clear(). 二,Hibernate的状态 hibernate的