Hibernate映射(七)— 组件


组件映射


情况:

多个类中存在一些相同属性,将其抽取出来


与继承区别?

继承:

    继承实在编译时刻静态定义的,较方便复用。但继承对子类暴露了其父类的实现细节,破坏了封装性;子类与父类有着较强的依赖关系,最终限制了复用

组合:

组合是通过获得对其他对象的引用而在运行时刻动态定义的。基于接口进行开发,所以实现上依赖性小

设计模式第二原则:

少用继承,多用组合


关系图:



具体实现

1、实体

<span style="font-size:18px;">contact:
	/**
	 * 共有的联系方式值类
	 * @author gxq
	 *
	 */
	public class Contact {
		//定义邮箱、地址、邮箱编号、联系方式
		private String email;
		private String address;
		private String zipCode;
		private String contactTel;
		
		public String getEmail() {
			return email;
		}
		public void setEmail(String email) {
			this.email = email;
		}
		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 getContactTel() {
			return contactTel;
		}
		public void setContactTel(String contactTel) {
			this.contactTel = contactTel;
		}
	}
User:
	/**
	 * 定义用户实体
	 * @author gxq
	 *
	 */
	public class User {
		//id、姓名、联系方式
		private int id;
		
		private String name;
		
		private Contact userContact;
		
		
	
		public Contact getUserContact() {
			return userContact;
		}
	
		public void setUserContact(Contact userContact) {
			this.userContact = userContact;
		}
	
		public int getId() {
			return id;
		}
	
		public void setId(int id) {
			this.id = id;
		}
	
		public String getName() {
			return name;
		}
	
		public void setName(String name) {
			this.name = name;
		}
	}
Employee:
	
	/**
	 * 定以员工实体
	 * @author gxq
	 *
	 */
	public class Employee {
		//id、姓名、联系方式
		private int id;
		
		private String name;
		
		private Contact employeeContact;
		
		
		public Contact getEmployeeContact() {
			return employeeContact;
		}
	
		public void setEmployeeContact(Contact employeeContact) {
			this.employeeContact = employeeContact;
		}
	
		public int getId() {
			return id;
		}
	
		public void setId(int id) {
			this.id = id;
		}
	
		public String getName() {
			return name;
		}
	
		public void setName(String name) {
			this.name = name;
		}
	}</span>


2、映射文件

<span style="font-size:18px;">User:
	<hibernate-mapping>
		<class name="com.bjpowernode.component.User" table="t_user">
			<id name="id">
				<generator class="native"/>
			</id>
			<property name="name"/>
			
			<component name="userContact">
				<property name="email"></property>
				<property name="address"></property>
				<property name="zipCode"></property>
				<property name="contactTel"></property>
			</component>
		</class>
	</hibernate-mapping>
Employee:
	<hibernate-mapping>
		<class name="com.bjpowernode.component.Employee" table="t_employee">
			<id name="id">
				<generator class="native" />
			</id>
			<property name="name" />
	
			<component name="employeeContact">
				<property name="email"></property>
				<property name="address"></property>
				<property name="zipCode"></property>
				<property name="contactTel"></property>
			</component>
		</class>
	</hibernate-mapping>
</span>

3、配置文件

<hibernate-configuration>
	<session-factory>
		<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="hibernate.connection.url">
        <![CDATA[jdbc:mysql://localhost:3306/Hibernate?useUnicode=true&characterEncoding=utf8]]>
		</property>
		<property name="hibernate.connection.username">root</property>
		<property name="hibernate.connection.password">root</property>
		<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
		<property name="hibernate.hbm2ddl.auto">update</property>
		<property name="hibernate.show_sql">true</property>
	
	    <mapping resource="com/bjpowernode/component/User.hbm.xml"/>
	    <mapping resource="com/bjpowernode/component/Employee.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

4、封装好的工具类:HibernateUtils

/**
 * 工具类(封装开启session和事务)
 * @classname   HibernateUtils 
 * @author      高晓青
 * @date        2015-4-16 下午2:56:42 
 * @version     hibernate
 */
public class HibernateUtils {
	private static SessionFactory factory;
	
	static{
		try {
			//默认读取的是hibernate.cfg.xml
			Configuration cfg = new Configuration().configure();
			
			//建立sessionFactory
			factory = cfg.buildSessionFactory();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//开启session
	public static Session getSession(){
		return factory.openSession();
	}
	
	//关闭session
	public static void closeSession(Session session){
		//判断是否为空
		if(session!=null){
			//判断是否是打开状态再进行关闭
			if(session.isOpen()){
				session.close();
			}
		}
	}
}

5、添加

public void testSaveComponent(){
         Session session=null;
	try {
		//获取session,打开事务
		session=HibernateUtils.getSession();
		session.beginTransaction();
		
		//定义User实体
		User user=new User();
		user.setName("小红");
		
		//定义Contact实体
		Contact contactUser=new Contact();
		contactUser.setAddress("廊坊市");
		contactUser.setContactTel("1324568923");
		contactUser.setEmail("456876@qq.com");
		contactUser.setZipCode("065000");
		
		//将Contact实体加载到User实体中
		user.setUserContact(contactUser);
		session.save(user);
		
		//定义Employee实体
		Employee employee=new Employee();
		employee.setName("张亮");
		
		//定义Contact实体
		Contact contactEmployee=new Contact();
		contactEmployee.setAddress("石家庄市");
		contactEmployee.setContactTel("18932623527");
		contactEmployee.setEmail("2416876@qq.com");
		contactEmployee.setZipCode("030000");
		
		//将Contact实体加载到Employee实体中
		employee.setEmployeeContact(contactEmployee);
		session.save(employee);
		
		//提交事务
		session.getTransaction().commit();
		} catch (Exception e) {
			e.printStackTrace();
			session.getTransaction().rollback();
		}finally{
			HibernateUtils.closeSession(session);
		}
}

 

6、查询

public void testLoad(){
	Session session=null;
	
	try {
		//获取session,打开事务
		session=HibernateUtils.getSession();
		session.beginTransaction();
		
		//根据用户id查询用户信息
		User user=(User) session.load(User.class,1);
		
		//打印用户姓名和地址
		System.out.println(user.getName());
		System.out.println(user.getUserContact().getAddress());
		
	} catch (Exception e) {
		e.printStackTrace();
	}
}

 


 


特殊的组件映射:符合主键映射


情况:

把主键相关字段拿出单独一个类,这个类是由要求的:

  1. 必须实现序列化接口
  2. 覆盖equalshashcode方法


关系图:


具体实现

1、实体

<span style="font-size:18px;">YearMonthPeriodPK:
	/**
	 * 复合主键实体
	 * 
	 * @author gxq
	 * 
	 */
	public class YearMonthPeriodPK implements Serializable {
		// 核算年份
		private String ficalYear;
		// 核算月份
		private String ficalmonth;
	
		public String getFicalYear() {
			return ficalYear;
		}
	
		public void setFicalYear(String ficalYear) {
			this.ficalYear = ficalYear;
		}
	
		public String getFicalmonth() {
			return ficalmonth;
		}
	
		public void setFicalmonth(String ficalmonth) {
			this.ficalmonth = ficalmonth;
		}
	
		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result
					+ ((ficalYear == null) ? 0 : ficalYear.hashCode());
			result = prime * result
					+ ((ficalmonth == null) ? 0 : ficalmonth.hashCode());
			return result;
		}
	
		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			YearMonthPeriodPK other = (YearMonthPeriodPK) obj;
			if (ficalYear == null) {
				if (other.ficalYear != null)
					return false;
			} else if (!ficalYear.equals(other.ficalYear))
				return false;
			if (ficalmonth == null) {
				if (other.ficalmonth != null)
					return false;
			} else if (!ficalmonth.equals(other.ficalmonth))
				return false;
			return true;
		}
	}
YearPeriod:
/**
 * 核算年实体
 * 
 * @author gxq
 * 
 */
public class YearPeriod {
	// 把主键当成一个属性
	private YearMonthPeriodPK yearMonthPeriodPK;

	// 开始时间
	private Date beginDate;
	// 结束时间
	private Date endDate;

	public Date getBeginDate() {
		return beginDate;
	}

	public void setBeginDate(Date beginDate) {
		this.beginDate = beginDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public YearMonthPeriodPK getYearMonthPeriodPK() {
		return yearMonthPeriodPK;
	}

	public void setYearMonthPeriodPK(YearMonthPeriodPK yearMonthPeriodPK) {
		this.yearMonthPeriodPK = yearMonthPeriodPK;
	}
}
MonthPeriod:
/**
 * 月核算实体
 * @author gxq
 *
 */
public class MonthPeriod {
	//把主键当成一个属性
	private YearMonthPeriodPK yearMonthPeriodPK;
	
	//开始时间
	private Date beginDate;
	//结束时间
	private Date endDate;
	
	public Date getBeginDate() {
		return beginDate;
	}
	public void setBeginDate(Date beginDate) {
		this.beginDate = beginDate;
	}
	public Date getEndDate() {
		return endDate;
	}
	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}
	
	public YearMonthPeriodPK getYearMonthPeriodPK() {
		return yearMonthPeriodPK;
	}
	public void setYearMonthPeriodPK(YearMonthPeriodPK yearMonthPeriodPK) {
		this.yearMonthPeriodPK = yearMonthPeriodPK;
	}
}
</span>


2、映射文件

YearPeriod:
	<hibernate-mapping>
		<class name="com.bjpowernode.component.YearPeriod" table="t_yearPeriod">
			//复合主键
			<composite-id name="yearMonthPeriod">
				<key-property name="ficalYear"></key-property>
				<key-property name="ficalmonth"></key-property>
			</composite-id>
	
			<property name="beginDate" type="date" />
			<property name="endDate" type="date" />
		</class>
	</hibernate-mapping>
MonthPeriod:
	<hibernate-mapping>
		<class name="com.bjpowernode.component.MonthPeriod" table="t_monthPeriod">
			//复合主键
			<composite-id name="yearMonthPeriodPK">
				<key-property name="ficalYear"></key-property>
				<key-property name="ficalmonth"></key-property>
			</composite-id>
			
			<property name="beginDate" type="date"/>
			<property name="endDate" type="date"/>
		</class>
	</hibernate-mapping>

3、配置文件

同上

4、封装好的工具类:HibernateUtils

同上

5、添加

<span style="font-size:18px;">public void testComposite() {
	Session session = null;
	try {
		// 获取session,打开事务
		session = HibernateUtils.getSession();
		session.beginTransaction();
		
		//实例年核算期
		YearPeriod yearPeriod=new YearPeriod();
		
		//构造复合主键对象
		YearMonthPeriodPK yearMonthPeriodPK=new YearMonthPeriodPK();
		yearMonthPeriodPK.setFicalmonth("6");
		yearMonthPeriodPK.setFicalYear("2016");
		yearPeriod.setYearMonthPeriodPK(yearMonthPeriodPK);
		
		yearPeriod.setBeginDate(new Date());
		yearPeriod.setEndDate(new Date());
		//保存年核算期
		session.save(yearPeriod);
		
		
		//实例年核算期
		MonthPeriod monthPeriod=new MonthPeriod();
		
		//构造复合主键对象
		YearMonthPeriodPK yearMonthPeriodPKMonth=new YearMonthPeriodPK();
		yearMonthPeriodPKMonth.setFicalmonth("5");
		yearMonthPeriodPKMonth.setFicalYear("2015");
		monthPeriod.setYearMonthPeriodPK(yearMonthPeriodPKMonth);
		
		monthPeriod.setBeginDate(new Date());
		monthPeriod.setEndDate(new Date()); 
		
		//保存月核算期
		session.save(monthPeriod);
		
		// 提交事务
		session.getTransaction().commit();
	} catch (Exception e) {
		e.printStackTrace();
		session.getTransaction().rollback();
	} finally {
		HibernateUtils.closeSession(session);
	}
}
</span>


 

6、查询

public void testComposite(){
	Session session=null;
	
	try {
		session=HibernateUtils.getSession();
		session.beginTransaction();
		
		//构造复合主键对象
		YearMonthPeriodPK yearMonthPeriodPK=new YearMonthPeriodPK();
		yearMonthPeriodPK.setFicalmonth("6");
		yearMonthPeriodPK.setFicalYear("2016");
		
		YearPeriod yearPeriod=(YearPeriod) session.load(YearPeriod.class,yearMonthPeriodPK);
		System.out.println(yearPeriod.getBeginDate());
		
	} catch (Exception e) {
		e.printStackTrace();
	}
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值