10 14Hibernate之实体粒度划分

本文介绍了Hibernate实体粒度划分的重要性,通过案例展示了如何基于文件和Annotation实现细粒度划分。实体粒度划分有助于符合面向对象设计,提高代码结构的合理性。文中给出了配置文件和测试代码示例,讨论了HBM配置与Annotation配置的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 实体粒度划分的意义

在整个Hibernate技术应用之中,基本的流程:要提供有一个POJO类,而后要提供有一个POJO.hbm.xml文件,但是如果说现在假设有如下一种情况出现。
范例:定义数据库脚本

-- 删除数据表
DROP TABLE IF EXISTS 'member';
-- 创建数据表
CREATE TABLE 'member'(
	mid VARCHAR(50),
	mname VARCHAR(50),
	mage INT,
	mbirthday DATE,
	maddress VARCHAR(100),
	mzipcode VARCHAR(8),
	mphone VARCHAR(50),
	CONSTRAINT pk_nid PRIMARY KEY(nid)
);

如果按照正常的思路,那么此时生成的POJO类的结构如下。
范例:生成的POJO类的结构

public class Member implements java.io.Serializable {

	// Fields

	private String mid;
	private String mname;
	private Integer mage;
	private Date mbirthday;
	private String maddress;
	private String mzipcode;
	private String mphone;
}

有人现在会提出这样的问题,以上的设计方式不适合于面向对象的应用形式。从面向对象的角度来看以上的Member的组成应该分为:Member、MemberBasic、MemberContact。而每个类的作用如下:
(1)MemberBasic:

package org.lks.pojo;

import java.util.Date;

@SuppressWarnings("serial")
public class MemberBasic implements java.io.Serializable {
	private String mname;
	private Integer mage;
	private Date mbirthday;
}

(2)MemberContract:

package org.lks.pojo;

@SuppressWarnings("serial")
public class MemberContact implements java.io.Serializable {
	private String maddress;
	private String mzipcode;
	private String mphone;
}

(3)Member:

package org.lks.pojo;

@SuppressWarnings("serial")
public class Member implements java.io.Serializable {
	private String mid;
	private MemberBasic basic = new MemberBasic();
	private MemberContact contact = new MemberContact();
}

此时的结构非常符合于面向对象的设计思想,这种的设计方式应该算是合成设计模式。

2 基于*.hbm.xml文件实现细粒度划分

虽然现在只有一张member表,但是却发现有三个实体类,并且这些实体类之间是存有引用关系的,而要想使用Hibernate开发,就必须将这些关系再配置文件中进行展示。

所以现在的重点就在配置文件的编写上。
范例:在Member.hbm.xml文件中实现配置

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
	<!-- 不管如何操作,每一个*.hbm.xml文件只会与一个POJO类关联 -->
    <class name="org.lks.pojo.Member" table="member" catalog="hedb">
        <id name="mid" type="java.lang.String">
            <column name="mid" length="50" />
            <generator class="assigned"></generator>
        </id>
        <!-- 此处配置的Member类中的basic属性的类型以及包含的内容 -->
        <component name="basic" class="org.lks.pojo.MemberBasic">
	        <property name="mname" type="java.lang.String">
	            <column name="mname" length="50" />
	        </property>
	        <property name="mage" type="java.lang.Integer">
	            <column name="mage" />
	        </property>
	        <property name="mbirthday" type="java.util.Date">
	            <column name="mbirthday" length="10" />
	        </property>
	    </component>
        <!-- 此处配置的Member类中的contact属性的类型以及包含的内容 -->
        <component name="contact" class="org.lks.pojo.MemberContact">
        	<property name="maddress" type="java.lang.String">
	            <column name="maddress" length="100" />
	        </property>
	        <property name="mzipcode" type="java.lang.String">
	            <column name="mzipcode" length="8" />
	        </property>
	        <property name="mphone" type="java.lang.String">
	            <column name="mphone" length="50" />
	        </property>
	    </component>
    </class>
</hibernate-mapping>

配置完成之后下面直接使用程序进行测试。
范例:编写增加操作

package org.lks.test;

import java.text.SimpleDateFormat;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;

public class TestMemberInsert {
	public static void main(String[] args) throws Exception {
		Member vo = new Member();
		vo.setMid("3161301220");
		vo.getBasic().setMage(23);
		vo.getBasic().setMname("lks");
		vo.getBasic().setMbirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1996-10-15"));
		vo.getContact().setMaddress("河南");
		vo.getContact().setMphone("121291");
		vo.getContact().setMzipcode("237283");
		HibernateSessionFactory.getSession().save(vo);
		HibernateSessionFactory.getSession().beginTransaction().commit();
		HibernateSessionFactory.closeSession();
		System.exit(0);
	}
}

Hibernate: 
insert into 
	hedb.member (mname, mage, mbirthday, maddress, mzipcode, mphone, mid) 
	values (?, ?, ?, ?, ?, ?, ?)

现在虽然是属于不同的类型,但是在最终生成的时候还是使用了一条SQL语句执行的增加。
范例:数据读取

package org.lks.test;

import org.lks.dbc.HibernateSessionFactory;
import org.lks.pojo.Member;

public class TestMemberGet {
	public static void main(String[] args) throws Exception {
		Member vo = (Member)HibernateSessionFactory.getSession().get(Member.class, "3161301220");
		System.out.println(vo);
		HibernateSessionFactory.closeSession();
		System.exit(0);
	}
}

Hibernate: 
    select
        member0_.mid as mid1_0_0_,
        member0_.mname as mname2_0_0_,
        member0_.mage as mage3_0_0_,
        member0_.mbirthday as mbirthda4_0_0_,
        member0_.maddress as maddress5_0_0_,
        member0_.mzipcode as mzipcode6_0_0_,
        member0_.mphone as mphone7_0_0_ 
    from
        hedb.member member0_ 
    where
        member0_.mid=?
Member [mid=3161301220, basic=MemberBasic [mname=lks, mage=23, mbirthday=1996-10-14 08:00:00.0], contact=MemberContact [maddress=河南, mzipcode=237283, mphone=121291]]

此时依然只发出了一条查询指令,但是查询之后的数据都已经各自保存到各自对象之中。

3 基于Annotation的配置

如果真的要使用了实体的细粒度划分,那么还是HBM的配置方式简便,而Annotation的配置模式太麻烦了。

首先还是生成一个基于Annotation配置的Member类,但是随后需要对这些类进行修改。
范例:创建支持于Annotation配置的MemberBasic类

package org.lks.pojo;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;


@SuppressWarnings("serial")
@Embeddable
@AttributeOverrides({
	@AttributeOverride(name="mname",column=@Column(name="mname")),
	@AttributeOverride(name="mage",column=@Column(name="mage")),
	@AttributeOverride(name="mbirthday",column=@Column(name="mbirthday"))
})
public class MemberBasic implements java.io.Serializable {

	private String mname;
	private Integer mage;
	private Date mbirthday;
	
	@Column(name = "mname", length = 50)

	public String getMname() {
		return this.mname;
	}

	public void setMname(String mname) {
		this.mname = mname;
	}

	@Column(name = "mage")

	public Integer getMage() {
		return this.mage;
	}

	public void setMage(Integer mage) {
		this.mage = mage;
	}

	@Temporal(TemporalType.DATE)
	@Column(name = "mbirthday", length = 10)

	public Date getMbirthday() {
		return this.mbirthday;
	}

	public void setMbirthday(Date mbirthday) {
		this.mbirthday = mbirthday;
	}

}

范例:创建支持于Annotation配置的MemberContact类

package org.lks.pojo;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embeddable;


@SuppressWarnings("serial")
@Embeddable
@AttributeOverrides({
	@AttributeOverride(name="maddress",column=@Column(name="maddress")),
	@AttributeOverride(name="mzipcode",column=@Column(name="mzipcode")),
	@AttributeOverride(name="mphone",column=@Column(name="mphone")),
})
public class MemberContact implements java.io.Serializable {

	private String maddress;
	private String mzipcode;
	private String mphone;

	@Column(name = "maddress", length = 100)

	public String getMaddress() {
		return this.maddress;
	}

	public void setMaddress(String maddress) {
		this.maddress = maddress;
	}

	@Column(name = "mzipcode", length = 8)

	public String getMzipcode() {
		return this.mzipcode;
	}

	public void setMzipcode(String mzipcode) {
		this.mzipcode = mzipcode;
	}

	@Column(name = "mphone", length = 50)

	public String getMphone() {
		return this.mphone;
	}

	public void setMphone(String mphone) {
		this.mphone = mphone;
	}

}

范例:修改Member类定义

package org.lks.pojo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@SuppressWarnings("serial")
@Entity
@Table(name = "member", catalog = "hedb")
public class Member implements java.io.Serializable {

	// Fields

	private String mid;
	private MemberBasic basic = new MemberBasic();
	private MemberContact contact = new MemberContact();

	@Id
	@Column(name = "mid", unique = true, nullable = false, length = 50)
	public String getMid() {
		return this.mid;
	}

	public void setMid(String mid) {
		this.mid = mid;
	}

	public MemberBasic getBasic() {
		return basic;
	}

	public void setBasic(MemberBasic basic) {
		this.basic = basic;
	}

	public MemberContact getContact() {
		return contact;
	}

	public void setContact(MemberContact contact) {
		this.contact = contact;
	}
}

此处关键就在于被包含的细粒度类上的变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值