读书人

Hibernate承袭映射一:每个类分层结构一

发布时间: 2012-10-10 13:58:11 作者: rapoo

Hibernate继承映射一:每个类分层结构一张表

本示例演示Hibernate继承映射的第一种策略:每棵类继承树对应一张表1、理解如何映射因为类继承树肯定是对应多个类,要把多个类的信息存放在一张表中,必须有某种机制来区分哪些记录是属于哪个类的。这种机制就是,在表中添加一个字段,用这个字段的值来进行区分。用hibernate实现这种策略的时候,有如下步骤:父类用普通的<class>标签定义在父类中定义一个discriminator,即指定这个区分的字段的名称和类型如:<discriminator column=”XXX” type=”string”/>子类使用<subclass>标签定义,在定义subclass的时候,需要注意如下几点:Subclass标签的name属性是子类的全路径名在Subclass标签中,用discriminator-value属性来标明本子类的discriminator字段(用来区分不同类的字段)的值Subclass标签,既可以被class标签所包含(这种包含关系正是表明了类之间的继承关系),也可以与class标签平行。 当subclass标签的定义与class标签平行的时候,需要在subclass标签中,添加extends属性,里面的值是父类的全路径名称。子类的其它属性,像普通类一样,定义在subclass标签的内部。2、理解如何存储在存储数据的时候,hibernate会自动将鉴别字段的值插入到数据库中,在加载数据的时候,hibernate便能根据这个鉴别字段正确的加载对象3、理解何为多态查询,即hibernate能够加载数据的时候自动鉴别其真正的类型多态get(),支持多态load(),设置Lazy=“false”时,支持多态查询,支持 

?

?

配置如下:

测试的话先在mysql下创建数据库hibernate.再配置好下列文件放在src根目录

hibernate.cfg.xml

<!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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">sys833199</property><property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property><property name="show_sql">True</property><property name="format_sql">True</property><property name="use_sql_comments">True</property><mapping resource="com/lwf/hibernate/extend1/ext1.hbm.xml"/></session-factory></hibernate-configuration>

?

log4j.properties

### direct log messages to stdout ###log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.Target=System.outlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### direct messages to file hibernate.log ####log4j.appender.file=org.apache.log4j.FileAppender#log4j.appender.file.File=hibernate.log#log4j.appender.file.layout=org.apache.log4j.PatternLayout#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n### set log levels - for more verbose logging change 'info' to 'debug' ###log4j.rootLogger=warn, stdout#log4j.logger.org.hibernate=info#log4j.logger.org.hibernate=debug### log HQL query parser activity#log4j.logger.org.hibernate.hql.ast.AST=debug### log just the SQL#log4j.logger.org.hibernate.SQL=debug### log JDBC bind parameters ###log4j.logger.org.hibernate.type=info#log4j.logger.org.hibernate.type=debug### log schema export/update ###log4j.logger.org.hibernate.tool.hbm2ddl=debug### log HQL parse trees#log4j.logger.org.hibernate.hql=debug### log cache activity ####log4j.logger.org.hibernate.cache=debug### log transaction activity#log4j.logger.org.hibernate.transaction=debug### log JDBC resource acquisition#log4j.logger.org.hibernate.jdbc=debug### enable the following line if you want to track down connection ###### leakages when using DriverManagerConnectionProvider ####log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

?

?

ext1.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="com.lwf.hibernate.extend1"><class name="Animal" table="t_animal"><id name="id"><generator type="string"/><property name="name"/><property name="sex"/><subclass name="Bird" discriminator-value="bird"><property name="height"/></subclass><subclass name="Pig" discriminator-value="pig"><property name="weight"/></subclass></class></hibernate-mapping>

?

Animal类

package com.lwf.hibernate.extend1;public class Animal {private int id;private String name;private boolean sex;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public boolean isSex() {return sex;}public void setSex(boolean sex) {this.sex = sex;}}

?

package com.lwf.hibernate.extend1;public class Bird extends Animal {private int height;public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}}

?

package com.lwf.hibernate.extend1;public class Pig extends Animal {private int weight;public int getWeight() {return weight;}public void setWeight(int weight) {this.weight = weight;}}

?

?

上面文件建立好后,使用ExportDB类创建表.

package com.lwf.hibernate.util;import org.hibernate.cfg.Configuration;import org.hibernate.tool.hbm2ddl.SchemaExport;public class ExportDB {public static void main(String[] args) {//读取配置文件Configuration cfg = new Configuration().configure();//创建SchemaExport对象SchemaExport export = new SchemaExport(cfg);//创建数据库表export.create(true,true);}}

?

?

建立工具类:

package com.lwf.hibernate.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class HibernateUtils {private static SessionFactory factory;private HibernateUtils() {}static {Configuration cfg = new Configuration().configure();factory = cfg.buildSessionFactory();}public static SessionFactory getSessionFactory() {return factory;}public static Session getSession() {return factory.openSession();}public static void closeSession(Session session) {if (session != null) {if (session.isOpen()) {session.close();}}}}

?

?

以下是我的测试类:

package com.lwf.hibernate.test;import java.util.Iterator;import java.util.List;import org.hibernate.Session;import com.lwf.hibernate.extend1.Animal;import com.lwf.hibernate.extend1.Bird;import com.lwf.hibernate.extend1.Pig;import com.lwf.hibernate.util.HibernateUtils;public class Ext1Test  {public static void main(String[] args) {//testSaveAnimal();//testLoad1();//testLoad2();testLoad3();testLoad4();//testLoad5();//testLoad6();}/** * 保存数据 * */public static void testSaveAnimal() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Pig p = new Pig();p.setName("猪1");p.setSex(true);p.setWeight(400);Bird b = new Bird();b.setName("孔雀");b.setSex(true);b.setHeight(100);session.save(p);session.save(b);session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(session);}}/** * 通过Pig类来装载 * */public static  void testLoad1() {Session session = null;try {session = HibernateUtils.getSession();Pig p = (Pig)session.load(Pig.class, 1);System.out.println("name=" + p.getName());}catch(Exception e) {e.printStackTrace();}finally {HibernateUtils.closeSession(session);}}/** * 通过Animal类来装载 * */public static  void testLoad2() {Session session = null;try {session = HibernateUtils.getSession();Animal a = (Animal)session.load(Animal.class, 1);System.out.println("name=" + a.getName());}catch(Exception e) {e.printStackTrace();}finally {HibernateUtils.closeSession(session);}}public static void  testLoad3() {Session session = null;try {session = HibernateUtils.getSession();Animal a = (Animal)session.load(Animal.class, 1);//因为我们load默认是Lazy,因为Lazy所以我们看到的是Animal的代理类//所以通过instance是具体反映不出真正的对象类型的if (a instanceof Pig) {System.out.println("name=" + a.getName());}else {System.out.println("不是猪!");}}catch(Exception e) {e.printStackTrace();}finally {HibernateUtils.closeSession(session);}}public static  void testLoad4() {Session session = null;try {session = HibernateUtils.getSession();Animal a = (Animal)session.get(Animal.class, 1);//可以正确判断,因为Animal不是代理类if (a instanceof Pig) {System.out.println("name=" + a.getName());}else {System.out.println("不是猪!");}}catch(Exception e) {e.printStackTrace();}finally {HibernateUtils.closeSession(session);}}/** * 将Animal的lazy设置为false * */public static void testLoad5() {Session session = null;try {session = HibernateUtils.getSession();Animal a = (Animal)session.load(Animal.class, 1);if (a instanceof Pig) {System.out.println("name=" + a.getName());}else {System.out.println("不是猪!");}}catch(Exception e) {e.printStackTrace();}finally {HibernateUtils.closeSession(session);}}public static  void testLoad6() {Session session = null;try {session = HibernateUtils.getSession();/** * 多态查询 */List animalList = session.createQuery("from com.lwf.hibernate.extend1.Animal").list();for (Iterator iter = animalList.iterator(); iter.hasNext(); ) {Animal a = (Animal)iter.next();System.out.println("name=" + a.getName());}}catch(Exception e) {e.printStackTrace();}finally {HibernateUtils.closeSession(session);}}}

?

要通过对每一个测试方法的运行才能将最开始的描述有更深的认识.

上面测试类中testLoad3与testLoad4比较得知:? 多态get(),支持

testLoad3与testLoad5比较得知:多态load(),设置Lazy=“false”时,支持

读书人网 >软件架构设计

热点推荐