基于设计的粒度设计
创建表contactee
ContactInfo类用来封装联系方式所有的字段
package vo;
public class ContactInfo {
private String address;
private String zipcode;
private String tel;
private String email;
private String msn;
private String fax;
public ContactInfo() {
super();
}
public ContactInfo(String address, String zipcode, String tel,
String email, String msn, String fax) {
super();
this.address = address;
this.zipcode = zipcode;
this.tel = tel;
this.email = email;
this.msn = msn;
this.fax = fax;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getMsn() {
return msn;
}
public void setMsn(String msn) {
this.msn = msn;
}
public String getFax() {
return fax;
}
public void setFax(String fax) {
this.fax = fax;
}
}
Contactee类中映射了除联系方式外的其他属性,并关联ContactInfo作为属性
package vo;
public class Contactee implements java.io.Serializable{
private Integer id;
private Integer age;
private String firstname;
private String lastname;
private ContactInfo contactInfo;
public Contactee() {
super();
}
public Contactee(Integer id) {
this.id = id;
}
public Contactee(Integer id, Integer age, String firstname,
String lastname) {
super();
this.id = id;
this.age = age;
this.firstname = firstname;
this.lastname = lastname;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public ContactInfo getContactInfo() {
return contactInfo;
}
public void setContactInfo(ContactInfo contactInfo) {
this.contactInfo = contactInfo;
}
}
其中ContactInfo并不是一个具体实体的引用,而仅仅是Contact的一个属性。
在映射文件中,使用component元素进行映射
Contactee.hbm.xml
<?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">
<hibernate-mapping>
<class name="vo.Contactee" table="contactee" catalog="mldn">
<id name="id" type="java.lang.Integer" >
<column name="id" />
<generator class="assigned"/>
</id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<property name="firstname" type="java.lang.String">
<column name="firstname" length ="50" />
</property>
<property name="lastname" type="java.lang.String">
<column name="lastname" length ="50" />
</property>
<component name="contactInfo" class="vo.ContactInfo">
<property name="address" type="java.lang.String">
<column name="address" length ="200" />
</property>
<property name="zipcode" type="java.lang.String">
<column name="zipcode" length ="10" />
</property>
<property name="tel" type="java.lang.String">
<column name="tel" length ="20" />
</property>
<property name="email" type="java.lang.String">
<column name="email" length ="100" />
</property>
<property name="msn" type="java.lang.String">
<column name="msn" length ="100" />
</property>
<property name="fax" type="java.lang.String">
<column name="fax" length ="20" />
</property>
</component>
</class>
</hibernate-mapping>
可见,在Contactee.hbm.xml中,使用component元素将类ContactInfo的属性和表的字段进行映射。
hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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="connection.username">root</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/mldn</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.password">password</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.pool_size">20</property>
<property name="show_sql">true</property>
<mapping resource="vo/Customer.hbm.xml"/>
<mapping resource="vo/Contactee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
package util;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;
/**
* Configures and provides access to Hibernate sessions, tied to the
* current thread of execution. Follows the Thread Local Session
* pattern, see {@link http://hibernate.org/42.html }.
*/
public class HibernateSessionFactory {
/**
* Location of hibernate.cfg.xml file.
* Location should be on the classpath as Hibernate uses
* #resourceAsStream style lookup for its configuration file.
* The default classpath location of the hibernate config file is
* in the default package. Use #setConfigFile() to update
* the location of the configuration file for the current session.
*/
private static String CONFIG_FILE_LOCATION = "config/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
private static org.hibernate.SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION;
static {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession()
: null;
threadLocal.set(session);
}
return session;
}
/**
* Rebuild hibernate session factory
*
*/
public static void rebuildSessionFactory() {
try {
configuration.configure(configFile);
sessionFactory = configuration.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
/**
* Close the single hibernate session instance.
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
/**
* return session factory
*
*/
public static org.hibernate.SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* return session factory
*
* session factory will be rebuilded in the next call
*/
public static void setConfigFile(String configFile) {
HibernateSessionFactory.configFile = configFile;
sessionFactory = null;
}
/**
* return hibernate configuration
*
*/
public static Configuration getConfiguration() {
return configuration;
}
}
测试类
package test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import util.HibernateSessionFactory;
import vo.ContactInfo;
import vo.Contactee;
public class Testhib {
public static void main(String[] args) {
ContactInfo cInfo = new ContactInfo("BeiJing HaiDian","100000","15013674319","mail@163.com","8888777","010-55577757");
Contactee c = new Contactee(2,23,"Greec","Marry");
c.setContactInfo(cInfo);
Session session = HibernateSessionFactory.getSession();
Transaction tran = session.beginTransaction();
session.save(c);
tran.commit();
}
}
运行结果:
向表中插入了一条完整记录。
关于性能的粒度设计
如果表中的某些字段不经常使用,而且占有空间较大,则可以使用基于性能的粒度设计。
例:创建表student
上述表中的字段image表示Student的照片,使用Blob类型,所占用空间较大。
如果在应用中,image的字段不是总被使用,那么就可以将表student映射为两个类,其中一个类为StudentDetail,映射表中所有字段,包括image字段;
而另一个类StudentBasic,映射表中除了image之外的字段。
StudentBasic.java
package vo;
public class StudentBasic {
private Integer id;
private Integer age;
private String firstname;
private String lastname;
public StudentBasic() {
}
public StudentBasic(Integer id) {
this.id = id;
}
public StudentBasic(Integer id, Integer age, String firstname,
String lastname) {
super();
this.id = id;
this.age = age;
this.firstname = firstname;
this.lastname = lastname;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
}
StudentBasic.hbm.xml
<?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">
<hibernate-mapping>
<class name="vo.StudentBasic" table="student" catalog="mldn">
<id name="id" type="java.lang.Integer" >
<column name="id" />
<generator class="assigned"/>
</id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<property name="firstname" type="java.lang.String">
<column name="firstname" length ="50" />
</property>
<property name="lastname" type="java.lang.String">
<column name="lastname" length ="50" />
</property>
</class>
</hibernate-mapping>
StudentDetail.java
package vo;
import com.mysql.jdbc.Blob;
public class StudentDetail extends StudentBasic{
private Blob image;
public StudentDetail() {
}
public StudentDetail(Integer id, Integer age, String firstname,
String lastname,Blob image) {
super(id, age, firstname, lastname);
this.image=image;
// TODO Auto-generated constructor stub
}
public Blob getImage() {
return image;
}
public void setImage(Blob image) {
this.image = image;
}
}
StudentDetail.hbm.xml
<?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">
<hibernate-mapping>
<class name="vo.StudentDetail" table="student" catalog="mldn">
<id name="id" type="java.lang.Integer" >
<column name="id" />
<generator class="assigned"/>
</id>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<property name="firstname" type="java.lang.String">
<column name="firstname" length ="50" />
</property>
<property name="lastname" type="java.lang.String">
<column name="lastname" length ="50" />
</property>
<property name="image" type="java.lang.Blob">
<column name="image" />
</property>
</class>
</hibernate-mapping>