这种方式,不再针对父类Container有专门的数据表和映射文件,hibernate隐性的通过 Container与两个子类的继承关系实现这一效果
数据库结构:
CREATE TABLE `box2` ( `id` varchar ( 50 ) NOT NULL default ' 0 ' , `size` double default NULL , `name` varchar ( 50 ) default NULL , `description` varchar ( 50 ) default NULL , `width` double default NULL , `height` double default NULL , ` len ` double default NULL , PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = gb2312; CREATE TABLE `bottle2` ( `id` varchar ( 50 ) NOT NULL default ' 0 ' , `size` double default NULL , `name` varchar ( 20 ) default NULL , `diameter` double default NULL , `height` double default NULL , `description` varchar ( 50 ) default NULL , PRIMARY KEY (`id`) ) ENGINE = InnoDB DEFAULT CHARSET = gb2312;
实体关系:
package extendstesttwo; public class Bottle extends Container ... { private double diameter; private double height; public double getDiameter() ... { return diameter; } public void setDiameter( double diameter) ... { this .diameter = diameter; } public double getHeight() ... { return height; } public void setHeight( double height) ... { this .height = height; } }package extendstesttwo; public class Box extends Container ... { private double height; private double length; private double width; public double getHeight() ... { return height; } public void setHeight( double height) ... { this .height = height; } public double getLength() ... { return length; } public void setLength( double length) ... { this .length = length; } public double getWidth() ... { return width; } public void setWidth( double width) ... { this .width = width; } }package extendstesttwo; // hibernate多态支持的策略,每个子类一张表 public abstract class Container ... { private String containerId; private double size; private String name; private String description; public String getContainerId() ... { return containerId; } public void setContainerId(String containerId) ... { this .containerId = containerId; } public String getDescription() ... { return description; } public void setDescription(String description) ... { this .description = description; } public String getName() ... { return name; } public void setName(String name) ... { this .name = name; } public double getSize() ... { return size; } public void setSize( double size) ... { this .size = size; } }
映射文件:
<? xml version="1.0" encoding="utf-8" ?> <! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> < hibernate-mapping package ="extendstesttwo" > < class name ="Bottle" table ="bottle2" > < id name ="containerId" column ="id" > < generator class ="uuid.hex" ></ generator > </ id > < property name ="size" column ="size" ></ property > < property name ="name" column ="name" ></ property > < property name ="description" column ="description" ></ property > < property name ="height" column ="height" ></ property > < property name ="diameter" column ="diameter" ></ property > </ class > </ hibernate-mapping >
<? xml version="1.0" encoding="utf-8" ?> <! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" > <!-- Mapping file autogenerated by MyEclipse - Hibernate Tools --> < hibernate-mapping package ="extendstesttwo" > < class name ="Box" table ="box2" > < id name ="containerId" column ="id" > < generator class ="uuid.hex" ></ generator > </ id > < property name ="size" column ="size" ></ property > < property name ="name" column ="name" ></ property > < property name ="description" column ="description" ></ property > < property name ="height" column ="height" ></ property > < property name ="width" column ="width" ></ property > < property name ="length" column ="len" ></ property > </ class > </ hibernate-mapping >
测试代码:
需要注意的是,由于没有Container的映射关系,此处需要用完成的包名
"from extendstesttwo.Container"
public static void main(String[] args) ... { Configuration cfg = new Configuration(); cfg.configure(); SessionFactory sf = cfg.buildSessionFactory(); Session session = sf.openSession(); Transaction t = session.beginTransaction(); Box box1 = new Box(); box1.setName( " 木箱子 " ); box1.setHeight( 50 ); box1.setLength( 50 ); box1.setWidth( 50 ); box1.setDescription( " 包装电视机 " ); box1.setSize( 12500 ); Bottle bottle1 = new Bottle(); bottle1.setName( " 玻璃瓶子 " ); bottle1.setDescription( " 喝牛奶用 " ); bottle1.setSize( 139.12 ); bottle1.setDiameter( 6 ); bottle1.setHeight( 12 ); session.save(box1); session.save(bottle1); // 取全部Box Query query1 = session.createQuery( " from Box " ); for (Iterator iter = query1.list().iterator();iter.hasNext();) ... { System.out.println(((Container)iter.next()).getName()); } // 取全部Bottle Query query2 = session.createQuery( " from Bottle " ); for (Iterator iter = query2.list().iterator();iter.hasNext();) ... { System.out.println(((Container)iter.next()).getName()); } // 取全部container Query query3 = session.createQuery( " from extendstesttwo.Container " ); for (Iterator iter = query3.list().iterator();iter.hasNext();) ... { System.out.println(((Container)iter.next()).getName()); } t.commit(); System.out.println(" success " ); }
运行结果: 木箱子 Hibernate: select bottle0_.id as id0_, bottle0_.size as size0_, bottle0_.name as name0_, bottle0_.description as descript4_0_, bottle0_.height as height0_, bottle0_.diameter as diameter0_ from bottle2 bottle0_ 玻璃瓶子 Hibernate: select box0_.id as id1_, box0_.size as size1_, box0_.name as name1_, box0_.description as descript4_1_, box0_.height as height1_, box0_.width as width1_, box0_.len as len1_ from box2 box0_ Hibernate: select bottle0_.id as id0_, bottle0_.size as size0_, bottle0_.name as name0_, bottle0_.description as descript4_0_, bottle0_.height as height0_, bottle0_.diameter as diameter0_ from bottle2 bottle0_ 木箱子 玻璃瓶子 success
可以看到,这样也可以实现继承的查询
总结:目前继承查询有了三种方法了:<subselect>标签加上这两种继承(每个子类一个表,每个类一个表)策略(三种方式在我的blog的经验技巧之hibernate中都有相关文章,本文是第二种策略)