2.1.4 使用subselect添加查询语句
在声明了Box和Bottle之后,利用subselect来实现Container。映射文件如下
<?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.weportal.subselect">
<class name="Box" table="Box">
<id name="id">
<generator class="hilo"/>
</id>
<property name="size" column="size"/>
<property name="name" column="name"/>
<property name="description" column="description"/>
<property name="width" column="width"/>
<property name="length" column="length"/>
<property name="height" column="height"/>
</class>
<class name="Bottle" table="Bottle">
<id name="id">
<generator class="hilo"/>
</id>
<property name="size" column="size"/>
<property name="name" column="name"/>
<property name="description" column="description"/>
<property name="diameter" column="diameter"/>
<property name="height" column="height"/>
</class>
<class name="Container" mutable="false" subselect="
select id, size, name, description, diameter as xparam, diameter as yparam, height as zparam from Bottle
union
select id, size, name, description, width as xparam, length as yparam, height as zparam from Box
">
<synchronize table="Bottle"/>
<synchronize table="Box"/>
<id name="id" unsaved-value="0">
<generator class="native"/>
</id>
<property name="size" column="size"/>
<property name="name" column="name"/>
<property name="description" column="description"/>
<property name="xparam" column="xparam"/>
<property name="yparam" column="yparam"/>
<property name="zparam" column="zparam"/>
</class>
</hibernate-mapping>
Container类实现如下,注意不是抽象类了。
package com.weportal.subselect;
public class Container ...{
private long id;
private double size;
private String name;
private String description;
private double xparam;
private double yparam;
private double zparam;
/** *//**
* @return Returns the description.
*/
public String getDescription() ...{
return description;
}
/** *//**
* @param description The description to set.
*/
public void setDescription(String description) ...{
this.description = description;
}
/** *//**
* @return Returns the name.
*/
public String getName() ...{
return name;
}
/** *//**
* @param name The name to set.
*/
public void setName(String name) ...{
this.name = name;
}
/** *//**
* @return Returns the size.
*/
public double getSize() ...{
return size;
}
/** *//**
* @param size The size to set.
*/
public void setSize(double size) ...{
this.size = size;
}
/** *//**
* @return Returns the containerId.
*/
public long getId() ...{
return id;
}
/** *//**
* @param containerId The containerId to set.
*/
public void setId(long containerId) ...{
this.id = containerId;
}
/** *//**
* @return Returns the xparam.
*/
public double getXparam() ...{
return xparam;
}
/** *//**
* @param xparam The xparam to set.
*/
public void setXparam(double xparam) ...{
this.xparam = xparam;
}
/** *//**
* @return Returns the yparam.
*/
public double getYparam() ...{
return yparam;
}
/** *//**
* @param yparam The yparam to set.
*/
public void setYparam(double yparam) ...{
this.yparam = yparam;
}
/** *//**
* @return Returns the zparam.
*/
public double getZparam() ...{
return zparam;
}
/** *//**
* @param zparam The zparam to set.
*/
public void setZparam(double zparam) ...{
this.zparam = zparam;
}
}
执行测试的程序如下:
package com.weportal.subselect;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.PropertyConfigurator;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class ContainerViewTest ...{
public static void main(String[] args) ...{
PropertyConfigurator.configure("log4j.Properties");
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sf = cfg.buildSessionFactory();
Session sess = sf.openSession();
Transaction t = sess.beginTransaction();
List pcs = sess.createQuery("from Container").list();
if(pcs.isEmpty())System.out.println("没数据");
for(Iterator it = pcs.iterator();it.hasNext();)...{
Container cter = (Container) it.next();
System.out.println(cter.getClass().getName());
System.out.println("id : "+cter.getId());
System.out.println("name : "+cter.getName());
System.out.println("size : "+cter.getSize());
System.out.println("xparam : "+cter.getXparam());
System.out.println("yparam : "+cter.getYparam());
System.out.println("zparam : "+cter.getZparam());
}
t.commit();
sess.close();
}
}
程序执行结果如下:
com.weportal.subselect.Container
id : 1
name : 玻璃瓶子
size : 339.12
xparam : 6.0
yparam : 6.0
zparam : 12.0
com.weportal.subselect.Container
id : 32768
name : 中木箱子
size : 4000.0
xparam : 20.0
yparam : 2.0
zparam : 100.0
2.1.5 使用join声明连接
在class中使用join来声明连接,可以把持久化类中的数据属性分散到多个数据表中,由hibernate维护。
例如下面的Person类的属性分成两个表存储。
package com.weportal.join;
public class Person ...{
private long id;
private String name;
private String sex;
private int age;
private String address;
private String country;
private String city;
private String zip;
/** *//**
* @return Returns the id.
*/
public long getId() ...{
return id;
}
/** *//**
* @param id The id to set.
*/
public void setId(long id) ...{
this.id = id;
}
/** *//**
* @return Returns the address.
*/
public String getAddress() ...{
return address;
}
/** *//**
* @param address The address to set.
*/
public void setAddress(String address) ...{
this.address = address;
}
/** *//**
* @return Returns the city.
*/
public String getCity() ...{
return city;
}
/** *//**
* @param city The city to set.
*/
public void setCity(String city) ...{
this.city = city;
}
/** *//**
* @return Returns the country.
*/
public String getCountry() ...{
return country;
}
/** *//**
* @param country The country to set.
*/
public void setCountry(String country) ...{
this.country = country;
}
/** *//**
* @return Returns the name.
*/
public String getName() ...{
return name;
}
/** *//**
* @param name The name to set.
*/
public void setName(String name) ...{
this.name = name;
}
/** *//**
* @return Returns the sex.
*/
public String getSex() ...{
return sex;
}
/** *//**
* @param sex The sex to set.
*/
public void setSex(String sex) ...{
this.sex = sex;
}
/** *//**
* @return Returns the zip.
*/
public String getZip() ...{
return zip;
}
/** *//**
* @param zip The zip to set.
*/
public void setZip(String zip) ...{
this.zip = zip;
}
/** *//**
* @return Returns the age.
*/
public int getAge() ...{
return age;
}
/** *//**
* @param age The age to set.
*/
public void setAge(int age) ...{
this.age = age;
}
}
映射文件如下:
<?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.weportal.join">
<class name="Person" table="Person">
<id name="id">
<generator class="hilo"></generator>
</id>
<property name="name"/>
<property name="sex"/>
<property name="age"/>
<join table="mailAddress">
<key column="addressId"/>
<property name="address"/>
<property name="country"/>
<property name="city"/>
<property name="zip"/>
</join>
</class>
</hibernate-mapping>
产生的数据表的定义如下:
create table `hibernate`.`person`(
`id` bigint default '' not null,
`name` varchar(255),
`sex` varchar(255),
`age` int,
primary key (`id`)
);
create unique index `PRIMARY` on `hibernate`.`person`(`id`);
create table `hibernate`.`mailaddress`(
`addressId` bigint default '' not null,
`address` varchar(255),
`country` varchar(255),
`city` varchar(255),
`zip` varchar(255),
primary key (`addressId`)
);
alter table `hibernate`.`mailaddress`
add index `FKB 714A 23DFE3703E1`(`addressId`),
add constraint `FKB 714A 23DFE3703E1`
foreign key (`addressId`)
references `hibernate`.`person`(`id`);
create unique index `PRIMARY` on `hibernate`.`mailaddress`(`addressId`);
create index `FKB 714A 23DFE3703E1` on `hibernate`.`mailaddress`(`addressId`);
参考《精通Hibernate》 刘洋 著