今天小节了一下:
1 Hibernate 中查询.
2 inverse 和 cascade的对比.
3 二级缓存和查询缓存的使用。
hibernate.cfg.xml 如下:
<!-- 指定使用 Echache做缓存提供者 -->
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<!-- 使用查询缓存(查询缓存在二级缓存的基础上使用) -->
<property name="hibernate.cache.use_query_cache">true</property>
ehcache.xml(用于二级缓存)如下:
<ehcache>
<!-- 内存中存不下时存放在硬盘的位置 -->
<diskStore path="F:\\temp" />
<defaultCache maxElementsInMemory="2000" eternal="false"
timeToIdleSeconds="1000" timeToLiveSeconds="1000"
overflowToDisk="true">
</defaultCache>
<cache name="com.isw2.bo.TelBO" maxElementsInMemory="500"
eternal="false" timeToIdleSeconds="1000" timeToLiveSeconds="1000"
overflowToDisk="true" />
<cache name="com.isw2.bo.UserBO" maxElementsInMemory="500"
eternal="false" timeToIdleSeconds="1000" timeToLiveSeconds="1000"
overflowToDisk="true" />
<cache name="com.isw2.bo.UserBO.telBOs" maxElementsInMemory="500"
eternal="false" timeToIdleSeconds="1000" timeToLiveSeconds="1000"
overflowToDisk="true" />
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="100" eternal="true" overflowToDisk="true">
</cache>
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="100" eternal="true" overflowToDisk="true">
</cache>
</ehcache>
TelBO.hbm.xml 如下:
<class name="com.isw2.bo.TelBO" table="t_tel" catalog="many_to_one"
lazy="true">
<!-- 读写策略 -->
<cache usage="read-write" />
<id name="telId" column="telId">
<generator class="native"></generator>
</id>
<property name="telNumber" column="telNumber" length="32"
type="string">
</property>
<many-to-one name="userBO" fetch="select"
column="userId" lazy="proxy">
</many-to-one>
</class>
UserBO.hbm.xml如下:
<class name="com.isw2.bo.UserBO" table="t_user"
catalog="many_to_one" lazy="true">
<!-- 使用二级缓存 -->
<cache usage="read-write" />
<id name="userId" column="userId">
<generator class="native"></generator>
</id>
<property name="userName" column="userName" length="32"
type="string">
</property>
<set name="telBOs" fetch="select" cascade="all" lazy="true"
inverse="true">
<!-- 使用二级缓存 -->
<cache usage="read-write" />
<key column="userId"></key>
<one-to-many class="com.isw2.bo.TelBO" />
</set>
</class>
/**
* 关于 inverse="true"
*/
public void update() {
Session session = HibernateSessionFactory.getSession();
Transaction tr = session.beginTransaction();
Query query = session.createQuery("from UserBO ub where ub.userId = 7");
UserBO userBO = (UserBO) query.uniqueResult();
TelBO telBO = new TelBO("9058492", userBO);
userBO.getTelBOs().add(telBO);
session.update(userBO);
tr.commit();
session.close();
/**
* 在one-to-many 中 设置 inverse="true" 表示由many方维护数据间的关系. 注意: 区别于 cascade
* 表示需要哪些维护数据间的关系(all:所有情况下均进行关联操作;
* none:所有情况下均不进行关联操作,这是默认值;save-update:在执行save/update/saveOrUpdate时进行关联操作;
* delete:在执行delete时进行关联操作。 )
*
* 对下面的操作分析可知,当由one方维护时数据先存入数据库,然后根据 one 执行更新操作;
* 由many 方维护时,数据先查询,然后根据查询结果存入数据库
*/
/**
* inverse="true" 时操作如下:
* Hibernate: select userbo0_.userId as userId1_,
* userbo0_.userName as userName1_ from many_to_one.t_user userbo0_
* where userbo0_.userId=7
*
* Hibernate: select telbos0_.userId as
* userId1_, telbos0_.telId as telId1_, telbos0_.telId as telId0_0_,
* telbos0_.telNumber as telNumber0_0_, telbos0_.userId as userId0_0_
* from many_to_one.t_tel telbos0_ where telbos0_.userId=?
*
* Hibernate:
* insert into many_to_one.t_tel (telNumber, userId) values (?, ?)
*
*
*
* inverse="false" 时操作如下:
*
* Hibernate: select userbo0_.userId as userId1_,
* userbo0_.userName as userName1_ from many_to_one.t_user userbo0_
* where userbo0_.userId=7
*
* Hibernate: select telbos0_.userId as
* userId1_, telbos0_.telId as telId1_, telbos0_.telId as telId0_0_,
* telbos0_.telNumber as telNumber0_0_, telbos0_.userId as userId0_0_
* from many_to_one.t_tel telbos0_ where telbos0_.userId=?
*
* Hibernate:insert into many_to_one.t_tel (telNumber, userId) values (?, ?)
* Hibernate: update many_to_one.t_tel set userId=? where telId=?
*/
}
/**
* 根据Bean 查询对象
*/
public void findByEntity() {
Session session = HibernateSessionFactory.getSession();
UserBO userBO = (UserBO) session.load(UserBO.class, new Long(7));
/**
* Query query = session.createQuery("from TelBO tb where tb.userBO =
* ?"); query.setParameter(0, userBO); TelBO telBO = new TelBO();
* telBO.setTelNumber("591201270");
*/
// 这里把UserBO 当作Bean 来使用,userBO.getUserId 在这里可以提供参数注意:userId
Query query = session.createQuery("from TelBO tb "
+ "where tb.telId =:userId");
query.setProperties(userBO);
System.out.println(query.setMaxResults(1).uniqueResult());
session.close();
}
/**
* 根据 Alias 联合查询(distinct 无法解决)
*/
public void findByJoinAlias() {
Session session = HibernateSessionFactory.getSession();
Criteria cr = session.createCriteria(UserBO.class);
cr.createAlias("telBOs", "tb");// 别名的使用
cr.add(Restrictions.like("tb.telNumber", "%"));
// //这样查询结果仅有userName 一个字段
// cr.setProjection(Projections.distinct(Projections.property("userName")));
// //这只是在结果集中做了处理分页时无法使用
// cr.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);
List list = cr.list();
for (Object object : list) {
System.out.println(object);
}
session.close();
}
/**
* 通过HQL 联合查询
*/
public void findByJoinHQL() {
Session session = HibernateSessionFactory.getSession();
// fetch 查询和 非fetch 查询, SQL语句相同,不同的是前者以 对象形式 返回,后者以数组形式返回
// Query query = session.createQuery("from UserBO ub inner join
// ub.telBOs");
// Query query = session
// .createQuery("from UserBO ub inner join fetch ub.telBOs");
Query query = session
.createQuery("select distinct ub from UserBO ub inner join fetch ub.telBOs");
List list = query.list();
for (Object object : list) {
System.out.println(object);
}
session.close();
}
/**
* 使用二级缓存(批量更新数据时为提高效率通过session.setCacheMode设置缓存模式)
*/
public void testCache() {
System.out.println("开始查询.....");
Session session = HibernateSessionFactory.getSession();
Query query = session.createQuery("from UserBO");
List list = query.list();
for (Object object : list) {
System.out.println(object);
}
session.close();
System.out.println("使用二级缓存......");
/**
* 查询SQL: Hibernate: select userbo0_.userId as col_0_0_ from
* many_to_one.t_user userbo0_
*
* 这里先查询Id 然后在缓存中根据id查找. 这里要注意,使用的是query.iterate.
* 因为它会先查询Id,再根据Id查询对象,如二级缓存中有则直接取,否则就去数据库查询.
* 之前一次查询后数据已放入二级缓存,第二次就没有查询数据库.
*
* 集合的缓存中存放的是Id,然后根据Id 查询二级缓存
*
* 如果用query.list 则要使用查询缓存.
*/
session = HibernateSessionFactory.getSession();
query = session.createQuery("from UserBO");
Iterator<Object> iterator = query.iterate();
for (; iterator.hasNext();) {
Object object = iterator.next();
System.out.println(object);
}
session.close();
}
/**
* 使用查询缓存
*/
public void testSearchCache() {
System.out.println("开始查询.....");
Session session = HibernateSessionFactory.getSession();
Query query = session.createQuery("from UserBO");
// 设置使用查询缓存(查询缓存默认不使用,这里要显示启动)
query.setCacheable(true);
// 设置缓存区域
query.setCacheRegion("com.isw2.bo.UserBO");
// ------------------------------------
List list = query.list();
for (Object object : list) {
System.out.println(object);
}
session.close();
System.out.println("使用查询缓存......");
session = HibernateSessionFactory.getSession();
query = session.createQuery("from UserBO");
// 设置使用查询缓存(两次使用同样的缓存区域)
query.setCacheable(true);
query.setCacheRegion("com.isw2.bo.UserBO");
// ------------------------------------
list = query.list();
for (Object object : list) {
System.out.println(object);
}
/**
* 在这里查询缓存类似于集合缓存。通过查询语句和 Id 集的方式存放查询结果,然后在二级缓存中查询结果
*/
}
这里以又向关联为主。二级缓存因为命中率不高使用的不多,自己也不是很熟。
参考:
http://www.iteye.com/topic/18904
http://rujingzhang.iteye.com/blog/219487
http://www.blogjava.net/i369/articles/219408.html
分享到:
相关推荐
总结,Hibernate的one-to-many和many-to-one关系映射是数据库对象关联的基础,理解和熟练掌握它们能帮助开发者更高效地设计和实现Java持久化层。通过合理的配置和实践,可以构建出高性能、易于维护的数据访问层。
综上所述,`many-to-one` 和 `cascade` 是Hibernate中非常重要的概念,它们能够帮助开发者更高效地管理实体之间的关系。然而,在实际应用中,需要根据具体的业务需求和场景来合理选择和配置这些功能,避免不必要的...
Hibernate中many-to-one关系的编写_远航的水手
Hibernate中many-to-one关系的编写_远航的水手.htm
本实例将详细讲解如何在Hibernate中实现Many-to-One关系映射,这是一种常见的数据库关联,表示一个实体可以与多个其他实体相关联。 在Many-to-One关系中,通常一个实体(如部门)可以有多个相关实体(如员工),而...
在上面的配置中, `<many-to-one>` 标签指定了Person实体与IdCard实体之间的一对一唯一外键关联关系,其中unique="true"指定了多的一端的多重性为一。 Hibernate 一对一唯一外键关联映射的应用 在实际应用中,一对...
同时,`Account.hbm.xml`中的`many-to-one`元素将`column`属性设置为`FID`,表示通过`FID`字段关联到`User`实体。 #### 测试场景解释 在测试场景中,我们创建了一个`User`对象和一个`Account`对象,并在`User`对象...
为了使用 `publisher` 属性,我们需要在 `Book` 类的 Hibernate 映射文件中添加 `<many-to-one>` 映射。这将在 `BOOK` 表中添加一个名为 `PUBLISHER_ID` 的列,并存储关联出版商的 ID。 ```xml <!-- 其他属性的...
在配置双向一对多关联时,我们通常在"多"一端(这里是`Student`)的集合属性上使用`<many-to-one>`标签,将`Classes`对象映射到数据库中的外键。同时,在"一"端(`Classes`)使用`<set>`标签,表示班级可以包含多个...
本示例将详细讲解如何在Hibernate中实现多对多(many-to-many)的关系映射。 在数据库设计中,多对多关系是指两个实体之间存在多个关联,比如学生和课程的关系,一个学生可以选修多门课程,一门课程也可以被多个...
在Hibernate中,`one-to-many`关系是常见的实体间关系之一,表示一个实体可以与多个其他实体相关联。本文将深入探讨`Hibernate one-to-many`注解的使用和实现细节。 ### 一、`@OneToMany`注解概述 `@OneToMany`...
标题"Hibernate one to many(many to one) 配置"涉及到的是关系型数据库在Java中的持久化框架Hibernate中的两种关联映射关系:一对一(One-to-One)和多对一(Many-to-One)。在数据库设计中,这种关系很常见,例如...
3. 在对应的映射文件中,使用`<set>`和`<one-to-many>`或`<many-to-one>`元素配置映射关系。 4. 如有必要,可以考虑将多对多关系转换为一对多,以优化性能和操作性。 理解并熟练掌握这些概念和实践,将有助于在使用...
many-to-one 配置详解 讲的很清楚 适合新手 值得下载
在Java的持久化框架Hibernate中,"Many-to-One"关系是一种常见的关联映射类型,它表示一个实体(类)可以与多个其他实体实例相关联。在这个主题中,我们将深入探讨Hibernate如何处理这种关系,以及如何在实际编程中...
本程序包含: hibenate 上传图片,二进制数据,大文本,集合映射的多种关系,onetoone,ontomany,manytomany等关系详细代码示例以及注释,全部由本人测试通过,对理解hibernate配置有极大帮助。
在提供的文件"hibernate_day03"中,可能包含相关的代码示例和更深入的解释,通过阅读和实践这些内容,你可以更好地掌握Hibernate的抓取策略,特别是对于"many-to-one"关系的应用。记住,理论知识固然重要,但实践...
本篇将重点探讨Hibernate中的Many-to-One关系映射,帮助开发者更深入地理解和运用这一关键特性。 Many-to-One关系是现实世界中常见的关联类型,一个实体可能对应另一个实体的多个实例,例如,一个员工可以属于一个...
本文将深入探讨“Hibernate关联映射中的Many-to-One关系”。 Many-to-One关联是现实世界中常见的关系类型,比如一个学生可以对应多个课程,而一个课程可能被多个学生选修。在数据库中,这通常表现为一对多(One-to-...