Hibernate写实体映射方法
前言:
在用SSH的框架时,有了实体,可以通过写Hibernate的映射完成自动的建立数据表,今天小编就来总结一下怎么建立hbm.xml的映射表的技巧:
画UML图,根据UML写实体
实体设计和映射:
其实上面的所有实体和实体关系都可以用 Rose 或EA自动生成的:
根据EA图看出实体之间关系,在Hibernate中怎么设计呢? Role,User,Department
步骤:第一步写注释,第二步代码模板,第三步填充代码
模板如下:
注意:多对一是,外键在多的一方
<!-- parent属性,本类与Department(上级)的多对一 -->
<!-- <many-to-one
name="parent"自己属性名字
class="Department"关联的类名
column="parentId"关联的外键></many-to-one> -->
<many-to-one name="parent" class="Department" column="parentId"></many-to-one>
外键总结:
外键引用的那个列在主表中必须是主键列或者唯一列。
1:n的肯定把外键建立在n的那张表上。
1:1,一般要看谁是主表,谁是附属表,外键当然建立在附属表中。
n:m的情况,需要建立一个关系表,两个原表和其关系分别是1:n,1:m
写 映 射
表与表关系总结:
下面是关系的模板:什么的属性,本类与?的怎样的关系
说明:(1)什么,都是与本类关系的表或关系而非自己;
(2)?都是指其他类
(3)name=”什么” class=”?” column=”什么+Id”
(1)什么的属性,本类与?的一对多
注意,关系为一对多是,这里的column值是一即本类的主键;如果是多对一,这column的值是什么+Id.
<set name=”什么”>
<key column=”本类+Id”/>
<one-to-many class=”?”/>
</set>
例如:
<!--topics的属性,本类与Topic的一对多-->
<set name="topics">
<key column="forumId"></key>
<one-to-many class="Topic"/>
</set>
(2)什么的属性,本类与?的多对一
<many-to-one name=”什么” column=”什么+Id” class=”?”>
</many-to-one>这里的column值就是什么+Id,column也即是外键值。
例如:
<!-- forum属性,本类与Forum的多对一 2017-6-5 10:31:10 -->
<many-to-one name="forum" class="Forum"column="forumId"></many-to-one>
(3)什么的属性,本类与?的多对多
<set name=”什么” table=”新实体表的名称”>
<key column=”本类+Id”/>
<many-to-manyclass=”?” colum=”?+Id”/>
</set>
例如:
<!-- users属性,本类与User的多对多 -->
<setname="users" table="itcast_user_role">
<keycolumn="roleId"></key>
<many-to-many class="User"column="userId"></many-to-many>
</set>
<!--privileges属性,本类与Privilege的多对多 -->
<setname="privileges" table="itcast_role_privilege"lazy="false">
<keycolumn="roleId"></key>
<many-to-manyclass="Privilege" column="privilegeId"></many-to-many>
</set>
(4)什么的属性,本类与?的一对一,采用基于外键的一对一映射方式,本方有外键。
<many-to-one name=”什么” column=”什么+Id” class=”?” unique=”true”></many-to-one>
例如:
<!--lastTopic属性,本类与Topic的一对一。
采用基于外键的一对一映射方式,本方有外键。 -->
<many-to-onename="lastTopic" class="Topic"column="lastTopicId" unique="true"></many-to-one>
<!--lastReply属性,本类与Reply的一对一。
采用基于外键的一对一映射,本方有外键。 -->
<many-to-onename="lastReply" class="Reply"column="lastReplyId" unique="true"></many-to-one>
注意:
(1),一对一的关系,比如只要在一个实体中说明就行了,下面三个个实体,只在Forum和Topic中写一对一的关系,具体的在上面两个例子。
(2)关于继承的,例如下面Topic和Reply 都继承Article,Article不用谢实体表,但是和User的关系都是多对一,在Topic和Reply中都要注明这个关系。
<!-- forum属性,本类与Forum的多对一 2017-6-5 10:31:10 -->
<many-to-one name="forum"class="Forum" column="forumId"></many-to-one>
将映射放到hibernate.cfg.xml中
建表测试报错:
org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'departmentDaoImpl': Injection of resource fieldsfailed; nested exception is org.springframework.beans.factory.BeanCreationException:Error creating bean with name 'sessionFactory' defined in class path resource[applicationContext.xml]: Invocation of init method failed; nested exception isorg.hibernate.HibernateException: Unable to instantiate default tuplizer[org.hibernate.tuple.entity.PojoEntityTuplizer]
atorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:959)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
atjava.security.AccessController.doPrivileged(Native Method)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
atorg.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
atorg.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
atorg.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
atorg.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:429)
atorg.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:728)
atorg.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:380)
atorg.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
atorg.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
atcn.itcast.oa.test.SpringTest.<init>(SpringTest.java:10)
atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
atsun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
atsun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
atjava.lang.reflect.Constructor.newInstance(Constructor.java:525)
atorg.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
atorg.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
atorg.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
atorg.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
atorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
atorg.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
atorg.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
atorg.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
atorg.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
atorg.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
atorg.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
atorg.junit.runners.ParentRunner.run(ParentRunner.java:309)
atorg.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
atorg.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
atorg.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
atorg.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
atorg.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
atorg.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Causedby: org.springframework.beans.factory.BeanCreationException: Error creatingbean with name 'sessionFactory' defined in class path resource[applicationContext.xml]: Invocation of init method failed; nested exception isorg.hibernate.HibernateException: Unable to instantiate default tuplizer[org.hibernate.tuple.entity.PojoEntityTuplizer]
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1338)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:473)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
atjava.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
atorg.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:264)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
atorg.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:261)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
atorg.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:168)
atorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:435)
atorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:409)
atorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:537)
atorg.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180)
atorg.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
atorg.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessAfterInstantiation(CommonAnnotationBeanPostProcessor.java:289)
... 38 more
Causedby: org.hibernate.HibernateException: Unable to instantiate default tuplizer[org.hibernate.tuple.entity.PojoEntityTuplizer]
atorg.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:108)
atorg.hibernate.tuple.entity.EntityTuplizerFactory.constructDefaultTuplizer(EntityTuplizerFactory.java:133)
atorg.hibernate.tuple.entity.EntityEntityModeToTuplizerMapping.<init>(EntityEntityModeToTuplizerMapping.java:80)
atorg.hibernate.tuple.entity.EntityMetamodel.<init>(EntityMetamodel.java:322)
atorg.hibernate.persister.entity.AbstractEntityPersister.<init>(AbstractEntityPersister.java:473)
atorg.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:133)
atorg.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:84)
atorg.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:284)
atorg.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1842)
atorg.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:814)
atorg.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:732)
atorg.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:211)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
atorg.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
... 53 more
Causedby: java.lang.reflect.InvocationTargetException
atsun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
atsun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
atsun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
atjava.lang.reflect.Constructor.newInstance(Constructor.java:525)
at org.hibernate.tuple.entity.EntityTuplizerFactory.constructTuplizer(EntityTuplizerFactory.java:105)
... 66 more
Causedby: org.hibernate.PropertyNotFoundException: Could not find a getter forlastUpdate in class cn.itcast.oa.domain.Topic
atorg.hibernate.property.BasicPropertyAccessor.createGetter(BasicPropertyAccessor.java:326)
atorg.hibernate.property.BasicPropertyAccessor.getGetter(BasicPropertyAccessor.java:320)
atorg.hibernate.mapping.Property.getGetter(Property.java:304)
atorg.hibernate.tuple.entity.PojoEntityTuplizer.buildPropertyGetter(PojoEntityTuplizer.java:297)
atorg.hibernate.tuple.entity.AbstractEntityTuplizer.<init>(AbstractEntityTuplizer.java:155)
atorg.hibernate.tuple.entity.PojoEntityTuplizer.<init>(PojoEntityTuplizer.java:77)
... 71 more
调错结果:其实就是一个字段没有写对:lastUpdateTime写成lastUpdatetime
小结:
学习了,实践了,今天对这个进行一个比较全面的总结。
表与表之间的关系就是那么几种,一对多,一对一,多对一,多对多。画好UML图,更加UML图自动生成实体之后在写hbm.xml映射时,按照模板一步一步照着填空就行了:
下面是关系的模板:什么的属性,本类与?的怎样的关系
说明:(1)什么,都是与本类关系的表或关系而非自己;
(2)?都是指其他类
(3)name=”什么” class=”?” column=”什么+Id”