?代理对象是不是只可以获取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()); } }