Hibernate组件映射
2016-05-17 14:48
316 查看
转载自:点击打开链接
在Hibernate中,component是某个实体的逻辑组成部分,它与实体的根本区别是没有oid(对象标识符),component是一个被包含的对象,它作为值类型被持久化,而非一个实体。
下面举两个例子说明其使用和配置:
1.以User和Address为例,一个User有id(Long类型)、name(String类型)、address地址(Address类型),其中Address类中没有id属性(即无对象标识符),则address就是User的一个component组件。
User持久化类:
组件类Address:
User.hbm.xml配置:
说明:
(1).User类映射的表为users,id为其主键,name为User的一般属性,被映射为name字段。
(2).<component>指定User类的address为User的组件,address并不是一个可以直接映射为表字段的属性而是一个类对象,class指定类的名称,<component>的子元素<property>指定组件类的属性与users表字段的映射关系。
(3)不必为Address写一个Address.hbm.xml映射文件,因为Address是作为User的一部分即值类型而不是实体被持久化的,所以Address的属性会与User的其它属性一样被映射为users表中的字段,而不会将Address映射为单独的一个表。
(4)User与Address的关系是"整体与部分",也可以将他们表示为一对一关联关系,这样的话两者就是“平等"关系,那么Address就会被映射为单独的一张表(需要配置Address.hbm.xml文件)。
(5)users表的结构为:
保存User对象:
执行的SQL语句为:
2.若User可有多个地址,即User类中的address属性为Set<Address>类型时,配置如下:
持久化类User:
Address类不变。
配置User.hbm.xml:
说明:
(1)与一对多关联关系不同,<set>中使用的不是<one-to-many>而是<composite-element>,Hibernate会将User对象address属性(Set类型)中的所有元素映射到另外一张表中(显然users中的一个记录不能表示Set中的多个元素),table属性指定另一张表的名称为address_table,该表存放Set中的元素,并且该表中还有一个参照users表id的外键字段user_id。
(2)users表与address_table表的结构为:(使用Hibernate自动建表功能创建)
address_table表的各字段说明:
可以发现address_table表中并没有主键,只有user_id参照users表中的主键id。
保存User对象:
输出的SQL语句为:
address_table的内容:
(因为address_table表没有主键,所以在MySQL WorkBench中无法通过图形化界面添加记录,但是可以操纵SQL语句添加记录,例:
要插入记录的user_id必须为users表中存在的id(因为user_id参照users表的id),可使用update语句更改使表中存在相同的记录,下面会查询id为1L的User对象的Set中的Address对象以检验Hibernate是否会自动排除重复的元素以符合Set中无重复元素的原则。
)
查询User对象:
控制台输出:
可知,Hibernate并没有过滤掉多余的元素,对于输出的3条delete和insert语句,尚不知其机制,但我认为Hibernate没有过滤掉重复的元素是因为Address类中没有实现hashCode()及equals()方法,使用MyEclipse在Address类中生成hashCode及equals方法后再执行上述查询语句:
控制台输出:
可知Hibernate已将多余的重复元素排除。
转载请注明出处:/article/8354811.html
在Hibernate中,component是某个实体的逻辑组成部分,它与实体的根本区别是没有oid(对象标识符),component是一个被包含的对象,它作为值类型被持久化,而非一个实体。
下面举两个例子说明其使用和配置:
1.以User和Address为例,一个User有id(Long类型)、name(String类型)、address地址(Address类型),其中Address类中没有id属性(即无对象标识符),则address就是User的一个component组件。
User持久化类:
public class User { private Long id; private String name; private Address address; //省略set、get方法 }
组件类Address:
public class Address {//注意Address类中无id属性(Address并不会被映射为一张表) private String addressName; private String addressValue; //省略set、get方法 }
User.hbm.xml配置:
<hibernate-mapping> <class name="bean.User" table="users"> <id name="id" column="id" type="long"> <generator class="increment"></generator> </id> <property name="name" column="name" type="string"></property> <component name="address" class="bean.Address"> <property name="addressName" column="address_name"></property> <property name="addressValue" column="address_value"></property> </component> </class> </hibernate-mapping>
说明:
(1).User类映射的表为users,id为其主键,name为User的一般属性,被映射为name字段。
(2).<component>指定User类的address为User的组件,address并不是一个可以直接映射为表字段的属性而是一个类对象,class指定类的名称,<component>的子元素<property>指定组件类的属性与users表字段的映射关系。
(3)不必为Address写一个Address.hbm.xml映射文件,因为Address是作为User的一部分即值类型而不是实体被持久化的,所以Address的属性会与User的其它属性一样被映射为users表中的字段,而不会将Address映射为单独的一个表。
(4)User与Address的关系是"整体与部分",也可以将他们表示为一对一关联关系,这样的话两者就是“平等"关系,那么Address就会被映射为单独的一张表(需要配置Address.hbm.xml文件)。
(5)users表的结构为:
保存User对象:
tx=session.beginTransaction(); User user=new User(); user.setName("zhangsan"); Address address=new Address(); address.setAddressName("HomeAddress"); address.setAddressValue("青岛"); user.setAddress(address); session.save(user); tx.commit();
执行的SQL语句为:
Hibernate: insert into users (name, address_name, address_value, id) values (?, ?, ?, ?)
2.若User可有多个地址,即User类中的address属性为Set<Address>类型时,配置如下:
持久化类User:
public class User { private Long id; private String name; private Set<Address> address; //省略set、get方法 }
Address类不变。
配置User.hbm.xml:
<class name="bean.User" table="users"> <id name="id" column="id" type="long"> <generator class="increment"></generator> </id> <property name="name" column="name" type="string"></property> <!--注意<set>中并不是<one-to-many>而是<composite-element>--> <set name="address" table="address_table"> <key column="user_id"></key> <composite-element class="bean.Address"> <property name="addressName" column="address_name"></property> <property name="addressValue" column="address_value"></property> </composite-element> </set> </class>
说明:
(1)与一对多关联关系不同,<set>中使用的不是<one-to-many>而是<composite-element>,Hibernate会将User对象address属性(Set类型)中的所有元素映射到另外一张表中(显然users中的一个记录不能表示Set中的多个元素),table属性指定另一张表的名称为address_table,该表存放Set中的元素,并且该表中还有一个参照users表id的外键字段user_id。
(2)users表与address_table表的结构为:(使用Hibernate自动建表功能创建)
address_table表的各字段说明:
可以发现address_table表中并没有主键,只有user_id参照users表中的主键id。
保存User对象:
tx=session.beginTransaction(); User user=new User(); user.setName("zhangsan"); Address address=new Address(); address.setAddressName("HomeAddress"); address.setAddressValue("青岛"); Address address2=new Address(); address2.setAddressName("SchoolAddress"); address2.setAddressValue("北京"); user.setAddress(new HashSet<Address>()); user.getAddress().add(address); user.getAddress().add(address2); session.save(user); tx.commit();
输出的SQL语句为:
Hibernate: insert into users (name, id) values (?, ?) Hibernate: insert into address_table (user_id, address_name, address_value) values (?, ?, ?) Hibernate: insert into address_table (user_id, address_name, address_value) values (?, ?, ?)
address_table的内容:
(因为address_table表没有主键,所以在MySQL WorkBench中无法通过图形化界面添加记录,但是可以操纵SQL语句添加记录,例:
要插入记录的user_id必须为users表中存在的id(因为user_id参照users表的id),可使用update语句更改使表中存在相同的记录,下面会查询id为1L的User对象的Set中的Address对象以检验Hibernate是否会自动排除重复的元素以符合Set中无重复元素的原则。
)
查询User对象:
User u=(User)session.get(User.class, 1L); Set<Address> address=u.getAddress(); for (Iterator iterator = address.iterator(); iterator.hasNext();) { Address a = (Address) iterator.next(); System.out.println(a.getAddressName()+":"+a.getAddressValue());}
控制台输出:
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_ from users user0_ where user0_.id=? Hibernate: select address0_.user_id as user1_0_, address0_.address_name as address2_0_, address0_.address_value as address3_0_ from address_table address0_ where address0_.user_id=? HomeAddress:青岛 HomeAddress:青岛 H:S Hibernate: delete from address_table where user_id=? and address_name=? and address_value=? Hibernate: delete from address_table where user_id=? and address_name=? and address_value=? Hibernate: delete from address_table where user_id=? and address_name=? and address_value=? Hibernate: insert into address_table (user_id, address_name, address_value) values (?, ?, ?) Hibernate: insert into address_table (user_id, address_name, address_value) values (?, ?, ?) Hibernate: insert into address_table (user_id, address_name, address_value) values (?, ?, ?)
可知,Hibernate并没有过滤掉多余的元素,对于输出的3条delete和insert语句,尚不知其机制,但我认为Hibernate没有过滤掉重复的元素是因为Address类中没有实现hashCode()及equals()方法,使用MyEclipse在Address类中生成hashCode及equals方法后再执行上述查询语句:
控制台输出:
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_ from users user0_ where user0_.id=? Hibernate: select address0_.user_id as user1_0_, address0_.address_name as address2_0_, address0_.address_value as address3_0_ from address_table address0_ where address0_.user_id=? HomeAddress:青岛 H:S
可知Hibernate已将多余的重复元素排除。
转载请注明出处:/article/8354811.html
相关文章推荐
- 架构漫谈(九):理清技术、业务和架构的关系
- I/O 重定向
- iOS多线程编程技术之NSThread、Cocoa NSOperation、GCD
- 代码讲解Android Scroller、VelocityTracker
- wordpress里控制摘要格式
- Masonry框架使用示例(转载)
- inheritprototype原型继承封装及综合继承最简实例
- .xsession-errors:openConnection: connect: No such file or directory cannot connect to brltty at :0
- Matlab和外部文件进行数据交换相关的命令
- Visual Studio调试服务端程序:w3wp进程消失 解决办法
- 请求消息体和响应消息体
- 封装
- Visual Studio调试服务端程序:w3wp进程消失 解决办法
- 深入理解Java:SimpleDateFormat安全的时间格式化
- angularJs中关于ng-class的三种使用方式说明
- phpstorm添加laravle语法支持
- 动态布局--动态修改RelativeLayout宽高的方法
- html代码变成文本显示在页面上
- js数组转json
- Invalid classpath publish/export dependency /common. Project entries not supported