- 浏览: 724114 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
yukang1:
太适合新手了 谢主隆恩
tomcat结合nginx使用小结 -
singformyself:
确实,楼主写的很好。必须赞一个。让我这个nginx新手如获至宝 ...
tomcat结合nginx使用小结 -
光太狼Leon:
这才是真正对新手有用的文章。
tomcat结合nginx使用小结 -
wangyudong:
由CXF实现的微服务需要有比较好的工具去测试RESTful A ...
JAVA webservice之CXF -
MCLoginandPwd:
如今,java技术框架太多了,给你分享一个好玩代码生成器,ht ...
论JAVA框架
记得我们在以前例子中一对多中用到的Set,还有印象么,如果没有赶快去查一下资料,回顾一下。今天我们就围绕着这些Collection来进行学习。
还是不废话了,我们直接进入正题。
1)首先我们来学习一下Set。大家都知道JAVA util包里面也有一个Set,那么hibernate里面的set和java的set和什么区别和联系呢?我们打开hibernate的API,找到Set,可以看到。
这个Collection是什么东西呢?我们再进去看:
我们看到的就是这样一个hibernate的集合的父类,它是一个抽象类,有一系列具体的实现类,我们继续看到下面的方法时,发现这个类实现上是对java集合的封装,这样我们就明白啦,所谓的hibernate的Set实际上也只是封装了java的Set。
那么,Set中不允许重复元素的这个特点是否也在hibernate中呢?答案当然是肯定啦。
我们这里不看这些,我们以前在学习映射时是直接把属性和所关联的类进行关联,但今天我们不这样啦,我们用另外一种方法,只是关联一个字符串,看看有什么问题。
但在看这个问题前,我们先来看看,java中的String比较。
public static void main(String[] args) { String s1 = "shun1"; String s2 = "shun1"; System.out.println("s1==s2:"+(s1==s2)); }
相信很多童鞋都知道答案是true,不知道的童鞋可以去看看这里http://blog.csdn.net/flyjimi/archive/2008/07/13/2645063.aspx,讲得比较清楚了。
废话不多说,我们讲这个原因就是为了引出下面的这个问题。
在进行例子前先看一下我们的映射文件,映射类那些就不写了:
这是TUser的映射文件:
<class name="TUser" table="t_user" dynamic-insert="true" dynamic-update="true"> <id name="id" column="id"> <generator class="native" /> </id> <property name="name" type="java.lang.String" column="name"/> <property name="age" type="java.lang.Integer" column="age"/> <set name="addresses" cascade="all" table="t_address"> <key column="user_id" /> <!-- <one-to-many class="Address"/> --> <element column="address" type="string" /> </set> </class>
接下来是Address的映射文件:
<class name="Address" table="t_address" dynamic-insert="false" dynamic-update="false"> <id name="id" column="id" type="java.lang.Integer"> <generator class="native" /> </id> <property name="address" column="address" type="java.lang.String" /> <many-to-one name="user" class="TUser" column="user_id" not-null="true"></many-to-one> </class>
童鞋们看清楚了,我在TUser中的Set里面把one-to-many注释了而用了element,这里先不管它有什么问题,我们先看数据库:
这是t_address表:
下面是t_user表:
我们可以看到id为4的User对应了三个地址,接下来,我们来看一下测试方法:
public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); TUser user = (TUser)session.load(TUser.class,new Integer(4)); Set set = user.getAddresses(); session.close(); System.out.println("address size:"+set.size()); }
很简单的一个查询类,只是取出了这个结果而已,我们看到一个奇怪的现象:
address size:1
这是结果!
你肯定会说,肯定错了吧,是hibernate的bug。这里肯定高兴啦,总算可以提交一个bug了,以前跳槽的时候可以大声说我为hibernate提交过bug。哈哈,但很遗憾,这并不是bug。
刚才说了我们前面的那个字符串比较的是为这里作铺垫的,那么怎么铺呢?
我们在配置文件中用Set,并且是通过String字符来进行关联的,那么它首先在数据库中取出放进Set中的时候会先判断该关联字符的值是否是相等的,这里由于我们的值都是相等的(这里我们暂时不深究它是怎么进行比较的),我们只需要知道当我们用字符串来进行比较的时候,我们又陷入了JAVA中的字符串陷阱了。查出来只有一条,那么删除呢,删除的时候就比较麻烦啦,它会把所有相同的记录都删除。
那么我们来看一下删除的:
TUser user = (TUser)session.load(TUser.class,new Integer(4)); Transaction tx = session.beginTransaction(); Object obj = user.getAddresses().iterator().next(); user.getAddresses().remove(obj); tx.commit(); session.close();
这里hibernate输出的语句是:
Hibernate: delete from t_address where user_id=?
相信什么时候大家都知道了,是删除该用户下的所有地址。这没得选择,只能全部都删除。
所以在真正的开发中需要注意。
2)上面我们讲了Set,好像用着不怎么爽啊,有那么个陷阱,但没办法,Set是我们用得最多的,而且一般也不会有人直接去关联字符串吧。但很多人还是会不爽,那么hibernate也就应大家要求搞多了一个Bag(也许不是应要求,可能它们里面也有人不满,哈哈)。
我们先来看看它的基本用法:
首先我们需要把前面的TUser的映射文件中的Set标签修改为:
<bag name="addresses" lazy="true" table="t_address"> <key column="user_id" /> <element type="string" column="address" /> </bag>
并且相应的实体类需要把addresses的类型修改为List类型。
这里我们重新添加三个地址:
我们运行测试代码:
public static void main(String[] args) { Configuration cfg = new Configuration().configure(); SessionFactory sessionFactory = cfg.buildSessionFactory(); Session session = sessionFactory.openSession(); TUser user = (TUser)session.load(TUser.class,new Integer(4)); System.out.println("address size:"+user.getAddresses().size()); session.close(); }
这里我们看到了:
address size:3
这次我们已经全部都可以看到了,不管有没有重复。
但我们刚才看了一个删除的问题,Bag在这里还是没有解决,需要借助idBag。我们看到配置文件,需要如下的修改:
<idbag name="addresses" table="t_address" lazy="true"> <collection-id type="int" column="id"> <generator class="identity" /> </collection-id> <key column="user_id" /> <element type="string" column="address" /> </idbag>
我们看到它只比bag多了一个collection-id进行表明要删除的记录号。
当我们重新运行删除的代码:
TUser user = (TUser)session.load(TUser.class,new Integer(4)); Transaction tx = session.beginTransaction(); Object obj = user.getAddresses().iterator().next(); user.getAddresses().remove(obj); tx.commit();
我们看到输出语句为:
Hibernate: delete from t_address where id=?
这次并不是通过user_id来进行删除,而是根据t_address的ID来进行删除,这说明它真正删除我们需要删除的那条记录。
我们看到数据库,现在记录是:
我们已经把第一条记录给删了,正确了。
3)看了上面两种方法,我们再来看一下MAP,它跟上面两个最大的不同就是可以进行键值的对应。直接看代码,直观点:
首先,我们需要修改配置文件:
<map name="addresses" table="t_address" lazy="true"> <key column="user_id" /> <index type="string" column="type" /> <element type="string" column="address" /> </map>
它和前面两个最大的不同就是有一个index,这相当于我们在java中map的key,我们通过这个来取出相对应的记录。记住,改完这里还要改相应的实体类,需要把addresses属性的类型改成Map。
看看数据库的数据:
这里我们看到有两个office和一个home,那么office是拿哪个呢?
不要急,我们运行一下测试代码就知道了:
TUser user = (TUser)session.load(TUser.class,new Integer(4)); System.out.println(user.getAddresses().get("home")); System.out.println(user.getAddresses().get("office"));
我们看到结果是:
ShanWei ShangHai
对,如结果可知,我们取得的是后面那个,这跟Map的原理一样,后面存入的值会覆盖前面的值(如果它们是同一个key的情况下)。
Map是比较简单的,相当前两个来说。
4)最后一个我们来看一下List。List与前几种又有不同,不同在它可以进行排序。
我们来看一下它是怎么实现的:
首先我们还是修改一下映射文件:
<list name="addresses" table="t_address" lazy="true"> <key column="user_id" /> <index type="string" column="idx" /> <element type="string" column="address" /> </list>
它和Map的配置差不多,但index的属性是不一样的,Map中的index是作为key来取得值,而List的index是作为排序的。
我们看数据库:
我们设了三个值,顺序分别为0,1,2。
下面我们运行代码来更改0,2的值:
TUser user = (TUser)session.load(TUser.class,new Integer(4)); Transaction tx = session.beginTransaction(); Object obj1 = user.getAddresses().get(0); Object obj2 = user.getAddresses().get(2); user.getAddresses().set(0,obj2); user.getAddresses().set(2,obj1); tx.commit();
我们看到结果:
我们看到,0,2已经调换了,当然这也只是调换了idx的值。但这已经基本上实现了排序的功能了。
发表评论
-
一个小小的hibernate学习之作
2011-06-21 21:20 1661经过前段时间hibernate的 ... -
hibernate中的Interceptor
2011-06-06 18:05 4472讲到Interceptor,相信熟 ... -
hibernate之二级缓存小谈
2011-06-03 21:31 1601上次我们一起学习了一下hibernate的一级缓存及在运行过 ... -
hibernate状态和缓存小谈
2011-05-30 22:59 1580前几次我们讲了一些比 ... -
hibernate之HQL(3)
2011-05-29 15:38 3312我们在之前一起学习了Hibernate的HQL查询语法。但我 ... -
hibernate查询之HQL(2)
2011-05-28 16:19 2375我们上次一起学习HQL,知道了怎么使用HQL,现在我们继续来学 ... -
hibernate查询之HQL
2011-05-28 09:57 2204上次我们一起学习了用 ... -
hibernate查询之Criteria(2)
2011-05-27 00:05 1510我们前面看了一下Criteria的基本用法,下面我们来了解一 ... -
hibernate查询之Criteria
2011-05-26 22:44 2182前几次我们讲了hibernate的关联映射,映射完了我们就要 ... -
hibernate关联映射之多对多
2011-05-25 22:38 1686我们学习了hibernate的一对一和一对多,下面就剩下一个 ... -
hibernate关联映射之一对多
2011-05-25 21:56 1492看了一对一的实现之后,我们来看一下hibernate中一对多 ... -
hibernate关联映射之一对一(外键关联)
2011-05-24 22:59 1566上次我们说了hibernate关联映射中的一对一关联,我们是 ... -
hibernate关联映射之一对一
2011-05-24 00:41 1257作为一个ORM框架,hibern ... -
hibernate层次设计(2)
2011-05-22 21:00 1277昨天我们了解了怎么使 ... -
hibernate层次设计
2011-05-21 23:04 1846这次我们来说一下hibernate的层次设计,层次设计也就是 ... -
hibernate自定义类型(2)
2011-05-21 12:06 1606昨天讲了自定义类型中会出现异常,今天我们就来解决一下异常,文 ... -
重拾hibernate——自定义类型
2011-05-20 22:56 4514从去年2月参加实习到现在已经差不多一年半没有碰三大框架啦,面 ...
相关推荐
描述中的"hibernate orm框架api中文文档,学习资料,框架详解资料"进一步明确了这些资源的性质,即它们是关于Hibernate ORM框架的API文档、学习教程以及框架的详细解释,都是中文版本,方便中文读者学习。...
【hibernate登录小例子】是一个面向初学者的教程,主要展示了如何利用Hibernate框架实现一个简单的用户登录功能。在这个例子中,我们将深入探讨Hibernate的基本概念、配置、实体类的创建、映射文件的编写以及Session...
9. **集合映射(Collection Mapping)**:Hibernate可以映射Java集合类型到数据库的关联关系,如List、Set、Map等,方便处理一对多、多对一、多对多的关系。 10. **Callback事件**:Hibernate提供了一些生命周期回...
3.8. Hibernate SQL方言 (hibernate.dialect) 3.9. Hibernate日志类别 3.10. JTA TransactionManagers 9.1. 继承映射特性(Features of inheritance mappings) 16.1. 别名注射(alias injection names) 19.1. ...
在Java开发中,Hibernate提供了一种抽象层,允许开发者使用面向对象的编程方式来操作数据库,而无需直接编写SQL语句,极大地提高了开发效率。 《Hibernate官方中文参考手册》是学习Hibernate的基础,它详细介绍了...
在Java世界中,Hibernate作为一个强大的对象关系映射(ORM)框架,极大地简化了数据库操作。本文将深入探讨Hibernate的核心概念,结合提供的中文文档,以及hibernate-annotation-3.4.0GA和hibernate-distribution-...
注意:在Hibernate3中,第二个要求并非是Hibernate强制必须的。但最好这样做。 你不能使用一个IdentifierGenerator产生组合关键字。一个应用程序必须分配它自己的标识符。 使用<composite-id> 标签(并且内嵌元素...
Hibernate开发者指南,包括HIBERNATE - Relational Persistence for Idiomatic Java.pdf,Hibernate Getting Started Guide.pdf,Hibernate Developer Guide.pdf,Hibernate 中文API文档.chm,Hibernate3.2.chm。
Hibernate高官谈Hibernate3.2新特性
12. **集合映射(Collection Mapping)**: Hibernate支持多种集合类型(List、Set、Map等)的映射,以及一对多、多对一、一对一和多对多的关系映射。 通过阅读“Hibernate+Annotation+文档.pdf”,您可以深入学习...
Hibernate分页查询小结
Fetching(抓取):抓取是指Hibernate如何从数据库中获取数据。包括基础抓取知识和应用抓取策略,例如通过查询和配置文件动态抓取数据。 批处理:Hibernate支持JDBC批处理,以提高批量数据操作的性能。 缓冲:讲解...
HIBERNATE - 符合Java习惯的关系数据库持久化 Hibernate参考文档 3.2 -------------------------------------------------------------------------------- 目录 前言 1. 翻译说明 2. 版权声明 1. Hibernate...
**hibernate入门小程序** Hibernate 是一款开源的对象关系映射(ORM)框架,它为Java开发者提供了方便的数据持久化服务,使得开发人员可以使用面向对象的方式来操作数据库,而无需过多地关注SQL语句的编写。在...
hibernate hibernate3 hibernate3中文 hibernateAPI
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC...在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在 应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
这个压缩包包含的资源是Hibernate的中英文API文档,以及一些指南,旨在帮助开发者更好地理解和使用Hibernate。 1. **Hibernate API文档**: Hibernate的API文档是理解其工作原理的关键。`Hibernate3.2.chm`可能是...
Hibernate框架中文帮助文档 CHM格式
struts2+hibernate一周小项目总结
《Hibernate电子书小压缩包》包含了关于Hibernate框架的宝贵学习资料。Hibernate是一个开源的对象关系映射(ORM)框架,它简化了Java应用与数据库之间的交互,使得开发人员能够以面向对象的方式处理数据,而无需过多...