Component映射体现一种封装复用的思想,我们知道数据域模型的设计一般是粗粒度的,而对象模型的设计我们往往遵循细粒度、单一职责、抽象复用的原则,但到了对象模型与数据模型相互转换、对应的时候,我们就需要考虑来怎样实现来同时满足双方的基本设计理念。Hibernate中就提供相关的实现。
原理分析
对象模型:
User类与Employee类存有很多相同的属性,为了更好的可维护性与灵活性,进行抽象、复用得出了Contact类,Contact类是不需要映射到数据库中表的,有了这样的需求,Hibernate进行了相关的实现。
相关的映射文件如下:
<?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>
<class name="com.tgb.hibernate.User" table="t_user">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<component name="contact">
<property name="email" />
<property name="address" />
<property name="zipCode" />
<property name="contactTel" />
</component>
</class>
</hibernate-mapping>
Employee类与User类的映射文件类似,不再说明。通过映射文件可以知道,Hibernate通过读取component标签内的property自标签,将其对应的属性映射到数据库表字段。
操作示例
保存与加载,与平时的类操作相似:
public void testSave(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
User user = new User();
user.setName("张三");
//建立值类
Contact contact = new Contact();
contact.setEmail("email");
contact.setAddress("address");
contact.setZipCode("zipCode");
contact.setContactTel("contactTel");
user.setContact(contact);
session.save(user);
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
public void testLoad(){
Session session = null;
Transaction tx = null;
try{
session = HibernateUtils.getSession();
tx = session.beginTransaction();
User user = (User)session.load(User.class, 1);
System.out.println(user.getName());
System.out.println(user.getContact().getAddress());
tx.commit();
}catch(Exception e){
e.printStackTrace();
if(tx != null){
tx.rollback();
}
}finally{
HibernateUtils.closeSession(session);
}
}
总结
Contact类在DDD中称为值类,从属于实体类,没有oid。通过这样的实现,我们既达到了对象模型的复用,也能够通过Hibernate的映射,得到在DB中的存储。
时间: 2024-12-12 22:44:10