Hibernate映射

?代理对象是不是只可以获取id,而不能修改id

实验结果是:代理对象可以正常获取其id值,但一旦setId,不管会不会成功都会查询其所在的表,即进行加载

但若只是set代理对象则不需要查询其表

 

在页面上使用<s:debug></s:debug>会产生莫名的错误,

如在对用户进行修改时明明没有使用到用户的commentSet属性,但还是报了它的懒加载异常。

 

/*
* 1. 声明集合类型时, 需使用接口类型, 因为 hibernate 在获取
* 集合类型时, 返回的是 Hibernate 内置的集合类型, 而不是 JavaSE 一个标准的
* 集合实现.
* 2. 需要把集合进行初始化, 可以防止发生空指针异常
*/
private Set<Order> orders = new HashSet<>();

 

单项n21

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 2017-2-19 13:51:15 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_danxiang_n21">
    <class name="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 2017-2-19 13:51:15 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_danxiang_n21">
    <class name="Order" table="ORDERS">
        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        <property name="orderDesc">
            <column name="ORDER_DESC" sql-type="mediumtext" />
        </property>
        <!-- name:为Order中表示与	一的一端Customer类的	    联系的属性名
        	 class:为一的一端的全类名
        	 column:为ORDERS表中的外键的字段名 -->
        <many-to-one name="customer" class="Customer">
            <column name="CUSTOMER_ID" />
        </many-to-one>
    </class>
</hibernate-mapping>

Test.java

package model_danxiang_n21;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
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 before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
				.applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	@After
	public void after(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testMany2OneSave() {
		Customer customer = new Customer();
		customer.setCustomerName("Ji");
		
		Order order1 = new Order("AA", customer);
		Order order2 = new Order("BB", customer);
		
		//这种顺序三条insert
//		session.save(customer);
//		session.save(order1);
//		session.save(order2);
		
		//这种顺序显示三条insert再是一条update
		session.save(order1);
		session.save(customer);
		session.save(order2);
	}
	@Test
	public void testMany2OneGet() {
		Order order = (Order) session.get(Order.class, 3);//这是仅仅查询了Order
		System.out.println(order.getOrderDesc());
		//直到执行过下面这行代码,才会打印select customer 的sql语句。此为延时加载。若此时session被close则会出懒加载异常
		System.out.println(order.getCustomer().getCustomerName());
	}
	@Test
	public void testMany2OneUpdate(){
		Order order = (Order) session.get(Order.class, 1);
		order.getCustomer().setCustomerName("Fei");
	}
	@Test
	public void testMany2OneDelete(){
		Order order = new Order();
		order.setOrderId(2);
		session.delete(order);
		Customer customer = new Customer();
		customer.setCustomerId(1);
		session.delete(customer);
		//customer是orders中的外键,所以当orders表中有order与此customer关联,则删除customer会报异常;若无则可删除
	}

}

  

单项n2n

He.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 2017-2-21 17:15:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="model_danxiang_n2n.He" table="HES">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <set name="set" table="HE_YU" inverse="false" lazy="true">
            <key>
                <column name="H_ID" />
            </key>
            <many-to-many column="Y_ID" class="model_danxiang_n2n.Yu"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

Yu.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 2017-2-21 17:15:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="model_danxiang_n2n.Yu" table="YUS">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
    </class>
</hibernate-mapping>

  Test.java

package model_danxiang_n2n;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class Test_danxiang_n2n {
	
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	@After
	public void after(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testSave() {
		Yu yu1 = new Yu();
		Yu yu2 = new Yu();
		
		He he1 = new He();
		He he2 = new He();
		
		yu1.setName("yun1");
		yu2.setName("yun2");
		
		he1.setName("ji1");
		he2.setName("ji2");
		
		he1.getSet().add(yu1);
		he1.getSet().add(yu2);
		he2.getSet().add(yu1);
		
		session.save(he1);
		session.save(he2);
		
		session.save(yu1);
		session.save(yu2);
	
		//无update,只有7条insert
	}
	@Test
	public void testGet(){
		He he = (He) session.get(He.class, 1);
		System.out.println(he.getName());
		
		System.out.println(he.getSet().size());
	}

}

双向n21

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 2017-2-19 16:01:24 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_shuangxiang_n21">
    <class name="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>
        
        <!-- set为1方中记录多方的属性名
        	 inverse:为true时就不用update,因为此时customer是被动方,无需主动添加关联
					   若不设置则1方和n方都为主动方就都需要添加关联
			 table:为n的一方在数据库中存的表
			 column:为n方表中的1方的外键字段名
			 one-to-many class:中写n方的全类名
		 -->
		 <!-- (不建议使用,建议使用手工的方式)
		 	cascade:不写时,此时级联删除会报异常;若想清空set,则数据库不会有变化;
		 				         若只save 1的一方,则与之相关联的n的对象不会被保存
		 			delete,此时删除它本身和与它关联的多方的多个对象
		 			delete-orphan,若想清空set,则set中的n方对象在数据库中被删除
		 			save-update,若只save 1的一方,则与之相关联的n的对象会被保存
		  -->
		  <!-- order-by="ORDER_ID DESC"		查询set中元素时按id降序排 -->
        <set name="set" table="ORDERS" inverse="true" cascade="save-update" order-by="ORDER_ID DESC" >
            <key>
                <column name="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">
<!-- Generated 2017-2-19 16:01:24 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_shuangxiang_n21">
    <class name="Order" table="ORDERS">
        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        <property name="orderDesc" type="text">
            <column name="ORDER_DESC" />
        </property>
        <!-- name:为1方的属性名 -->
        <many-to-one name="customer" class="Customer">
            <column name="CUSTOMER_ID" />
        </many-to-one>
    </class>
</hibernate-mapping>

  Test.java

package model_shuangxiang_n21;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
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 before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
				.applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	@After
	public void after(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testMany2OneSave() {
		Customer customer = new Customer();
		customer.setCustomerName("Ji");
		
		Order order1 = new Order("AA", customer);
		Order order2 = new Order("BB", customer);
		
		customer.getSet().add(order1);
		customer.getSet().add(order2);
		
		//这种顺序三条insert,默认是两条update,因为此时customer也要添加关联,
		//当set标签的属性inverse为true时就不用update,因为此时customer是被动方,无需主动添加关联
		//若不设置则1方和n方都为主动方就都需要添加关联
		session.save(customer);
		session.save(order1);
		session.save(order2);
		
		//这种顺序显示三条insert,默认是3条update
//		session.save(order1);
//		session.save(customer);
//		session.save(order2);
	}
	@Test
	public void testMany2OneGet() {
		Customer customer = (Customer) session.get(Customer.class, 1);//懒加载set
		System.out.println(customer.getSet().getClass());//class org.hibernate.collection.internal.PersistentSet
	}
	@Test
	public void testMany2OneUpdate(){
		Order order = (Order) session.get(Order.class, 1);
		order.getCustomer().setCustomerName("Fei");
	}
	@Test
	public void testMany2OneDelete(){
		Order order = new Order();
		order.setOrderId(2);
		session.delete(order);
		Customer customer = new Customer();
		customer.setCustomerId(1);
		session.delete(customer);
		//customer是orders中的外键,所以当orders表中有order与此customer关联,则删除customer会报异常;若无则可删除
	}
	@Test
	public void testSetCascade(){
		Customer customer = (Customer) session.get(Customer.class, 3);
//		session.delete(customer);
		
		Order order = (Order) session.get(Order.class, 4);
//		session.delete(order);
		
		order.setCustomer(customer);
		
//		customer.getSet().clear();
	}
	@Test
	public void testSetCascade2(){
		Customer customer = new Customer();
		customer.setCustomerName("Fei");
		
		Order order1 = new Order("CC", customer);
		Order order2 = new Order("DD", customer);
		
		customer.getSet().add(order1);
		customer.getSet().add(order2);
		
		session.save(customer);
	}
	
}

  

双向n2n

  双向多对多,若想使中间表中多出一行,可以自定义一个中间表的类(implements Serializable),其中包含了两个多方表的主键,并且在hbm文件中将这两个外键联合声明成一个主键

<composite-id>
        <key-property name="student_id" column="student_id" type="int"></key-property>
        <key-property name="course_id" column="course_id" type="int"></key-property>
</composite-id>

 

He.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 2017-2-21 17:15:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="model_shuangxiang_n2n.He" table="HES">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        
        <set name="set" table="HE_YU">
            <key>
                <column name="H_ID" />
            </key>
            <many-to-many column="Y_ID" class="model_shuangxiang_n2n.Yu"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

  Yu.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 2017-2-21 17:15:59 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="model_shuangxiang_n2n.Yu" table="YUS">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        <!-- 重点inverse必须有一个 -->
        <!-- table:为额外增加的一个联系表的名字 -->
        <!-- key中列名是本表的主键在额外表中对应的外键列名 -->
        <!-- many-to-many中列名为对应的对象的主键在额外表中对应的外键列名 -->
        <set name="set" table="HE_YU" inverse="true">
        	<key>
        		<column name="Y_ID"></column>
        	</key>
        	<many-to-many column="H_ID" class="model_shuangxiang_n2n.He"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

  Test.java

package model_shuangxiang_n2n;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class Test_shuangxiang_n2n {
	
	private SessionFactory sessionFactory;
	private Session session;
	private Transaction transaction;
	
	@Before
	public void before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	@After
	public void after(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void testSave() {
		Yu yu1 = new Yu();
		Yu yu2 = new Yu();
		
		He he1 = new He();
		He he2 = new He();
		
		yu1.setName("yun1");
		yu2.setName("yun2");
		
		he1.setName("ji1");
		he2.setName("ji2");
		
		he1.getSet().add(yu1);
		he1.getSet().add(yu2);
		he2.getSet().add(yu1);
		
		yu1.getSet().add(he1);
		yu1.getSet().add(he2);
		yu2.getSet().add(he1);
		
		session.save(he1);
		session.save(he2);
		
		session.save(yu1);
		session.save(yu2);
	
		//无update,只有7条insert
	}
	@Test
	public void testGet(){
		He he = (He) session.get(He.class, 5);
		System.out.println(he.getName());
		
		System.out.println(he.getSet().size());
	}
	
	@Test
	public void testGet2(){
		Yu yu = (Yu) session.get(Yu.class, 6);
		
		System.out.println(yu.getSet().size());
	}
	
}

  

双向121

外键方式

Nan.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 2017-2-20 19:40:30 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_shuangxiang_waijian_121">
	<class name="Nan" table="NANS">
		<id name="nanId" type="java.lang.Integer">
			<column name="NAN_ID" />
			<generator class="native" />
		</id>
		<property name="nanName" type="java.lang.String">
			<column name="NAN_NAME" />
		</property>
		
		<!-- 要实现基于外键的121,就至少要有一方中含有外键,并且把外键的一列设置为唯一即可-->
		<!-- name:外键对应的属性的名-->
		<!-- column:外键列的列名-->
		<!-- unique:将外键列设置为唯一,,因为要实现的是121-->
		<many-to-one name="XiHuan" column="XI_HUAN" unique="true"></many-to-one>
		
	</class>
</hibernate-mapping>

  Nv.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 2017-2-20 19:40:30 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_shuangxiang_waijian_121">
    <class name="Nv" table="NVS">
        <id name="nvId" type="java.lang.Integer">
            <column name="NV_ID" />
            <generator class="native" />
        </id>
        <property name="nvName" type="java.lang.String">
            <column name="NV_NAME" />
        </property>
        
        <!-- name:关联的对象在本类中的属性的名-->
		<!-- class:关联对象的全类名-->
		<!-- property:这是外键关联方式在实现121时必须设置的,值为  关联对象中记录本对象的属性名(若不写在get时会出错)-->
		<!-- 若只写<one-to-one>而不写用外键的方式生成主键,则单在NVS中看不到关联的另一端1,
			 加上property-ref="XiHuan"则在做外链接love所存的表时
			  left outer join
			        NANS nan1_ 
			            on nv0_.NV_ID=nan1_.XI_HUAN
			 -->
        <one-to-one name="love" class="Nan" property-ref="XiHuan"></one-to-one>
    </class>
</hibernate-mapping>

  Test.java

package model_shuangxiang_waijian_121;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
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 before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
				.applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	@After
	public void after(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void test121Save(){
		Nan nan = new Nan();
		nan.setNanName("AA");
		Nv nv = new Nv();
		nv.setNvName("BB");
		
		//1的一方可以不set,但“多”的一方(即对应表中含有外键的一方)必须set
		nan.setXiHuan(nv);
//		nv.setLove(nan);
		
		session.save(nv);
		session.save(nan);
	}
	@Test
	public void test121Get(){
//		Nan nan = (Nan) session.get(Nan.class, 3);
//		System.out.println(nan.getNanName());
//		System.out.println(nan.getXiHuan().getNvName());
		
		Nv nv = (Nv) session.get(Nv.class, 3);
		System.out.println(nv.getLove().getNanName());
	}
}

主键方式

Nan.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 2017-2-20 19:40:30 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_shuangxiang_zhujian_121">
	<class name="Nan" table="NANS">
		<id name="nanId" type="java.lang.Integer">
			<column name="NAN_ID" />
			<!-- 使用外键的方式生成主键 -->
			<generator class="foreign">
				<!-- property 指定用哪一个属性的主键作为自己的外键 -->
				<param name="property">XiHuan</param>
			</generator>
		</id>
		<property name="nanName" type="java.lang.String">
			<column name="NAN_NAME" />
		</property>
		
		<!-- 这个one-to-one中要带有constrained=true 表示在此表中生成外键约束-->
		<one-to-one name="XiHuan" class="Nv" constrained="true"></one-to-one>
		
	</class>
</hibernate-mapping>

  Nv.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 2017-2-20 19:40:30 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_shuangxiang_zhujian_121">
    <class name="Nv" table="NVS">
        <id name="nvId" type="java.lang.Integer">
            <column name="NV_ID" />
            <generator class="native" />
        </id>
        <property name="nvName" type="java.lang.String">
            <column name="NV_NAME" />
        </property>
        
        <one-to-one name="love" class="Nan"></one-to-one>
    </class>
</hibernate-mapping>

  Test.java

package model_shuangxiang_zhujian_121;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
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 before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
				.applySettings(configuration.getProperties()).buildServiceRegistry();
		sessionFactory = configuration.buildSessionFactory(serviceRegistry);
		session = sessionFactory.openSession();
		transaction = session.beginTransaction();
	}
	@After
	public void after(){
		transaction.commit();
		session.close();
		sessionFactory.close();
	}
	
	@Test
	public void test121Save(){
		Nan nan = new Nan();
		nan.setNanName("Ji");
		Nv nv = new Nv();
		nv.setNvName("Yun");
		
		//主键生成方式是参照关联对象的一方必须set,但另一方可以不set
		nan.setXiHuan(nv);
//		nv.setLove(nan);
		
		//此时无论顺序都是先插女再插男,且不会有多余的update
		session.save(nan);
		session.save(nv);
	}
	@Test
	public void test121Get(){
		//两个select
//		Nan nan = (Nan) session.get(Nan.class, 2);
//		System.out.println(nan.getNanName());
//		System.out.println(nan.getXiHuan().getNvName());
		//一个select
		/*
		 * Hibernate: 
		    select
		        nv0_.NV_ID as NV_ID1_1_1_,
		        nv0_.NV_NAME as NV_NAME2_1_1_,
		        nan1_.NAN_ID as NAN_ID1_0_0_,
		        nan1_.NAN_NAME as NAN_NAME2_0_0_ 
		    from
		        NVS nv0_ 
		    left outer join
		        NANS nan1_ 
		            on nv0_.NV_ID=nan1_.NAN_ID 
		    where
		        nv0_.NV_ID=?
		 * */
		Nv nv = (Nv) session.get(Nv.class, 2);
		System.out.println(nv.getLove().getNanName());
	}
}

继承映射

subclass方式

Person.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 2017-2-24 19:56:10 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="model_extends.Person" table="PERSONS" discriminator-value="PERSON">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        
        <discriminator column="TYPE" type="string"></discriminator>
        
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        <subclass name="model_extends.Student" discriminator-value="STUDENT" >
        	<property name="grade" type="string" column="GRADE"></property>
        </subclass>
        
    </class>
</hibernate-mapping>

  Test.java

package model_extends;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import model_extends_join.Person;

public class TestExtends {
	
	private SessionFactory factory = null;
	private Session session = null;
	private Transaction transaction = null;
	
	@Before
	public void before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry registry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
																.buildServiceRegistry();
		factory = configuration.buildSessionFactory(registry);
		session = factory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void after(){
		transaction.commit();
		session.close();
		factory.close();
	}
	/**
	 * 只生成一张表。会用一列type的标识列,
	 * 
	 * 关键:子类独有的属性在表中不能设置非null约束
	 * 
	 * */
	@Test
	public void testSave() {
//		Person p =new Person();
//		p.setName("jiyunfei");
//		
//		session.save(p);
		
		Student s = new Student();
		s.setGrade("Wu");
		
		session.save(s);
	}
	
	@Test
	public void testGet() {
		Student s = (Student) session.get(Student.class, 2);
		System.out.println(s.getGrade());
		s.setName("AA");
		
		Person p = (Person) session.get(Person.class, 2);
		
		System.out.println(p.getName());
	}

}

joined-subclass方式

Person.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 2017-2-26 9:14:01 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_extends_join">
    <class name="Person" table="PERSONS">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
        <joined-subclass name="Student" table="STUDENTS">
        	<key column="ID"></key>
        	<property name="grade" type="string" column="GRADE"></property>
        </joined-subclass>
        
    </class>
</hibernate-mapping>

  Test.java

package model_extends_join;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import model_extends_join.Person;

public class TestExtends {
	
	private SessionFactory factory = null;
	private Session session = null;
	private Transaction transaction = null;
	
	@Before
	public void before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry registry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
																.buildServiceRegistry();
		factory = configuration.buildSessionFactory(registry);
		session = factory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void after(){
		transaction.commit();
		session.close();
		factory.close();
	}
	/**
	 * join方式的继承映射是生成两张表,Students表中有一个主键id是Persons表的外键
	 * 
	 * 只有一个冗余项就是Students中的主键
	 * */
	@Test
	public void testSave() {
//		Person p =new Person();
//		p.setName("jiyunfei");
//		
//		session.save(p);
		
		Student s = new Student();
		s.setGrade("Wu");
		
		session.save(s);
	}
	/**
	 * 若查询的是Student,则用内连接只查询
	 * 
	 * 若查询的是Person,则用的左外链接查询
	 * */
	@Test
	public void testGet() {
//		Student s = (Student) session.get(Student.class, 2);
//		System.out.println(s.getGrade());
//		s.setName("AA");
		
		Person p = (Person) session.get(Person.class, 2);
		
		System.out.println(p.getName());
		System.out.println(((Student)p).getGrade());
	}

}

  union-subclass方式

Person.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 2017-2-26 9:14:01 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping package="model_extends_union">
    <class name="Person" table="PERSONS">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="hilo" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
       <union-subclass name="Student" table="STUDENTS">
       		<property name="grade" column="GRADE" type="string"></property>
       </union-subclass>
        
    </class>
</hibernate-mapping>

  Test.java

package model_extends_union;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


public class TestExtends {
	
	private SessionFactory factory = null;
	private Session session = null;
	private Transaction transaction = null;
	
	@Before
	public void before(){
		Configuration configuration = new Configuration().configure();
		ServiceRegistry registry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
																.buildServiceRegistry();
		factory = configuration.buildSessionFactory(registry);
		session = factory.openSession();
		transaction = session.beginTransaction();
	}
	
	@After
	public void after(){
		transaction.commit();
		session.close();
		factory.close();
	}
	/**
	 * union方式的继承映射时生成两个独立的没有外键链接的表,会有冗余字段
	 * */
	@Test
	public void testSave() {
//		Person p =new Person();
//		p.setName("jiyunfei");
//		
//		session.save(p);
		
		Student s = new Student();
		s.setGrade("Wu");
		s.setName("QQ");
		session.save(s);
	}
	/**
	 * 若查询的是Student,则只从Students表查询
	 * 
	 * 若查询的是Person,则用的是联合查询
	 * */
	@Test
	public void testGet() {
		Student s = (Student) session.get(Student.class, 32768);
		System.out.println(s.getGrade());
//		s.setName("AA");
		
//		Person p = (Person) session.get(Person.class, 32768);
//		
//		System.out.println(p.getName());
//		System.out.println(((Student)p).getGrade());
	}

}

  

posted @ 2017-02-26 20:24  逢甘霖成大事  阅读(121)  评论(0编辑  收藏  举报